aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPete Popov <ppopov@embeddedalley.com>2005-07-14 13:47:57 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:54 -0400
commitbdf21b18b4abf983db38f04ef7fec88f47389867 (patch)
treeb7e551f09f0ee39f4a59132be4c0890e1ba80d91 /arch
parente01402b115cccb6357f956649487aca2c6f7fbba (diff)
Philips PNX8550 support: MIPS32-like core with 2 Trimedias on it.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/Kconfig21
-rw-r--r--arch/mips/Makefile14
-rw-r--r--arch/mips/kernel/cpu-probe.c19
-rw-r--r--arch/mips/kernel/proc.c3
-rw-r--r--arch/mips/kernel/time.c3
-rw-r--r--arch/mips/mm/tlbex.c1
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-pnx8550.c57
-rw-r--r--arch/mips/pci/ops-pnx8550.c284
-rw-r--r--arch/mips/philips/pnx8550/common/Kconfig1
-rw-r--r--arch/mips/philips/pnx8550/common/Makefile27
-rw-r--r--arch/mips/philips/pnx8550/common/gdb_hook.c109
-rw-r--r--arch/mips/philips/pnx8550/common/int.c293
-rw-r--r--arch/mips/philips/pnx8550/common/mipsIRQ.S76
-rw-r--r--arch/mips/philips/pnx8550/common/pci.c133
-rw-r--r--arch/mips/philips/pnx8550/common/platform.c135
-rw-r--r--arch/mips/philips/pnx8550/common/proc.c113
-rw-r--r--arch/mips/philips/pnx8550/common/prom.c138
-rw-r--r--arch/mips/philips/pnx8550/common/reset.c49
-rw-r--r--arch/mips/philips/pnx8550/common/setup.c149
-rw-r--r--arch/mips/philips/pnx8550/common/time.c105
-rw-r--r--arch/mips/philips/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/philips/pnx8550/jbs/board_setup.c65
-rw-r--r--arch/mips/philips/pnx8550/jbs/init.c57
-rw-r--r--arch/mips/philips/pnx8550/jbs/irqmap.c36
25 files changed, 1892 insertions, 1 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4ef015f580f9..f6b25ae1861b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -489,6 +489,16 @@ config HYPERTRANSPORT
489 bool "Hypertransport Support for PMC-Sierra Yosemite" 489 bool "Hypertransport Support for PMC-Sierra Yosemite"
490 depends on PMC_YOSEMITE 490 depends on PMC_YOSEMITE
491 491
492config PNX8550_V2PCI
493 bool "Support for Philips PNX8550 based Viper2-PCI board"
494 select PNX8550
495 select SYS_SUPPORTS_LITTLE_ENDIAN
496
497config PNX8550_JBS
498 bool "Support for Philips PNX8550 based JBS board"
499 select PNX8550
500 select SYS_SUPPORTS_LITTLE_ENDIAN
501
492config DDB5074 502config DDB5074
493 bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)" 503 bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
494 depends on EXPERIMENTAL 504 depends on EXPERIMENTAL
@@ -827,6 +837,7 @@ config TOSHIBA_FPCIB0
827 837
828source "arch/mips/sgi-ip27/Kconfig" 838source "arch/mips/sgi-ip27/Kconfig"
829source "arch/mips/sibyte/Kconfig" 839source "arch/mips/sibyte/Kconfig"
840source "arch/mips/philips/pnx8550/common/Kconfig"
830 841
831config RWSEM_GENERIC_SPINLOCK 842config RWSEM_GENERIC_SPINLOCK
832 bool 843 bool
@@ -954,6 +965,16 @@ config ITE_BOARD_GEN
954 depends on MIPS_IVR || MIPS_ITE8172 965 depends on MIPS_IVR || MIPS_ITE8172
955 default y 966 default y
956 967
968config PNX8550
969 bool
970 select SOC_PNX8550
971
972config SOC_PNX8550
973 bool
974 select SYS_SUPPORTS_32BIT_KERNEL
975 select DMA_NONCOHERENT
976 select HW_HAS_PCI
977
957config SWAP_IO_SPACE 978config SWAP_IO_SPACE
958 bool 979 bool
959 980
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 6780d115a7dc..d62787ab9fff 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -228,6 +228,7 @@ cflags-$(CONFIG_CPU_RM9000) += \
228 $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ 228 $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
229 -Wa,--trap 229 -Wa,--trap
230 230
231
231cflags-$(CONFIG_CPU_SB1) += \ 232cflags-$(CONFIG_CPU_SB1) += \
232 $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ 233 $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
233 -Wa,--trap 234 -Wa,--trap
@@ -561,6 +562,19 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
561load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000 562load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
562 563
563# 564#
565# Common Philips PNX8550
566#
567core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/
568cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550
569
570#
571# Philips PNX8550 JBS board
572#
573libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/
574#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550
575load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
576
577#
564# SGI IP22 (Indy/Indigo2) 578# SGI IP22 (Indy/Indigo2)
565# 579#
566# Set the load address to >= 0xffffffff88069000 if you want to leave space for 580# Set the load address to >= 0xffffffff88069000 if you want to leave space for
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 844126b39ed3..70c8ad9bc8fc 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -121,6 +121,7 @@ static inline void check_wait(void)
121 case CPU_24K: 121 case CPU_24K:
122 case CPU_25KF: 122 case CPU_25KF:
123 case CPU_34K: 123 case CPU_34K:
124 case CPU_PR4450:
124 cpu_wait = r4k_wait; 125 cpu_wait = r4k_wait;
125 printk(" available.\n"); 126 printk(" available.\n");
126 break; 127 break;
@@ -624,6 +625,21 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
624 } 625 }
625} 626}
626 627
628static inline void cpu_probe_philips(struct cpuinfo_mips *c)
629{
630 decode_configs(c);
631 switch (c->processor_id & 0xff00) {
632 case PRID_IMP_PR4450:
633 c->cputype = CPU_PR4450;
634 c->isa_level = MIPS_CPU_ISA_M32;
635 break;
636 default:
637 panic("Unknown Philips Core!"); /* REVISIT: die? */
638 break;
639 }
640}
641
642
627__init void cpu_probe(void) 643__init void cpu_probe(void)
628{ 644{
629 struct cpuinfo_mips *c = &current_cpu_data; 645 struct cpuinfo_mips *c = &current_cpu_data;
@@ -649,6 +665,9 @@ __init void cpu_probe(void)
649 case PRID_COMP_SANDCRAFT: 665 case PRID_COMP_SANDCRAFT:
650 cpu_probe_sandcraft(c); 666 cpu_probe_sandcraft(c);
651 break; 667 break;
668 case PRID_COMP_PHILIPS:
669 cpu_probe_philips(c);
670 break;
652 default: 671 default:
653 c->cputype = CPU_UNKNOWN; 672 c->cputype = CPU_UNKNOWN;
654 } 673 }
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 1bd40af508ed..e46a92d01d51 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -80,7 +80,8 @@ static const char *cpu_name[] = {
80 [CPU_VR4133] = "NEC VR4133", 80 [CPU_VR4133] = "NEC VR4133",
81 [CPU_VR4181] = "NEC VR4181", 81 [CPU_VR4181] = "NEC VR4181",
82 [CPU_VR4181A] = "NEC VR4181A", 82 [CPU_VR4181A] = "NEC VR4181A",
83 [CPU_SR71000] = "Sandcraft SR71000" 83 [CPU_SR71000] = "Sandcraft SR71000",
84 [CPU_PR4450] = "Philips PR4450",
84}; 85};
85 86
86 87
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index fbc153c8f833..a24651dfaaba 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -11,6 +11,7 @@
11 * Free Software Foundation; either version 2 of the License, or (at your 11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14#include <linux/config.h>
14#include <linux/types.h> 15#include <linux/types.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/init.h> 17#include <linux/init.h>
@@ -112,8 +113,10 @@ static void c0_timer_ack(void)
112{ 113{
113 unsigned int count; 114 unsigned int count;
114 115
116#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */
115 /* Ack this timer interrupt and set the next one. */ 117 /* Ack this timer interrupt and set the next one. */
116 expirelo += cycles_per_jiffy; 118 expirelo += cycles_per_jiffy;
119#endif
117 write_c0_compare(expirelo); 120 write_c0_compare(expirelo);
118 121
119 /* Check to see if we have missed any timer interrupts. */ 122 /* Check to see if we have missed any timer interrupts. */
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index c1d394d36f6c..a876ed6cde24 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -844,6 +844,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
844 case CPU_AU1500: 844 case CPU_AU1500:
845 case CPU_AU1550: 845 case CPU_AU1550:
846 case CPU_AU1200: 846 case CPU_AU1200:
847 case CPU_PR4450:
847 i_nop(p); 848 i_nop(p);
848 tlbw(p); 849 tlbw(p);
849 break; 850 break;
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 83d81c9cdc2b..ea8438b81fed 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
34obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o 34obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o
35obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o 35obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
36obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o 36obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
37obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
37obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o 38obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
38obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o 39obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
39obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o 40obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
new file mode 100644
index 000000000000..4256b3b30b77
--- /dev/null
+++ b/arch/mips/pci/fixup-pnx8550.c
@@ -0,0 +1,57 @@
1/*
2 * Philips PNX8550 pci fixups.
3 *
4 * Copyright 2005 Embedded Alley Solutions, Inc
5 * source@embeddealley.com
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 */
20#include <linux/types.h>
21#include <linux/pci.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24
25#include <asm/mach-pnx8550/pci.h>
26#include <asm/mach-pnx8550/int.h>
27
28
29#undef DEBUG
30#ifdef DEBUG
31#define DBG(x...) printk(x)
32#else
33#define DBG(x...)
34#endif
35
36extern char irq_tab_jbs[][5];
37
38void __init pcibios_fixup_resources(struct pci_dev *dev)
39{
40 /* no need to fixup IO resources */
41}
42
43void __init pcibios_fixup(void)
44{
45 /* nothing to do here */
46}
47
48int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
49{
50 return irq_tab_jbs[slot][pin];
51}
52
53/* Do platform specific device initialization at pci_enable_device() time */
54int pcibios_plat_dev_init(struct pci_dev *dev)
55{
56 return 0;
57}
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
new file mode 100644
index 000000000000..454b65cc3354
--- /dev/null
+++ b/arch/mips/pci/ops-pnx8550.c
@@ -0,0 +1,284 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 *
5 * 2.6 port, Embedded Alley Solutions, Inc
6 *
7 * Based on:
8 * Author: source@mvista.com
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 */
23#include <linux/types.h>
24#include <linux/pci.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/vmalloc.h>
28#include <linux/delay.h>
29
30#include <asm/mach-pnx8550/pci.h>
31#include <asm/mach-pnx8550/glb.h>
32#include <asm/debug.h>
33
34
35static inline void clear_status(void)
36{
37 unsigned long pci_stat;
38
39 pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
40 outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
41}
42
43static inline unsigned int
44calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
45{
46 unsigned int addr;
47
48 addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
49 addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
50
51 return addr;
52}
53
54static int
55config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
56{
57 unsigned int flags;
58 unsigned long loops = 0;
59 unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
60
61 local_irq_save(flags);
62 /*Clear pending interrupt status */
63 if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
64 clear_status();
65 while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
66 }
67
68 outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
69
70 if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
71 outl(*val, PCI_BASE | PCI_GPPM_WDAT);
72
73 outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
74 PCI_BASE | PCI_GPPM_CTRL);
75
76 loops =
77 ((loops_per_jiffy *
78 PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
79 while (1) {
80 if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
81 if ((pci_cmd == PCI_CMD_IOR) ||
82 (pci_cmd == PCI_CMD_CONFIG_READ))
83 *val = inl(PCI_BASE | PCI_GPPM_RDAT);
84 clear_status();
85 local_irq_restore(flags);
86 return PCIBIOS_SUCCESSFUL;
87 } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
88 break;
89 }
90
91 loops--;
92 if (loops == 0) {
93 printk("%s : Arbiter Locked.\n", __FUNCTION__);
94 }
95 }
96
97 clear_status();
98 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
99 printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
100 __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
101 pci_cmd);
102 }
103
104 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
105 *val = 0xffffffff;
106 local_irq_restore(flags);
107 return PCIBIOS_DEVICE_NOT_FOUND;
108}
109
110/*
111 * We can't address 8 and 16 bit words directly. Instead we have to
112 * read/write a 32bit word and mask/modify the data we actually want.
113 */
114static int
115read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
116{
117 unsigned int data = 0;
118 int err;
119
120 if (bus == 0)
121 return -1;
122
123 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
124 switch (where & 0x03) {
125 case 0:
126 *val = (unsigned char)(data & 0x000000ff);
127 break;
128 case 1:
129 *val = (unsigned char)((data & 0x0000ff00) >> 8);
130 break;
131 case 2:
132 *val = (unsigned char)((data & 0x00ff0000) >> 16);
133 break;
134 case 3:
135 *val = (unsigned char)((data & 0xff000000) >> 24);
136 break;
137 }
138
139 return err;
140}
141
142static int
143read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
144{
145 unsigned int data = 0;
146 int err;
147
148 if (bus == 0)
149 return -1;
150
151 if (where & 0x01)
152 return PCIBIOS_BAD_REGISTER_NUMBER;
153
154 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
155 switch (where & 0x02) {
156 case 0:
157 *val = (unsigned short)(data & 0x0000ffff);
158 break;
159 case 2:
160 *val = (unsigned short)((data & 0xffff0000) >> 16);
161 break;
162 }
163
164 return err;
165}
166
167static int
168read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
169{
170 int err;
171 if (bus == 0)
172 return -1;
173
174 if (where & 0x03)
175 return PCIBIOS_BAD_REGISTER_NUMBER;
176
177 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
178
179 return err;
180}
181
182static int
183write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
184{
185 unsigned int data = (unsigned int)val;
186 int err;
187
188 if (bus == 0)
189 return -1;
190
191 switch (where & 0x03) {
192 case 1:
193 data = (data << 8);
194 break;
195 case 2:
196 data = (data << 16);
197 break;
198 case 3:
199 data = (data << 24);
200 break;
201 default:
202 break;
203 }
204
205 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
206
207 return err;
208}
209
210static int
211write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
212{
213 unsigned int data = (unsigned int)val;
214 int err;
215
216 if (bus == 0)
217 return -1;
218
219 if (where & 0x01)
220 return PCIBIOS_BAD_REGISTER_NUMBER;
221
222 switch (where & 0x02) {
223 case 2:
224 data = (data << 16);
225 break;
226 default:
227 break;
228 }
229 err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
230
231 return err;
232}
233
234static int
235write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
236{
237 int err;
238 if (bus == 0)
239 return -1;
240
241 if (where & 0x03)
242 return PCIBIOS_BAD_REGISTER_NUMBER;
243
244 err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
245
246 return err;
247}
248
249static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
250{
251 switch (size) {
252 case 1: {
253 u8 _val;
254 int rc = read_config_byte(bus, devfn, where, &_val);
255 *val = _val;
256 return rc;
257 }
258 case 2: {
259 u16 _val;
260 int rc = read_config_word(bus, devfn, where, &_val);
261 *val = _val;
262 return rc;
263 }
264 default:
265 return read_config_dword(bus, devfn, where, val);
266 }
267}
268
269static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
270{
271 switch (size) {
272 case 1:
273 return write_config_byte(bus, devfn, where, (u8) val);
274 case 2:
275 return write_config_word(bus, devfn, where, (u16) val);
276 default:
277 return write_config_dword(bus, devfn, where, val);
278 }
279}
280
281struct pci_ops pnx8550_pci_ops = {
282 config_read,
283 config_write
284};
diff --git a/arch/mips/philips/pnx8550/common/Kconfig b/arch/mips/philips/pnx8550/common/Kconfig
new file mode 100644
index 000000000000..072572d173cc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Kconfig
@@ -0,0 +1 @@
# Place holder
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile
new file mode 100644
index 000000000000..6e38f3bc443c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/Makefile
@@ -0,0 +1,27 @@
1#
2# Per Hallsmark, per.hallsmark@mvista.com
3#
4# ########################################################################
5#
6# This program is free software; you can distribute it and/or modify it
7# 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 it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc.,
17# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
18#
19# #######################################################################
20#
21# Makefile for the PNX8550 specific kernel interface routines
22# under Linux.
23#
24
25obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o
26obj-$(CONFIG_PCI) += pci.o
27obj-$(CONFIG_KGDB) += gdb_hook.o
diff --git a/arch/mips/philips/pnx8550/common/gdb_hook.c b/arch/mips/philips/pnx8550/common/gdb_hook.c
new file mode 100644
index 000000000000..ad4624f6d9bc
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/gdb_hook.c
@@ -0,0 +1,109 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * ########################################################################
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 *
20 * ########################################################################
21 *
22 * This is the interface to the remote debugger stub.
23 *
24 */
25#include <linux/types.h>
26#include <linux/serial.h>
27#include <linux/serialP.h>
28#include <linux/serial_reg.h>
29#include <linux/serial_ip3106.h>
30
31#include <asm/serial.h>
32#include <asm/io.h>
33
34#include <uart.h>
35
36static struct serial_state rs_table[IP3106_NR_PORTS] = {
37};
38static struct async_struct kdb_port_info = {0};
39
40void rs_kgdb_hook(int tty_no)
41{
42 struct serial_state *ser = &rs_table[tty_no];
43
44 kdb_port_info.state = ser;
45 kdb_port_info.magic = SERIAL_MAGIC;
46 kdb_port_info.port = tty_no;
47 kdb_port_info.flags = ser->flags;
48
49 /*
50 * Clear all interrupts
51 */
52 /* Clear all the transmitter FIFO counters (pointer and status) */
53 ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_TX_RST;
54 /* Clear all the receiver FIFO counters (pointer and status) */
55 ip3106_lcr(UART_BASE, tty_no) |= IP3106_UART_LCR_RX_RST;
56 /* Clear all interrupts */
57 ip3106_iclr(UART_BASE, tty_no) = IP3106_UART_INT_ALLRX |
58 IP3106_UART_INT_ALLTX;
59
60 /*
61 * Now, initialize the UART
62 */
63 ip3106_lcr(UART_BASE, tty_no) = IP3106_UART_LCR_8BIT;
64 ip3106_baud(UART_BASE, tty_no) = 5; // 38400 Baud
65}
66
67int putDebugChar(char c)
68{
69 /* Wait until FIFO not full */
70 while (((ip3106_fifo(UART_BASE, kdb_port_info.port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
71 ;
72 /* Send one char */
73 ip3106_fifo(UART_BASE, kdb_port_info.port) = c;
74
75 return 1;
76}
77
78char getDebugChar(void)
79{
80 char ch;
81
82 /* Wait until there is a char in the FIFO */
83 while (!((ip3106_fifo(UART_BASE, kdb_port_info.port) &
84 IP3106_UART_FIFO_RXFIFO) >> 8))
85 ;
86 /* Read one char */
87 ch = ip3106_fifo(UART_BASE, kdb_port_info.port) &
88 IP3106_UART_FIFO_RBRTHR;
89 /* Advance the RX FIFO read pointer */
90 ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_NEXT;
91 return (ch);
92}
93
94void rs_disable_debug_interrupts(void)
95{
96 ip3106_ien(UART_BASE, kdb_port_info.port) = 0; /* Disable all interrupts */
97}
98
99void rs_enable_debug_interrupts(void)
100{
101 /* Clear all the transmitter FIFO counters (pointer and status) */
102 ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_TX_RST;
103 /* Clear all the receiver FIFO counters (pointer and status) */
104 ip3106_lcr(UART_BASE, kdb_port_info.port) |= IP3106_UART_LCR_RX_RST;
105 /* Clear all interrupts */
106 ip3106_iclr(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX |
107 IP3106_UART_INT_ALLTX;
108 ip3106_ien(UART_BASE, kdb_port_info.port) = IP3106_UART_INT_ALLRX; /* Enable RX interrupts */
109}
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
new file mode 100644
index 000000000000..546144988bf5
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/int.c
@@ -0,0 +1,293 @@
1/*
2 *
3 * Copyright (C) 2005 Embedded Alley Solutions, Inc
4 * Ported to 2.6.
5 *
6 * Per Hallsmark, per.hallsmark@mvista.com
7 * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
8 * Copyright (C) 2001 Ralf Baechle
9 *
10 * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com
11 *
12 * This program is free software; you can distribute it and/or modify it
13 * under the terms of the GNU General Public License (Version 2) as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 *
25 */
26#include <linux/config.h>
27#include <linux/init.h>
28#include <linux/irq.h>
29#include <linux/sched.h>
30#include <linux/slab.h>
31#include <linux/interrupt.h>
32#include <linux/kernel_stat.h>
33#include <linux/random.h>
34#include <linux/module.h>
35
36#include <asm/io.h>
37#include <asm/gdb-stub.h>
38#include <int.h>
39#include <uart.h>
40
41extern asmlinkage void cp0_irqdispatch(void);
42
43static DEFINE_SPINLOCK(irq_lock);
44
45/* default prio for interrupts */
46/* first one is a no-no so therefore always prio 0 (disabled) */
47static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
48 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9
49 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19
50 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29
51 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49
53 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59
54 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69
55 1 // 70
56};
57
58void hw0_irqdispatch(int irq, struct pt_regs *regs)
59{
60 /* find out which interrupt */
61 irq = PNX8550_GIC_VECTOR_0 >> 3;
62
63 if (irq == 0) {
64 printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
65 return;
66 }
67 do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
68}
69
70
71void timer_irqdispatch(int irq, struct pt_regs *regs)
72{
73 irq = (0x01c0 & read_c0_config7()) >> 6;
74
75 if (irq == 0) {
76 printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
77 return;
78 }
79
80 if (irq & 0x1) {
81 do_IRQ(PNX8550_INT_TIMER1, regs);
82 }
83 if (irq & 0x2) {
84 do_IRQ(PNX8550_INT_TIMER2, regs);
85 }
86 if (irq & 0x4) {
87 do_IRQ(PNX8550_INT_TIMER3, regs);
88 }
89}
90
91static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
92{
93 unsigned long status = read_c0_status();
94
95 status &= ~((clr_mask & 0xFF) << 8);
96 status |= (set_mask & 0xFF) << 8;
97
98 write_c0_status(status);
99}
100
101static inline void mask_gic_int(unsigned int irq_nr)
102{
103 /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */
104 PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */
105}
106
107static inline void unmask_gic_int(unsigned int irq_nr)
108{
109 /* set prio mask to lower four bits and enable interrupt */
110 PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
111}
112
113static inline void mask_irq(unsigned int irq_nr)
114{
115 if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
116 modify_cp0_intmask(1 << irq_nr, 0);
117 } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
118 (irq_nr <= PNX8550_INT_GIC_MAX)) {
119 mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
120 } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
121 (irq_nr <= PNX8550_INT_TIMER_MAX)) {
122 modify_cp0_intmask(1 << 7, 0);
123 } else {
124 printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
125 }
126}
127
128static inline void unmask_irq(unsigned int irq_nr)
129{
130 if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
131 modify_cp0_intmask(0, 1 << irq_nr);
132 } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
133 (irq_nr <= PNX8550_INT_GIC_MAX)) {
134 unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
135 } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
136 (irq_nr <= PNX8550_INT_TIMER_MAX)) {
137 modify_cp0_intmask(0, 1 << 7);
138 } else {
139 printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
140 }
141}
142
143#define pnx8550_disable pnx8550_ack
144static void pnx8550_ack(unsigned int irq)
145{
146 unsigned long flags;
147
148 spin_lock_irqsave(&irq_lock, flags);
149 mask_irq(irq);
150 spin_unlock_irqrestore(&irq_lock, flags);
151}
152
153#define pnx8550_enable pnx8550_unmask
154static void pnx8550_unmask(unsigned int irq)
155{
156 unsigned long flags;
157
158 spin_lock_irqsave(&irq_lock, flags);
159 unmask_irq(irq);
160 spin_unlock_irqrestore(&irq_lock, flags);
161}
162
163static unsigned int startup_irq(unsigned int irq_nr)
164{
165 pnx8550_unmask(irq_nr);
166 return 0;
167}
168
169static void shutdown_irq(unsigned int irq_nr)
170{
171 pnx8550_ack(irq_nr);
172 return;
173}
174
175int pnx8550_set_gic_priority(int irq, int priority)
176{
177 int gic_irq = irq-PNX8550_INT_GIC_MIN;
178 int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf;
179
180 gic_prio[gic_irq] = priority;
181 PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]);
182
183 return prev_priority;
184}
185
186static inline void mask_and_ack_level_irq(unsigned int irq)
187{
188 pnx8550_disable(irq);
189 return;
190}
191
192static void end_irq(unsigned int irq)
193{
194 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
195 pnx8550_enable(irq);
196 }
197}
198
199static struct hw_interrupt_type level_irq_type = {
200 .typename = "PNX Level IRQ",
201 .startup = startup_irq,
202 .shutdown = shutdown_irq,
203 .enable = pnx8550_enable,
204 .disable = pnx8550_disable,
205 .ack = mask_and_ack_level_irq,
206 .end = end_irq,
207};
208
209static struct irqaction gic_action = {
210 .handler = no_action,
211 .flags = SA_INTERRUPT,
212 .name = "GIC",
213};
214
215static struct irqaction timer_action = {
216 .handler = no_action,
217 .flags = SA_INTERRUPT,
218 .name = "Timer",
219};
220
221void __init arch_init_irq(void)
222{
223 int i;
224 int configPR;
225
226 /* init of cp0 interrupts */
227 set_except_vector(0, cp0_irqdispatch);
228
229 for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
230 irq_desc[i].handler = &level_irq_type;
231 pnx8550_ack(i); /* mask the irq just in case */
232 }
233
234 /* init of GIC/IPC interrupts */
235 /* should be done before cp0 since cp0 init enables the GIC int */
236 for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) {
237 int gic_int_line = i - PNX8550_INT_GIC_MIN;
238 if (gic_int_line == 0 )
239 continue; // don't fiddle with int 0
240 /*
241 * enable change of TARGET, ENABLE and ACTIVE_LOW bits
242 * set TARGET 0 to route through hw0 interrupt
243 * set ACTIVE_LOW 0 active high (correct?)
244 *
245 * We really should setup an interrupt description table
246 * to do this nicely.
247 * Note, PCI INTA is active low on the bus, but inverted
248 * in the GIC, so to us it's active high.
249 */
250#ifdef CONFIG_PNX8550_V2PCI
251 if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
252 /* PCI INT through gpio 8, which is setup in
253 * pnx8550_setup.c and routed to GPIO
254 * Interrupt Level 0 (GPIO Connection 58).
255 * Set it active low. */
256
257 PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
258 } else
259#endif
260 {
261 PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
262 }
263
264 /* mask/priority is still 0 so we will not get any
265 * interrupts until it is unmasked */
266
267 irq_desc[i].handler = &level_irq_type;
268 }
269
270 /* Priority level 0 */
271 PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0;
272
273 /* Set int vector table address */
274 PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
275
276 irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type;
277 setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
278
279 /* init of Timer interrupts */
280 for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) {
281 irq_desc[i].handler = &level_irq_type;
282 }
283
284 /* Stop Timer 1-3 */
285 configPR = read_c0_config7();
286 configPR |= 0x00000038;
287 write_c0_config7(configPR);
288
289 irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type;
290 setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
291}
292
293EXPORT_SYMBOL(pnx8550_set_gic_priority);
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
new file mode 100644
index 000000000000..338bffda3fab
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/mipsIRQ.S
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2002 Philips, Inc. All rights.
3 * Copyright (c) 2002 Red Hat, Inc. All rights.
4 *
5 * This software may be freely redistributed under the terms of the
6 * GNU General Public License.
7 *
8 * You should have received a copy of the GNU General Public License
9 * along with this program; if not, write to the Free Software
10 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
13 *
14 */
15#include <asm/asm.h>
16#include <asm/mipsregs.h>
17#include <asm/addrspace.h>
18#include <asm/regdef.h>
19#include <asm/stackframe.h>
20
21/*
22 * cp0_irqdispatch
23 *
24 * Code to handle in-core interrupt exception.
25 */
26
27 .align 5
28 .set reorder
29 .set noat
30 NESTED(cp0_irqdispatch, PT_SIZE, sp)
31 SAVE_ALL
32 CLI
33 .set at
34 mfc0 t0,CP0_CAUSE
35 mfc0 t2,CP0_STATUS
36
37 and t0,t2
38
39 andi t1,t0,STATUSF_IP2 /* int0 hardware line */
40 bnez t1,ll_hw0_irq
41 nop
42
43 andi t1,t0,STATUSF_IP7 /* int5 hardware line */
44 bnez t1,ll_timer_irq
45 nop
46
47 /* wrong alarm or masked ... */
48
49 j spurious_interrupt
50 nop
51 END(cp0_irqdispatch)
52
53 .align 5
54 .set reorder
55ll_hw0_irq:
56 li a0,2
57 move a1,sp
58 jal hw0_irqdispatch
59 nop
60 j ret_from_irq
61 nop
62
63 .align 5
64 .set reorder
65ll_timer_irq:
66 mfc0 t3,CP0_CONFIG,7
67 andi t4,t3,0x01c0
68 beqz t4,ll_timer_out
69 nop
70 li a0,7
71 move a1,sp
72 jal timer_irqdispatch
73 nop
74
75ll_timer_out: j ret_from_irq
76 nop
diff --git a/arch/mips/philips/pnx8550/common/pci.c b/arch/mips/philips/pnx8550/common/pci.c
new file mode 100644
index 000000000000..baa6905f649f
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/pci.c
@@ -0,0 +1,133 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 *
5 * Author: source@mvista.com
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 */
20#include <linux/types.h>
21#include <linux/pci.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24
25#include <pci.h>
26#include <glb.h>
27#include <nand.h>
28
29static struct resource pci_io_resource = {
30 "pci IO space",
31 (u32)(PNX8550_PCIIO + 0x1000), /* reserve regacy I/O space */
32 (u32)(PNX8550_PCIIO + PNX8550_PCIIO_SIZE),
33 IORESOURCE_IO
34};
35
36static struct resource pci_mem_resource = {
37 "pci memory space",
38 (u32)(PNX8550_PCIMEM),
39 (u32)(PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1),
40 IORESOURCE_MEM
41};
42
43extern struct pci_ops pnx8550_pci_ops;
44
45static struct pci_controller pnx8550_controller = {
46 .pci_ops = &pnx8550_pci_ops,
47 .io_resource = &pci_io_resource,
48 .mem_resource = &pci_mem_resource,
49};
50
51/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
52static inline unsigned long get_system_mem_size(void)
53{
54 /* Read IP2031_RANK0_ADDR_LO */
55 unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
56 /* Read IP2031_RANK1_ADDR_HI */
57 unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
58
59 return dram_r1_hi - dram_r0_lo + 1;
60}
61
62static int __init pnx8550_pci_setup(void)
63{
64 int pci_mem_code;
65 int mem_size = get_system_mem_size() >> 20;
66
67 /* Clear the Global 2 Register, PCI Inta Output Enable Registers
68 Bit 1:Enable DAC Powerdown
69 -> 0:DACs are enabled and are working normally
70 1:DACs are powerdown
71 Bit 0:Enable of PCI inta output
72 -> 0 = Disable PCI inta output
73 1 = Enable PCI inta output
74 */
75 PNX8550_GLB2_ENAB_INTA_O = 0;
76
77 /* Calc the PCI mem size code */
78 if (mem_size >= 128)
79 pci_mem_code = SIZE_128M;
80 else if (mem_size >= 64)
81 pci_mem_code = SIZE_64M;
82 else if (mem_size >= 32)
83 pci_mem_code = SIZE_32M;
84 else
85 pci_mem_code = SIZE_16M;
86
87 /* Set PCI_XIO registers */
88 outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
89 outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
90 outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
91 outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
92
93 /* Send memory transaction via PCI_BASE2 */
94 outl(0x00000001, PCI_BASE | PCI_IO);
95
96 /* Unlock the setup register */
97 outl(0xca, PCI_BASE | PCI_UNLOCKREG);
98
99 /*
100 * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
101 * to work, and in order for bus_to_baddr to work without any
102 * hacks.
103 */
104 outl(0x00000000, PCI_BASE | PCI_BASE10);
105
106 /*
107 *These two bars are set by default or the boot code.
108 * However, it's safer to set them here so we're not boot
109 * code dependent.
110 */
111 outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
112 outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
113
114 outl(PCI_EN_TA |
115 PCI_EN_PCI2MMI |
116 PCI_EN_XIO |
117 PCI_SETUP_BASE18_SIZE(SIZE_32M) |
118 PCI_SETUP_BASE18_EN |
119 PCI_SETUP_BASE14_EN |
120 PCI_SETUP_BASE10_PREF |
121 PCI_SETUP_BASE10_SIZE(pci_mem_code) |
122 PCI_SETUP_CFGMANAGE_EN |
123 PCI_SETUP_PCIARB_EN,
124 PCI_BASE |
125 PCI_SETUP); /* PCI_SETUP */
126 outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
127
128 register_pci_controller(&pnx8550_controller);
129
130 return 0;
131}
132
133arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
new file mode 100644
index 000000000000..8aa9bd65b45e
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/platform.c
@@ -0,0 +1,135 @@
1/*
2 * Platform device support for Philips PNX8550 SoCs
3 *
4 * Copyright 2005, Embedded Alley Solutions, Inc
5 *
6 * Based on arch/mips/au1000/common/platform.c
7 * Platform device support for Au1x00 SoCs.
8 *
9 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15#include <linux/device.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/resource.h>
19#include <linux/serial.h>
20#include <linux/serial_ip3106.h>
21
22#include <int.h>
23#include <usb.h>
24#include <uart.h>
25
26extern struct uart_ops ip3106_pops;
27
28static struct resource pnx8550_usb_ohci_resources[] = {
29 [0] = {
30 .start = PNX8550_USB_OHCI_OP_BASE,
31 .end = PNX8550_USB_OHCI_OP_BASE +
32 PNX8550_USB_OHCI_OP_LEN,
33 .flags = IORESOURCE_MEM,
34 },
35 [1] = {
36 .start = PNX8550_INT_USB,
37 .end = PNX8550_INT_USB,
38 .flags = IORESOURCE_IRQ,
39 },
40};
41
42static struct resource pnx8550_uart_resources[] = {
43 [0] = {
44 .start = PNX8550_UART_PORT0,
45 .end = PNX8550_UART_PORT0 + 0xfff,
46 .flags = IORESOURCE_MEM,
47 },
48 [1] = {
49 .start = PNX8550_UART_INT(0),
50 .end = PNX8550_UART_INT(0),
51 .flags = IORESOURCE_IRQ,
52 },
53 [2] = {
54 .start = PNX8550_UART_PORT1,
55 .end = PNX8550_UART_PORT1 + 0xfff,
56 .flags = IORESOURCE_MEM,
57 },
58 [3] = {
59 .start = PNX8550_UART_INT(1),
60 .end = PNX8550_UART_INT(1),
61 .flags = IORESOURCE_IRQ,
62 },
63};
64
65struct ip3106_port ip3106_ports[] = {
66 [0] = {
67 .port = {
68 .type = PORT_IP3106,
69 .iotype = SERIAL_IO_MEM,
70 .membase = (void __iomem *)PNX8550_UART_PORT0,
71 .mapbase = PNX8550_UART_PORT0,
72 .irq = PNX8550_UART_INT(0),
73 .uartclk = 3692300,
74 .fifosize = 16,
75 .ops = &ip3106_pops,
76 .flags = ASYNC_BOOT_AUTOCONF,
77 .line = 0,
78 },
79 },
80 [1] = {
81 .port = {
82 .type = PORT_IP3106,
83 .iotype = SERIAL_IO_MEM,
84 .membase = (void __iomem *)PNX8550_UART_PORT1,
85 .mapbase = PNX8550_UART_PORT1,
86 .irq = PNX8550_UART_INT(1),
87 .uartclk = 3692300,
88 .fifosize = 16,
89 .ops = &ip3106_pops,
90 .flags = ASYNC_BOOT_AUTOCONF,
91 .line = 1,
92 },
93 },
94};
95
96/* The dmamask must be set for OHCI to work */
97static u64 ohci_dmamask = ~(u32)0;
98
99static u64 uart_dmamask = ~(u32)0;
100
101static struct platform_device pnx8550_usb_ohci_device = {
102 .name = "pnx8550-ohci",
103 .id = -1,
104 .dev = {
105 .dma_mask = &ohci_dmamask,
106 .coherent_dma_mask = 0xffffffff,
107 },
108 .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
109 .resource = pnx8550_usb_ohci_resources,
110};
111
112static struct platform_device pnx8550_uart_device = {
113 .name = "ip3106-uart",
114 .id = -1,
115 .dev = {
116 .dma_mask = &uart_dmamask,
117 .coherent_dma_mask = 0xffffffff,
118 .platform_data = ip3106_ports,
119 },
120 .num_resources = ARRAY_SIZE(pnx8550_uart_resources),
121 .resource = pnx8550_uart_resources,
122};
123
124static struct platform_device *pnx8550_platform_devices[] __initdata = {
125 &pnx8550_usb_ohci_device,
126 &pnx8550_uart_device,
127};
128
129int pnx8550_platform_init(void)
130{
131 return platform_add_devices(pnx8550_platform_devices,
132 ARRAY_SIZE(pnx8550_platform_devices));
133}
134
135arch_initcall(pnx8550_platform_init);
diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c
new file mode 100644
index 000000000000..72a016767e09
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/proc.c
@@ -0,0 +1,113 @@
1/*
2 * This program is free software; you can distribute it and/or modify it
3 * under the terms of the GNU General Public License (Version 2) as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
14 */
15#include <linux/init.h>
16#include <linux/proc_fs.h>
17#include <linux/irq.h>
18#include <linux/sched.h>
19#include <linux/slab.h>
20#include <linux/interrupt.h>
21#include <linux/kernel_stat.h>
22#include <linux/random.h>
23
24#include <asm/io.h>
25#include <asm/gdb-stub.h>
26#include <int.h>
27#include <uart.h>
28
29
30static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
31{
32 int len = 0;
33 int configPR = read_c0_config7();
34
35 if (offset==0) {
36 len += sprintf(&page[len],"Timer: count, compare, tc, status\n");
37 len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n",
38 read_c0_count(), read_c0_compare(),
39 (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on");
40 len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n",
41 read_c0_count2(), read_c0_compare2(),
42 (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on");
43 len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n",
44 read_c0_count3(), read_c0_compare3(),
45 (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on");
46 }
47
48 return len;
49}
50
51static int pnx8550_registers_read (char* page, char** start, off_t offset, int count, int* eof, void* data)
52{
53 int len = 0;
54
55 if (offset==0) {
56 len += sprintf(&page[len],"config1: %#10.8x\n",read_c0_config1());
57 len += sprintf(&page[len],"config2: %#10.8x\n",read_c0_config2());
58 len += sprintf(&page[len],"config3: %#10.8x\n",read_c0_config3());
59 len += sprintf(&page[len],"configPR: %#10.8x\n",read_c0_config7());
60 len += sprintf(&page[len],"status: %#10.8x\n",read_c0_status());
61 len += sprintf(&page[len],"cause: %#10.8x\n",read_c0_cause());
62 len += sprintf(&page[len],"count: %#10.8x\n",read_c0_count());
63 len += sprintf(&page[len],"count_2: %#10.8x\n",read_c0_count2());
64 len += sprintf(&page[len],"count_3: %#10.8x\n",read_c0_count3());
65 len += sprintf(&page[len],"compare: %#10.8x\n",read_c0_compare());
66 len += sprintf(&page[len],"compare_2: %#10.8x\n",read_c0_compare2());
67 len += sprintf(&page[len],"compare_3: %#10.8x\n",read_c0_compare3());
68 }
69
70 return len;
71}
72
73static struct proc_dir_entry* pnx8550_dir = NULL;
74static struct proc_dir_entry* pnx8550_timers = NULL;
75static struct proc_dir_entry* pnx8550_registers = NULL;
76
77static int pnx8550_proc_init( void )
78{
79
80 // Create /proc/pnx8550
81 pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL);
82 if (pnx8550_dir){
83 pnx8550_dir->nlink = 1;
84 }
85 else {
86 printk(KERN_ERR "Can't create pnx8550 proc dir\n");
87 return -1;
88 }
89
90 // Create /proc/pnx8550/timers
91 pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir );
92 if (pnx8550_timers){
93 pnx8550_timers->nlink = 1;
94 pnx8550_timers->read_proc = pnx8550_timers_read;
95 }
96 else {
97 printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
98 }
99
100 // Create /proc/pnx8550/registers
101 pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir );
102 if (pnx8550_registers){
103 pnx8550_registers->nlink = 1;
104 pnx8550_registers->read_proc = pnx8550_registers_read;
105 }
106 else {
107 printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
108 }
109
110 return 0;
111}
112
113__initcall(pnx8550_proc_init);
diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c
new file mode 100644
index 000000000000..70aac9759412
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/prom.c
@@ -0,0 +1,138 @@
1/*
2 *
3 * Per Hallsmark, per.hallsmark@mvista.com
4 *
5 * Based on jmr3927/common/prom.c
6 *
7 * 2004 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/string.h>
16#include <linux/serial_ip3106.h>
17
18#include <asm/bootinfo.h>
19#include <uart.h>
20
21/* #define DEBUG_CMDLINE */
22
23extern int prom_argc;
24extern char **prom_argv, **prom_envp;
25
26typedef struct
27{
28 char *name;
29/* char *val; */
30}t_env_var;
31
32
33char * prom_getcmdline(void)
34{
35 return &(arcs_cmdline[0]);
36}
37
38void prom_init_cmdline(void)
39{
40 char *cp;
41 int actr;
42
43 actr = 1; /* Always ignore argv[0] */
44
45 cp = &(arcs_cmdline[0]);
46 while(actr < prom_argc) {
47 strcpy(cp, prom_argv[actr]);
48 cp += strlen(prom_argv[actr]);
49 *cp++ = ' ';
50 actr++;
51 }
52 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
53 --cp;
54 *cp = '\0';
55}
56
57char *prom_getenv(char *envname)
58{
59 /*
60 * Return a pointer to the given environment variable.
61 * Environment variables are stored in the form of "memsize=64".
62 */
63
64 t_env_var *env = (t_env_var *)prom_envp;
65 int i;
66
67 i = strlen(envname);
68
69 while(env->name) {
70 if(strncmp(envname, env->name, i) == 0) {
71 return(env->name + strlen(envname) + 1);
72 }
73 env++;
74 }
75 return(NULL);
76}
77
78inline unsigned char str2hexnum(unsigned char c)
79{
80 if(c >= '0' && c <= '9')
81 return c - '0';
82 if(c >= 'a' && c <= 'f')
83 return c - 'a' + 10;
84 if(c >= 'A' && c <= 'F')
85 return c - 'A' + 10;
86 return 0; /* foo */
87}
88
89inline void str2eaddr(unsigned char *ea, unsigned char *str)
90{
91 int i;
92
93 for(i = 0; i < 6; i++) {
94 unsigned char num;
95
96 if((*str == '.') || (*str == ':'))
97 str++;
98 num = str2hexnum(*str++) << 4;
99 num |= (str2hexnum(*str++));
100 ea[i] = num;
101 }
102}
103
104int get_ethernet_addr(char *ethernet_addr)
105{
106 char *ethaddr_str;
107
108 ethaddr_str = prom_getenv("ethaddr");
109 if (!ethaddr_str) {
110 printk("ethaddr not set in boot prom\n");
111 return -1;
112 }
113 str2eaddr(ethernet_addr, ethaddr_str);
114 return 0;
115}
116
117unsigned long __init prom_free_prom_memory(void)
118{
119 return 0;
120}
121
122extern int pnx8550_console_port;
123
124/* used by prom_printf */
125void prom_putchar(char c)
126{
127 if (pnx8550_console_port != -1) {
128 /* Wait until FIFO not full */
129 while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & IP3106_UART_FIFO_TXFIFO) >> 16) >= 16)
130 ;
131 /* Send one char */
132 ip3106_fifo(UART_BASE, pnx8550_console_port) = c;
133 }
134}
135
136EXPORT_SYMBOL(prom_getcmdline);
137EXPORT_SYMBOL(get_ethernet_addr);
138EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/philips/pnx8550/common/reset.c b/arch/mips/philips/pnx8550/common/reset.c
new file mode 100644
index 000000000000..7b2cbc5b2c7c
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/reset.c
@@ -0,0 +1,49 @@
1/*.
2 *
3 * ########################################################################
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * ########################################################################
19 *
20 * Reset the PNX8550 board.
21 *
22 */
23#include <linux/slab.h>
24#include <asm/reboot.h>
25#include <glb.h>
26
27void pnx8550_machine_restart(char *command)
28{
29 char head[] = "************* Machine restart *************";
30 char foot[] = "*******************************************";
31
32 printk("\n\n");
33 printk("%s\n", head);
34 if (command != NULL)
35 printk("* %s\n", command);
36 printk("%s\n", foot);
37
38 PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
39}
40
41void pnx8550_machine_halt(void)
42{
43 printk("*** Machine halt. (Not implemented) ***\n");
44}
45
46void pnx8550_machine_power_off(void)
47{
48 printk("*** Machine power off. (Not implemented) ***\n");
49}
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
new file mode 100644
index 000000000000..ee6bf72094f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -0,0 +1,149 @@
1/*
2 *
3 * 2.6 port, Embedded Alley Solutions, Inc
4 *
5 * Based on Per Hallsmark, per.hallsmark@mvista.com
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 */
20#include <linux/config.h>
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/ioport.h>
24#include <linux/mm.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/serial_ip3106.h>
28
29#include <asm/cpu.h>
30#include <asm/bootinfo.h>
31#include <asm/irq.h>
32#include <asm/mipsregs.h>
33#include <asm/reboot.h>
34#include <asm/pgtable.h>
35#include <asm/time.h>
36
37#include <glb.h>
38#include <int.h>
39#include <pci.h>
40#include <uart.h>
41#include <nand.h>
42
43extern void prom_printf(char *fmt, ...);
44
45extern void __init board_setup(void);
46extern void pnx8550_machine_restart(char *);
47extern void pnx8550_machine_halt(void);
48extern void pnx8550_machine_power_off(void);
49extern struct resource ioport_resource;
50extern struct resource iomem_resource;
51extern void (*board_time_init)(void);
52extern void pnx8550_time_init(void);
53extern void (*board_timer_setup)(struct irqaction *irq);
54extern void pnx8550_timer_setup(struct irqaction *irq);
55extern void rs_kgdb_hook(int tty_no);
56extern void prom_printf(char *fmt, ...);
57extern char *prom_getcmdline(void);
58
59struct resource standard_io_resources[] = {
60 {"dma1", 0x00, 0x1f, IORESOURCE_BUSY},
61 {"timer", 0x40, 0x5f, IORESOURCE_BUSY},
62 {"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY},
63 {"dma2", 0xc0, 0xdf, IORESOURCE_BUSY},
64};
65
66#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
67
68extern struct resource pci_io_resource;
69extern struct resource pci_mem_resource;
70
71/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
72unsigned long get_system_mem_size(void)
73{
74 /* Read IP2031_RANK0_ADDR_LO */
75 unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
76 /* Read IP2031_RANK1_ADDR_HI */
77 unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
78
79 return dram_r1_hi - dram_r0_lo + 1;
80}
81
82int pnx8550_console_port = -1;
83
84void __init plat_setup(void)
85{
86 int i;
87 char* argptr;
88
89 board_setup(); /* board specific setup */
90
91 _machine_restart = pnx8550_machine_restart;
92 _machine_halt = pnx8550_machine_halt;
93 _machine_power_off = pnx8550_machine_power_off;
94
95 board_time_init = pnx8550_time_init;
96 board_timer_setup = pnx8550_timer_setup;
97
98 /* Clear the Global 2 Register, PCI Inta Output Enable Registers
99 Bit 1:Enable DAC Powerdown
100 -> 0:DACs are enabled and are working normally
101 1:DACs are powerdown
102 Bit 0:Enable of PCI inta output
103 -> 0 = Disable PCI inta output
104 1 = Enable PCI inta output
105 */
106 PNX8550_GLB2_ENAB_INTA_O = 0;
107
108 /* IO/MEM resources. */
109 set_io_port_base(KSEG1);
110 ioport_resource.start = 0;
111 ioport_resource.end = ~0;
112 iomem_resource.start = 0;
113 iomem_resource.end = ~0;
114
115 /* Request I/O space for devices on this board */
116 for (i = 0; i < STANDARD_IO_RESOURCES; i++)
117 request_resource(&ioport_resource, standard_io_resources + i);
118
119 /* Place the Mode Control bit for GPIO pin 16 in primary function */
120 /* Pin 16 is used by UART1, UA1_TX */
121 outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
122 (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
123 PNX8550_GPIO_MC1);
124
125 argptr = prom_getcmdline();
126 if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
127 argptr += strlen("console=ttyS");
128 pnx8550_console_port = *argptr == '0' ? 0 : 1;
129
130 /* We must initialize the UART (console) before prom_printf */
131 /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
132 ip3106_lcr(UART_BASE, pnx8550_console_port) =
133 IP3106_UART_LCR_8BIT;
134 ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
135 }
136
137#ifdef CONFIG_KGDB
138 argptr = prom_getcmdline();
139 if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
140 int line;
141 argptr += strlen("kgdb=ttyS");
142 line = *argptr == '0' ? 0 : 1;
143 rs_kgdb_hook(line);
144 prom_printf("KGDB: Using ttyS%i for session, "
145 "please connect your debugger\n", line ? 1 : 0);
146 }
147#endif
148 return;
149}
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
new file mode 100644
index 000000000000..70664ea96b92
--- /dev/null
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2001, 2002, 2003 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 *
5 * Common time service routines for MIPS machines. See
6 * Documents/MIPS/README.txt.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/sched.h>
17#include <linux/param.h>
18#include <linux/time.h>
19#include <linux/timer.h>
20#include <linux/smp.h>
21#include <linux/kernel_stat.h>
22#include <linux/spinlock.h>
23#include <linux/interrupt.h>
24#include <linux/module.h>
25
26#include <asm/bootinfo.h>
27#include <asm/cpu.h>
28#include <asm/time.h>
29#include <asm/hardirq.h>
30#include <asm/div64.h>
31#include <asm/debug.h>
32
33#include <int.h>
34#include <cm.h>
35
36extern unsigned int mips_hpt_frequency;
37
38/*
39 * pnx8550_time_init() - it does the following things:
40 *
41 * 1) board_time_init() -
42 * a) (optional) set up RTC routines,
43 * b) (optional) calibrate and set the mips_hpt_frequency
44 * (only needed if you intended to use fixed_rate_gettimeoffset
45 * or use cpu counter as timer interrupt source)
46 */
47
48void pnx8550_time_init(void)
49{
50 unsigned int n;
51 unsigned int m;
52 unsigned int p;
53 unsigned int pow2p;
54
55 /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */
56 /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */
57
58 n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16;
59 m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8;
60 p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2;
61 pow2p = (1 << p);
62
63 db_assert(m != 0 && pow2p != 0);
64
65 /*
66 * Compute the frequency as in the PNX8550 User Manual 1.0, p.186
67 * (a.k.a. 8-10). Divide by HZ for a timer offset that results in
68 * HZ timer interrupts per second.
69 */
70 mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
71}
72
73/*
74 * pnx8550_timer_setup() - it does the following things:
75 *
76 * 5) board_timer_setup() -
77 * a) (optional) over-write any choices made above by time_init().
78 * b) machine specific code should setup the timer irqaction.
79 * c) enable the timer interrupt
80 */
81
82void __init pnx8550_timer_setup(struct irqaction *irq)
83{
84 int configPR;
85
86 setup_irq(PNX8550_INT_TIMER1, irq);
87
88 /* Start timer1 */
89 configPR = read_c0_config7();
90 configPR &= ~0x00000008;
91 write_c0_config7(configPR);
92
93 /* Timer 2 stop */
94 configPR = read_c0_config7();
95 configPR |= 0x00000010;
96 write_c0_config7(configPR);
97
98 write_c0_count2(0);
99 write_c0_compare2(0xffffffff);
100
101 /* Timer 3 stop */
102 configPR = read_c0_config7();
103 configPR |= 0x00000020;
104 write_c0_config7(configPR);
105}
diff --git a/arch/mips/philips/pnx8550/jbs/Makefile b/arch/mips/philips/pnx8550/jbs/Makefile
new file mode 100644
index 000000000000..e8228dbca8f6
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
1
2# Makefile for the Philips JBS Board.
3
4lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/philips/pnx8550/jbs/board_setup.c b/arch/mips/philips/pnx8550/jbs/board_setup.c
new file mode 100644
index 000000000000..f92826e0096d
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/board_setup.c
@@ -0,0 +1,65 @@
1/*
2 * JBS Specific board startup routines.
3 *
4 * Copyright 2005, Embedded Alley Solutions, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26#include <linux/init.h>
27#include <linux/sched.h>
28#include <linux/ioport.h>
29#include <linux/mm.h>
30#include <linux/console.h>
31#include <linux/mc146818rtc.h>
32#include <linux/delay.h>
33
34#include <asm/cpu.h>
35#include <asm/bootinfo.h>
36#include <asm/irq.h>
37#include <asm/mipsregs.h>
38#include <asm/reboot.h>
39#include <asm/pgtable.h>
40
41#include <glb.h>
42
43/* CP0 hazard avoidance. */
44#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
45 "nop; nop; nop; nop; nop; nop;\n\t" \
46 ".set reorder\n\t")
47
48void __init board_setup(void)
49{
50 unsigned long config0, configpr;
51
52 config0 = read_c0_config();
53
54 /* clear all three cache coherency fields */
55 config0 &= ~(0x7 | (7<<25) | (7<<28));
56 config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
57 (CONF_CM_DEFAULT<<28));
58 write_c0_config(config0);
59 BARRIER;
60
61 configpr = read_c0_config7();
62 configpr |= (1<<19); /* enable tlb */
63 write_c0_config7(configpr);
64 BARRIER;
65}
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
new file mode 100644
index 000000000000..85f449174bc3
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/init.c
@@ -0,0 +1,57 @@
1/*
2 *
3 * Copyright 2005 Embedded Alley Solutions, Inc
4 * source@embeddedalley.com
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/init.h>
28#include <linux/mm.h>
29#include <linux/sched.h>
30#include <linux/bootmem.h>
31#include <asm/addrspace.h>
32#include <asm/bootinfo.h>
33#include <linux/string.h>
34#include <linux/kernel.h>
35
36int prom_argc;
37char **prom_argv, **prom_envp;
38extern void __init prom_init_cmdline(void);
39extern char *prom_getenv(char *envname);
40
41const char *get_system_type(void)
42{
43 return "Philips PNX8550/JBS";
44}
45
46void __init prom_init(void)
47{
48
49 unsigned long memsize;
50
51 mips_machgroup = MACH_GROUP_PHILIPS;
52 mips_machtype = MACH_PHILIPS_JBS;
53
54 //memsize = 0x02800000; /* Trimedia uses memory above */
55 memsize = 0x08000000; /* Trimedia uses memory above */
56 add_memory_region(0, memsize, BOOT_MEM_RAM);
57}
diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c
new file mode 100644
index 000000000000..f78e0423dc98
--- /dev/null
+++ b/arch/mips/philips/pnx8550/jbs/irqmap.c
@@ -0,0 +1,36 @@
1/*
2 * Philips JBS board irqmap.
3 *
4 * Copyright 2005 Embedded Alley Solutions, Inc
5 * source@embeddealley.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/init.h>
29#include <int.h>
30
31char irq_tab_jbs[][5] __initdata = {
32 [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
33 [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
34 [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
35};
36