aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/se/73180
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/se/73180')
-rw-r--r--arch/sh/boards/se/73180/Makefile7
-rw-r--r--arch/sh/boards/se/73180/io.c265
-rw-r--r--arch/sh/boards/se/73180/irq.c137
-rw-r--r--arch/sh/boards/se/73180/led.c67
-rw-r--r--arch/sh/boards/se/73180/setup.c68
5 files changed, 544 insertions, 0 deletions
diff --git a/arch/sh/boards/se/73180/Makefile b/arch/sh/boards/se/73180/Makefile
new file mode 100644
index 000000000000..8f63886a0f3f
--- /dev/null
+++ b/arch/sh/boards/se/73180/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the 73180 SolutionEngine specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/73180/io.c b/arch/sh/boards/se/73180/io.c
new file mode 100644
index 000000000000..73648cbe3678
--- /dev/null
+++ b/arch/sh/boards/se/73180/io.c
@@ -0,0 +1,265 @@
1/*
2 * arch/sh/boards/se/73180/io.c
3 *
4 * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/boards/se/7300/io.c
6 *
7 * I/O routine for SH-Mobile3 73180 SolutionEngine.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <asm/mach/se73180.h>
14#include <asm/io.h>
15
16#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
17
18struct iop {
19 unsigned long start, end;
20 unsigned long base;
21 struct iop *(*check) (struct iop * p, unsigned long port);
22 unsigned char (*inb) (struct iop * p, unsigned long port);
23 unsigned short (*inw) (struct iop * p, unsigned long port);
24 void (*outb) (struct iop * p, unsigned char value, unsigned long port);
25 void (*outw) (struct iop * p, unsigned short value, unsigned long port);
26};
27
28struct iop *
29simple_check(struct iop *p, unsigned long port)
30{
31 if ((p->start <= port) && (port <= p->end))
32 return p;
33 else
34 badio(check, port);
35}
36
37struct iop *
38ide_check(struct iop *p, unsigned long port)
39{
40 if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
41 return p;
42 return NULL;
43}
44
45unsigned char
46simple_inb(struct iop *p, unsigned long port)
47{
48 return *(unsigned char *) (p->base + port);
49}
50
51unsigned short
52simple_inw(struct iop *p, unsigned long port)
53{
54 return *(unsigned short *) (p->base + port);
55}
56
57void
58simple_outb(struct iop *p, unsigned char value, unsigned long port)
59{
60 *(unsigned char *) (p->base + port) = value;
61}
62
63void
64simple_outw(struct iop *p, unsigned short value, unsigned long port)
65{
66 *(unsigned short *) (p->base + port) = value;
67}
68
69unsigned char
70pcc_inb(struct iop *p, unsigned long port)
71{
72 unsigned long addr = p->base + port + 0x40000;
73 unsigned long v;
74
75 if (port & 1)
76 addr += 0x00400000;
77 v = *(volatile unsigned char *) addr;
78 return v;
79}
80
81void
82pcc_outb(struct iop *p, unsigned char value, unsigned long port)
83{
84 unsigned long addr = p->base + port + 0x40000;
85
86 if (port & 1)
87 addr += 0x00400000;
88 *(volatile unsigned char *) addr = value;
89}
90
91unsigned char
92bad_inb(struct iop *p, unsigned long port)
93{
94 badio(inb, port);
95}
96
97void
98bad_outb(struct iop *p, unsigned char value, unsigned long port)
99{
100 badio(inw, port);
101}
102
103/* MSTLANEX01 LAN at 0xb400:0000 */
104static struct iop laniop = {
105 .start = 0x300,
106 .end = 0x30f,
107 .base = 0xb4000000,
108 .check = simple_check,
109 .inb = simple_inb,
110 .inw = simple_inw,
111 .outb = simple_outb,
112 .outw = simple_outw,
113};
114
115/* NE2000 pc card NIC */
116static struct iop neiop = {
117 .start = 0x280,
118 .end = 0x29f,
119 .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
120 .check = simple_check,
121 .inb = pcc_inb,
122 .inw = simple_inw,
123 .outb = pcc_outb,
124 .outw = simple_outw,
125};
126
127/* CF in CF slot */
128static struct iop cfiop = {
129 .base = 0xb0600000,
130 .check = ide_check,
131 .inb = pcc_inb,
132 .inw = simple_inw,
133 .outb = pcc_outb,
134 .outw = simple_outw,
135};
136
137static __inline__ struct iop *
138port2iop(unsigned long port)
139{
140 if (0) ;
141#if defined(CONFIG_SMC91111)
142 else if (laniop.check(&laniop, port))
143 return &laniop;
144#endif
145#if defined(CONFIG_NE2000)
146 else if (neiop.check(&neiop, port))
147 return &neiop;
148#endif
149#if defined(CONFIG_IDE)
150 else if (cfiop.check(&cfiop, port))
151 return &cfiop;
152#endif
153 else
154 return &neiop; /* fallback */
155}
156
157static inline void
158delay(void)
159{
160 ctrl_inw(0xac000000);
161 ctrl_inw(0xac000000);
162}
163
164unsigned char
165sh73180se_inb(unsigned long port)
166{
167 struct iop *p = port2iop(port);
168 return (p->inb) (p, port);
169}
170
171unsigned char
172sh73180se_inb_p(unsigned long port)
173{
174 unsigned char v = sh73180se_inb(port);
175 delay();
176 return v;
177}
178
179unsigned short
180sh73180se_inw(unsigned long port)
181{
182 struct iop *p = port2iop(port);
183 return (p->inw) (p, port);
184}
185
186unsigned int
187sh73180se_inl(unsigned long port)
188{
189 badio(inl, port);
190}
191
192void
193sh73180se_outb(unsigned char value, unsigned long port)
194{
195 struct iop *p = port2iop(port);
196 (p->outb) (p, value, port);
197}
198
199void
200sh73180se_outb_p(unsigned char value, unsigned long port)
201{
202 sh73180se_outb(value, port);
203 delay();
204}
205
206void
207sh73180se_outw(unsigned short value, unsigned long port)
208{
209 struct iop *p = port2iop(port);
210 (p->outw) (p, value, port);
211}
212
213void
214sh73180se_outl(unsigned int value, unsigned long port)
215{
216 badio(outl, port);
217}
218
219void
220sh73180se_insb(unsigned long port, void *addr, unsigned long count)
221{
222 unsigned char *a = addr;
223 struct iop *p = port2iop(port);
224 while (count--)
225 *a++ = (p->inb) (p, port);
226}
227
228void
229sh73180se_insw(unsigned long port, void *addr, unsigned long count)
230{
231 unsigned short *a = addr;
232 struct iop *p = port2iop(port);
233 while (count--)
234 *a++ = (p->inw) (p, port);
235}
236
237void
238sh73180se_insl(unsigned long port, void *addr, unsigned long count)
239{
240 badio(insl, port);
241}
242
243void
244sh73180se_outsb(unsigned long port, const void *addr, unsigned long count)
245{
246 unsigned char *a = (unsigned char *) addr;
247 struct iop *p = port2iop(port);
248 while (count--)
249 (p->outb) (p, *a++, port);
250}
251
252void
253sh73180se_outsw(unsigned long port, const void *addr, unsigned long count)
254{
255 unsigned short *a = (unsigned short *) addr;
256 struct iop *p = port2iop(port);
257 while (count--)
258 (p->outw) (p, *a++, port);
259}
260
261void
262sh73180se_outsl(unsigned long port, const void *addr, unsigned long count)
263{
264 badio(outsw, port);
265}
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c
new file mode 100644
index 000000000000..70f04caad9a4
--- /dev/null
+++ b/arch/sh/boards/se/73180/irq.c
@@ -0,0 +1,137 @@
1/*
2 * arch/sh/boards/se/73180/irq.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/boards/se/7300/irq.c
6 *
7 * Modified for SH-Mobile SolutionEngine 73180 Support
8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
9 *
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/irq.h>
17#include <asm/io.h>
18#include <asm/mach/se73180.h>
19
20static int
21intreq2irq(int i)
22{
23 if (i == 5)
24 return 10;
25 return 32 + 7 - i;
26}
27
28static int
29irq2intreq(int irq)
30{
31 if (irq == 10)
32 return 5;
33 return 7 - (irq - 32);
34}
35
36static void
37disable_intreq_irq(unsigned int irq)
38{
39 ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSK0);
40}
41
42static void
43enable_intreq_irq(unsigned int irq)
44{
45 ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSKCLR0);
46}
47
48static void
49mask_and_ack_intreq_irq(unsigned int irq)
50{
51 disable_intreq_irq(irq);
52}
53
54static unsigned int
55startup_intreq_irq(unsigned int irq)
56{
57 enable_intreq_irq(irq);
58 return 0;
59}
60
61static void
62shutdown_intreq_irq(unsigned int irq)
63{
64 disable_intreq_irq(irq);
65}
66
67static void
68end_intreq_irq(unsigned int irq)
69{
70 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
71 enable_intreq_irq(irq);
72}
73
74static struct hw_interrupt_type intreq_irq_type = {
75 .typename = "intreq",
76 .startup = startup_intreq_irq,
77 .shutdown = shutdown_intreq_irq,
78 .enable = enable_intreq_irq,
79 .disable = disable_intreq_irq,
80 .ack = mask_and_ack_intreq_irq,
81 .end = end_intreq_irq
82};
83
84void
85make_intreq_irq(unsigned int irq)
86{
87 disable_irq_nosync(irq);
88 irq_desc[irq].handler = &intreq_irq_type;
89 disable_intreq_irq(irq);
90}
91
92int
93shmse_irq_demux(int irq)
94{
95 if (irq == IRQ5_IRQ)
96 return 10;
97 return irq;
98}
99
100/*
101 * Initialize IRQ setting
102 */
103void __init
104init_73180se_IRQ(void)
105{
106 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
107
108 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
109 ctrl_outw(0x2000, 0xb07fffec); /* mrshpc irq enable */
110 ctrl_outl(3 << ((7 - 5) * 4), INTC_INTPRI0); /* irq5 pri=3 */
111 ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1); /* low-level irq */
112 make_intreq_irq(10);
113
114 make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
115
116 ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */
117
118 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
119 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
120 make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
121 make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
122 make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
123 IIC0_PRIORITY);
124 make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
125 IIC0_PRIORITY);
126 make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
127 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
128 make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
129
130 /* VIO interrupt */
131 make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
132 make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
133 make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
134
135 make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
136 ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
137}
diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c
new file mode 100644
index 000000000000..1e8f1cf3e10f
--- /dev/null
+++ b/arch/sh/boards/se/73180/led.c
@@ -0,0 +1,67 @@
1/*
2 * arch/sh/boards/se/73180/led.c
3 *
4 * Derived from arch/sh/boards/se/770x/led.c
5 *
6 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * This file contains Solution Engine specific LED code.
12 */
13
14#include <linux/config.h>
15#include <linux/sched.h>
16#include <asm/mach/se73180.h>
17
18static void
19mach_led(int position, int value)
20{
21 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
22
23 if (value) {
24 *p |= (1 << LED_SHIFT);
25 } else {
26 *p &= ~(1 << LED_SHIFT);
27 }
28}
29
30/* Cycle the LED's in the clasic Knightrider/Sun pattern */
31void
32heartbeat_73180se(void)
33{
34 static unsigned int cnt = 0, period = 0;
35 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
36 static unsigned bit = 0, up = 1;
37
38 cnt += 1;
39 if (cnt < period) {
40 return;
41 }
42
43 cnt = 0;
44
45 /* Go through the points (roughly!):
46 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
47 */
48 period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
49
50 if (up) {
51 if (bit == 7) {
52 bit--;
53 up = 0;
54 } else {
55 bit++;
56 }
57 } else {
58 if (bit == 0) {
59 bit++;
60 up = 1;
61 } else {
62 bit--;
63 }
64 }
65 *p = 1 << (bit + LED_SHIFT);
66
67}
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c
new file mode 100644
index 000000000000..07fa90c38a06
--- /dev/null
+++ b/arch/sh/boards/se/73180/setup.c
@@ -0,0 +1,68 @@
1/*
2 * arch/sh/boards/se/73180/setup.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/setup_shmse.c
6 *
7 * Modified for 73180 SolutionEngine
8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/machvec.h>
15#include <asm/machvec_init.h>
16#include <asm/mach/io.h>
17
18void heartbeat_73180se(void);
19void init_73180se_IRQ(void);
20
21const char *
22get_system_type(void)
23{
24 return "SolutionEngine 73180";
25}
26
27/*
28 * The Machine Vector
29 */
30
31struct sh_machine_vector mv_73180se __initmv = {
32 .mv_nr_irqs = 108,
33 .mv_inb = sh73180se_inb,
34 .mv_inw = sh73180se_inw,
35 .mv_inl = sh73180se_inl,
36 .mv_outb = sh73180se_outb,
37 .mv_outw = sh73180se_outw,
38 .mv_outl = sh73180se_outl,
39
40 .mv_inb_p = sh73180se_inb_p,
41 .mv_inw_p = sh73180se_inw,
42 .mv_inl_p = sh73180se_inl,
43 .mv_outb_p = sh73180se_outb_p,
44 .mv_outw_p = sh73180se_outw,
45 .mv_outl_p = sh73180se_outl,
46
47 .mv_insb = sh73180se_insb,
48 .mv_insw = sh73180se_insw,
49 .mv_insl = sh73180se_insl,
50 .mv_outsb = sh73180se_outsb,
51 .mv_outsw = sh73180se_outsw,
52 .mv_outsl = sh73180se_outsl,
53
54 .mv_init_irq = init_73180se_IRQ,
55#ifdef CONFIG_HEARTBEAT
56 .mv_heartbeat = heartbeat_73180se,
57#endif
58};
59
60ALIAS_MV(73180se)
61/*
62 * Initialize the board
63 */
64void __init
65platform_setup(void)
66{
67
68}