aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/se/7206
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/se/7206')
-rw-r--r--arch/sh/boards/se/7206/Makefile7
-rw-r--r--arch/sh/boards/se/7206/io.c123
-rw-r--r--arch/sh/boards/se/7206/irq.c147
-rw-r--r--arch/sh/boards/se/7206/led.c57
-rw-r--r--arch/sh/boards/se/7206/setup.c79
5 files changed, 413 insertions, 0 deletions
diff --git a/arch/sh/boards/se/7206/Makefile b/arch/sh/boards/se/7206/Makefile
new file mode 100644
index 000000000000..63950f4f2453
--- /dev/null
+++ b/arch/sh/boards/se/7206/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the 7206 SolutionEngine specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6obj-$(CONFIG_HEARTBEAT) += led.o
7
diff --git a/arch/sh/boards/se/7206/io.c b/arch/sh/boards/se/7206/io.c
new file mode 100644
index 000000000000..b557273e0cbe
--- /dev/null
+++ b/arch/sh/boards/se/7206/io.c
@@ -0,0 +1,123 @@
1/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
2 *
3 * linux/arch/sh/boards/se/7206/io.c
4 *
5 * Copyright (C) 2006 Yoshinori Sato
6 *
7 * I/O routine for Hitachi 7206 SolutionEngine.
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <asm/io.h>
14#include <asm/se7206.h>
15
16
17static inline void delay(void)
18{
19 ctrl_inw(0x20000000); /* P2 ROM Area */
20}
21
22/* MS7750 requires special versions of in*, out* routines, since
23 PC-like io ports are located at upper half byte of 16-bit word which
24 can be accessed only with 16-bit wide. */
25
26static inline volatile __u16 *
27port2adr(unsigned int port)
28{
29 if (port >= 0x2000)
30 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
31 else if (port >= 0x300 || port < 0x310)
32 return (volatile __u16 *) (PA_SMSC + (port - 0x300));
33}
34
35unsigned char se7206_inb(unsigned long port)
36{
37 return (*port2adr(port))&0xff;
38}
39
40unsigned char se7206_inb_p(unsigned long port)
41{
42 unsigned long v;
43
44 v = (*port2adr(port))&0xff;
45 delay();
46 return v;
47}
48
49unsigned short se7206_inw(unsigned long port)
50{
51 return *port2adr(port);;
52}
53
54unsigned int se7206_inl(unsigned long port)
55{
56 maybebadio(port);
57 return 0;
58}
59
60void se7206_outb(unsigned char value, unsigned long port)
61{
62 *(port2adr(port)) = value;
63}
64
65void se7206_outb_p(unsigned char value, unsigned long port)
66{
67 *(port2adr(port)) = value;
68 delay();
69}
70
71void se7206_outw(unsigned short value, unsigned long port)
72{
73 *port2adr(port) = value;
74}
75
76void se7206_outl(unsigned int value, unsigned long port)
77{
78 maybebadio(port);
79}
80
81void se7206_insb(unsigned long port, void *addr, unsigned long count)
82{
83 volatile __u16 *p = port2adr(port);
84 __u8 *ap = addr;
85
86 while (count--)
87 *ap++ = *p;
88}
89
90void se7206_insw(unsigned long port, void *addr, unsigned long count)
91{
92 volatile __u16 *p = port2adr(port);
93 __u16 *ap = addr;
94 while (count--)
95 *ap++ = *p;
96}
97
98void se7206_insl(unsigned long port, void *addr, unsigned long count)
99{
100 maybebadio(port);
101}
102
103void se7206_outsb(unsigned long port, const void *addr, unsigned long count)
104{
105 volatile __u16 *p = port2adr(port);
106 const __u8 *ap = addr;
107
108 while (count--)
109 *p = *ap++;
110}
111
112void se7206_outsw(unsigned long port, const void *addr, unsigned long count)
113{
114 volatile __u16 *p = port2adr(port);
115 const __u16 *ap = addr;
116 while (count--)
117 *p = *ap++;
118}
119
120void se7206_outsl(unsigned long port, const void *addr, unsigned long count)
121{
122 maybebadio(port);
123}
diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c
new file mode 100644
index 000000000000..27da88486f73
--- /dev/null
+++ b/arch/sh/boards/se/7206/irq.c
@@ -0,0 +1,147 @@
1/*
2 * linux/arch/sh/boards/se/7206/irq.c
3 *
4 * Copyright (C) 2005,2006 Yoshinori Sato
5 *
6 * Hitachi SolutionEngine Support.
7 *
8 */
9#include <linux/init.h>
10#include <linux/irq.h>
11#include <linux/io.h>
12#include <linux/irq.h>
13#include <linux/interrupt.h>
14#include <asm/se7206.h>
15
16#define INTSTS0 0x31800000
17#define INTSTS1 0x31800002
18#define INTMSK0 0x31800004
19#define INTMSK1 0x31800006
20#define INTSEL 0x31800008
21
22#define IRQ0_IRQ 64
23#define IRQ1_IRQ 65
24#define IRQ3_IRQ 67
25
26#define INTC_IPR01 0xfffe0818
27#define INTC_ICR1 0xfffe0802
28
29static void disable_se7206_irq(unsigned int irq)
30{
31 unsigned short val;
32 unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
33 unsigned short msk0,msk1;
34
35 /* Set the priority in IPR to 0 */
36 val = ctrl_inw(INTC_IPR01);
37 val &= mask;
38 ctrl_outw(val, INTC_IPR01);
39 /* FPGA mask set */
40 msk0 = ctrl_inw(INTMSK0);
41 msk1 = ctrl_inw(INTMSK1);
42
43 switch (irq) {
44 case IRQ0_IRQ:
45 msk0 |= 0x0010;
46 break;
47 case IRQ1_IRQ:
48 msk0 |= 0x000f;
49 break;
50 case IRQ3_IRQ:
51 msk0 |= 0x0f00;
52 msk1 |= 0x00ff;
53 break;
54 }
55 ctrl_outw(msk0, INTMSK0);
56 ctrl_outw(msk1, INTMSK1);
57}
58
59static void enable_se7206_irq(unsigned int irq)
60{
61 unsigned short val;
62 unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
63 unsigned short msk0,msk1;
64
65 /* Set priority in IPR back to original value */
66 val = ctrl_inw(INTC_IPR01);
67 val |= value;
68 ctrl_outw(val, INTC_IPR01);
69
70 /* FPGA mask reset */
71 msk0 = ctrl_inw(INTMSK0);
72 msk1 = ctrl_inw(INTMSK1);
73
74 switch (irq) {
75 case IRQ0_IRQ:
76 msk0 &= ~0x0010;
77 break;
78 case IRQ1_IRQ:
79 msk0 &= ~0x000f;
80 break;
81 case IRQ3_IRQ:
82 msk0 &= ~0x0f00;
83 msk1 &= ~0x00ff;
84 break;
85 }
86 ctrl_outw(msk0, INTMSK0);
87 ctrl_outw(msk1, INTMSK1);
88}
89
90static void eoi_se7206_irq(unsigned int irq)
91{
92 unsigned short sts0,sts1;
93
94 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
95 enable_se7206_irq(irq);
96 /* FPGA isr clear */
97 sts0 = ctrl_inw(INTSTS0);
98 sts1 = ctrl_inw(INTSTS1);
99
100 switch (irq) {
101 case IRQ0_IRQ:
102 sts0 &= ~0x0010;
103 break;
104 case IRQ1_IRQ:
105 sts0 &= ~0x000f;
106 break;
107 case IRQ3_IRQ:
108 sts0 &= ~0x0f00;
109 sts1 &= ~0x00ff;
110 break;
111 }
112 ctrl_outw(sts0, INTSTS0);
113 ctrl_outw(sts1, INTSTS1);
114}
115
116static struct irq_chip se7206_irq_chip __read_mostly = {
117 .name = "SE7206-FPGA",
118 .mask = disable_se7206_irq,
119 .unmask = enable_se7206_irq,
120 .mask_ack = disable_se7206_irq,
121 .eoi = eoi_se7206_irq,
122};
123
124static void make_se7206_irq(unsigned int irq)
125{
126 disable_irq_nosync(irq);
127 set_irq_chip_and_handler_name(irq, &se7206_irq_chip,
128 handle_level_irq, "level");
129 disable_se7206_irq(irq);
130}
131
132/*
133 * Initialize IRQ setting
134 */
135void __init init_se7206_IRQ(void)
136{
137 make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
138 make_se7206_irq(IRQ1_IRQ); /* ATA */
139 make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
140 ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
141
142 /* FPGA System register setup*/
143 ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
144 ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
145 /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
146 ctrl_outw(0x0001,INTSEL);
147}
diff --git a/arch/sh/boards/se/7206/led.c b/arch/sh/boards/se/7206/led.c
new file mode 100644
index 000000000000..ef794601ab86
--- /dev/null
+++ b/arch/sh/boards/se/7206/led.c
@@ -0,0 +1,57 @@
1/*
2 * linux/arch/sh/kernel/led_se.c
3 *
4 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains Solution Engine specific LED code.
10 */
11
12#include <linux/config.h>
13#include <asm/se7206.h>
14
15#ifdef CONFIG_HEARTBEAT
16
17#include <linux/sched.h>
18
19/* Cycle the LED's in the clasic Knightrider/Sun pattern */
20void heartbeat_se(void)
21{
22 static unsigned int cnt = 0, period = 0;
23 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
24 static unsigned bit = 0, up = 1;
25
26 cnt += 1;
27 if (cnt < period) {
28 return;
29 }
30
31 cnt = 0;
32
33 /* Go through the points (roughly!):
34 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
35 */
36 period = 110 - ( (300<<FSHIFT)/
37 ((avenrun[0]/5) + (3<<FSHIFT)) );
38
39 if (up) {
40 if (bit == 7) {
41 bit--;
42 up=0;
43 } else {
44 bit ++;
45 }
46 } else {
47 if (bit == 0) {
48 bit++;
49 up=1;
50 } else {
51 bit--;
52 }
53 }
54 *p = 1<<(bit+8);
55
56}
57#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c
new file mode 100644
index 000000000000..0f42e91a3238
--- /dev/null
+++ b/arch/sh/boards/se/7206/setup.c
@@ -0,0 +1,79 @@
1/*
2 *
3 * linux/arch/sh/boards/se/7206/setup.c
4 *
5 * Copyright (C) 2006 Yoshinori Sato
6 *
7 * Hitachi 7206 SolutionEngine Support.
8 *
9 */
10
11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <asm/se7206.h>
14#include <asm/io.h>
15#include <asm/machvec.h>
16
17static struct resource smc91x_resources[] = {
18 [0] = {
19 .start = 0x300,
20 .end = 0x300 + 0x020 - 1,
21 .flags = IORESOURCE_MEM,
22 },
23 [1] = {
24 .start = 64,
25 .end = 64,
26 .flags = IORESOURCE_IRQ,
27 },
28};
29
30static struct platform_device smc91x_device = {
31 .name = "smc91x",
32 .id = -1,
33 .num_resources = ARRAY_SIZE(smc91x_resources),
34 .resource = smc91x_resources,
35};
36
37static int __init se7206_devices_setup(void)
38{
39 return platform_device_register(&smc91x_device);
40}
41
42__initcall(se7206_devices_setup);
43
44void heartbeat_se(void);
45
46/*
47 * The Machine Vector
48 */
49
50struct sh_machine_vector mv_se __initmv = {
51 .mv_name = "SolutionEngine",
52 .mv_nr_irqs = 256,
53 .mv_inb = se7206_inb,
54 .mv_inw = se7206_inw,
55 .mv_inl = se7206_inl,
56 .mv_outb = se7206_outb,
57 .mv_outw = se7206_outw,
58 .mv_outl = se7206_outl,
59
60 .mv_inb_p = se7206_inb_p,
61 .mv_inw_p = se7206_inw,
62 .mv_inl_p = se7206_inl,
63 .mv_outb_p = se7206_outb_p,
64 .mv_outw_p = se7206_outw,
65 .mv_outl_p = se7206_outl,
66
67 .mv_insb = se7206_insb,
68 .mv_insw = se7206_insw,
69 .mv_insl = se7206_insl,
70 .mv_outsb = se7206_outsb,
71 .mv_outsw = se7206_outsw,
72 .mv_outsl = se7206_outsl,
73
74 .mv_init_irq = init_se7206_IRQ,
75#ifdef CONFIG_HEARTBEAT
76 .mv_heartbeat = heartbeat_se,
77#endif
78};
79ALIAS_MV(se)