1/*
2 *  linux/arch/m32r/platforms/opsput/setup.c
3 *
4 *  Setup routines for Renesas OPSPUT Board
5 *
6 *  Copyright (c) 2002-2005
7 * 	Hiroyuki Kondo, Hirokazu Takata,
8 *      Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa
9 *
10 *  This file is subject to the terms and conditions of the GNU General
11 *  Public License.  See the file "COPYING" in the main directory of this
12 *  archive for more details.
13 */
14
15#include <linux/irq.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19
20#include <asm/m32r.h>
21#include <asm/io.h>
22
23/*
24 * OPSP Interrupt Control Unit (Level 1)
25 */
26#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
27
28icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
29
30static void disable_opsput_irq(unsigned int irq)
31{
32	unsigned long port, data;
33
34	port = irq2port(irq);
35	data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7;
36	outl(data, port);
37}
38
39static void enable_opsput_irq(unsigned int irq)
40{
41	unsigned long port, data;
42
43	port = irq2port(irq);
44	data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6;
45	outl(data, port);
46}
47
48static void mask_opsput(struct irq_data *data)
49{
50	disable_opsput_irq(data->irq);
51}
52
53static void unmask_opsput(struct irq_data *data)
54{
55	enable_opsput_irq(data->irq);
56}
57
58static void shutdown_opsput(struct irq_data *data)
59{
60	unsigned long port;
61
62	port = irq2port(data->irq);
63	outl(M32R_ICUCR_ILEVEL7, port);
64}
65
66static struct irq_chip opsput_irq_type =
67{
68	.name		= "OPSPUT-IRQ",
69	.irq_shutdown	= shutdown_opsput,
70	.irq_mask	= mask_opsput,
71	.irq_unmask	= unmask_opsput,
72};
73
74/*
75 * Interrupt Control Unit of PLD on OPSPUT (Level 2)
76 */
77#define irq2pldirq(x)		((x) - OPSPUT_PLD_IRQ_BASE)
78#define pldirq2port(x)		(unsigned long)((int)PLD_ICUCR1 + \
79				 (((x) - 1) * sizeof(unsigned short)))
80
81typedef struct {
82	unsigned short icucr;  /* ICU Control Register */
83} pld_icu_data_t;
84
85static pld_icu_data_t pld_icu_data[OPSPUT_NUM_PLD_IRQ];
86
87static void disable_opsput_pld_irq(unsigned int irq)
88{
89	unsigned long port, data;
90	unsigned int pldirq;
91
92	pldirq = irq2pldirq(irq);
93	port = pldirq2port(pldirq);
94	data = pld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
95	outw(data, port);
96}
97
98static void enable_opsput_pld_irq(unsigned int irq)
99{
100	unsigned long port, data;
101	unsigned int pldirq;
102
103	pldirq = irq2pldirq(irq);
104	port = pldirq2port(pldirq);
105	data = pld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
106	outw(data, port);
107}
108
109static void mask_opsput_pld(struct irq_data *data)
110{
111	disable_opsput_pld_irq(data->irq);
112}
113
114static void unmask_opsput_pld(struct irq_data *data)
115{
116	enable_opsput_pld_irq(data->irq);
117	enable_opsput_irq(M32R_IRQ_INT1);
118}
119
120static void shutdown_opsput_pld(struct irq_data *data)
121{
122	unsigned long port;
123	unsigned int pldirq;
124
125	pldirq = irq2pldirq(data->irq);
126	port = pldirq2port(pldirq);
127	outw(PLD_ICUCR_ILEVEL7, port);
128}
129
130static struct irq_chip opsput_pld_irq_type =
131{
132	.name		= "OPSPUT-PLD-IRQ",
133	.irq_shutdown	= shutdown_opsput_pld,
134	.irq_mask	= mask_opsput_pld,
135	.irq_unmask	= unmask_opsput_pld,
136};
137
138/*
139 * Interrupt Control Unit of PLD on OPSPUT-LAN (Level 2)
140 */
141#define irq2lanpldirq(x)	((x) - OPSPUT_LAN_PLD_IRQ_BASE)
142#define lanpldirq2port(x)	(unsigned long)((int)OPSPUT_LAN_ICUCR1 + \
143				 (((x) - 1) * sizeof(unsigned short)))
144
145static pld_icu_data_t lanpld_icu_data[OPSPUT_NUM_LAN_PLD_IRQ];
146
147static void disable_opsput_lanpld_irq(unsigned int irq)
148{
149	unsigned long port, data;
150	unsigned int pldirq;
151
152	pldirq = irq2lanpldirq(irq);
153	port = lanpldirq2port(pldirq);
154	data = lanpld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
155	outw(data, port);
156}
157
158static void enable_opsput_lanpld_irq(unsigned int irq)
159{
160	unsigned long port, data;
161	unsigned int pldirq;
162
163	pldirq = irq2lanpldirq(irq);
164	port = lanpldirq2port(pldirq);
165	data = lanpld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
166	outw(data, port);
167}
168
169static void mask_opsput_lanpld(struct irq_data *data)
170{
171	disable_opsput_lanpld_irq(data->irq);
172}
173
174static void unmask_opsput_lanpld(struct irq_data *data)
175{
176	enable_opsput_lanpld_irq(data->irq);
177	enable_opsput_irq(M32R_IRQ_INT0);
178}
179
180static void shutdown_opsput_lanpld(struct irq_data *data)
181{
182	unsigned long port;
183	unsigned int pldirq;
184
185	pldirq = irq2lanpldirq(data->irq);
186	port = lanpldirq2port(pldirq);
187	outw(PLD_ICUCR_ILEVEL7, port);
188}
189
190static struct irq_chip opsput_lanpld_irq_type =
191{
192	.name		= "OPSPUT-PLD-LAN-IRQ",
193	.irq_shutdown	= shutdown_opsput_lanpld,
194	.irq_mask	= mask_opsput_lanpld,
195	.irq_unmask	= unmask_opsput_lanpld,
196};
197
198/*
199 * Interrupt Control Unit of PLD on OPSPUT-LCD (Level 2)
200 */
201#define irq2lcdpldirq(x)	((x) - OPSPUT_LCD_PLD_IRQ_BASE)
202#define lcdpldirq2port(x)	(unsigned long)((int)OPSPUT_LCD_ICUCR1 + \
203				 (((x) - 1) * sizeof(unsigned short)))
204
205static pld_icu_data_t lcdpld_icu_data[OPSPUT_NUM_LCD_PLD_IRQ];
206
207static void disable_opsput_lcdpld_irq(unsigned int irq)
208{
209	unsigned long port, data;
210	unsigned int pldirq;
211
212	pldirq = irq2lcdpldirq(irq);
213	port = lcdpldirq2port(pldirq);
214	data = lcdpld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
215	outw(data, port);
216}
217
218static void enable_opsput_lcdpld_irq(unsigned int irq)
219{
220	unsigned long port, data;
221	unsigned int pldirq;
222
223	pldirq = irq2lcdpldirq(irq);
224	port = lcdpldirq2port(pldirq);
225	data = lcdpld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
226	outw(data, port);
227}
228
229static void mask_opsput_lcdpld(struct irq_data *data)
230{
231	disable_opsput_lcdpld_irq(data->irq);
232}
233
234static void unmask_opsput_lcdpld(struct irq_data *data)
235{
236	enable_opsput_lcdpld_irq(data->irq);
237	enable_opsput_irq(M32R_IRQ_INT2);
238}
239
240static void shutdown_opsput_lcdpld(struct irq_data *data)
241{
242	unsigned long port;
243	unsigned int pldirq;
244
245	pldirq = irq2lcdpldirq(data->irq);
246	port = lcdpldirq2port(pldirq);
247	outw(PLD_ICUCR_ILEVEL7, port);
248}
249
250static struct irq_chip opsput_lcdpld_irq_type = {
251	.name		= "OPSPUT-PLD-LCD-IRQ",
252	.irq_shutdown	= shutdown_opsput_lcdpld,
253	.irq_mask	= mask_opsput_lcdpld,
254	.irq_unmask	= unmask_opsput_lcdpld,
255};
256
257void __init init_IRQ(void)
258{
259#if defined(CONFIG_SMC91X)
260	/* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/
261	irq_set_chip_and_handler(OPSPUT_LAN_IRQ_LAN, &opsput_lanpld_irq_type,
262				 handle_level_irq);
263	lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* "H" edge sense */
264	disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN);
265#endif  /* CONFIG_SMC91X */
266
267	/* MFT2 : system timer */
268	irq_set_chip_and_handler(M32R_IRQ_MFT2, &opsput_irq_type,
269				 handle_level_irq);
270	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
271	disable_opsput_irq(M32R_IRQ_MFT2);
272
273	/* SIO0 : receive */
274	irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &opsput_irq_type,
275				 handle_level_irq);
276	icu_data[M32R_IRQ_SIO0_R].icucr = 0;
277	disable_opsput_irq(M32R_IRQ_SIO0_R);
278
279	/* SIO0 : send */
280	irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &opsput_irq_type,
281				 handle_level_irq);
282	icu_data[M32R_IRQ_SIO0_S].icucr = 0;
283	disable_opsput_irq(M32R_IRQ_SIO0_S);
284
285	/* SIO1 : receive */
286	irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &opsput_irq_type,
287				 handle_level_irq);
288	icu_data[M32R_IRQ_SIO1_R].icucr = 0;
289	disable_opsput_irq(M32R_IRQ_SIO1_R);
290
291	/* SIO1 : send */
292	irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &opsput_irq_type,
293				 handle_level_irq);
294	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
295	disable_opsput_irq(M32R_IRQ_SIO1_S);
296
297	/* DMA1 : */
298	irq_set_chip_and_handler(M32R_IRQ_DMA1, &opsput_irq_type,
299				 handle_level_irq);
300	icu_data[M32R_IRQ_DMA1].icucr = 0;
301	disable_opsput_irq(M32R_IRQ_DMA1);
302
303#ifdef CONFIG_SERIAL_M32R_PLDSIO
304	/* INT#1: SIO0 Receive on PLD */
305	irq_set_chip_and_handler(PLD_IRQ_SIO0_RCV, &opsput_pld_irq_type,
306				 handle_level_irq);
307	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
308	disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV);
309
310	/* INT#1: SIO0 Send on PLD */
311	irq_set_chip_and_handler(PLD_IRQ_SIO0_SND, &opsput_pld_irq_type,
312				 handle_level_irq);
313	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
314	disable_opsput_pld_irq(PLD_IRQ_SIO0_SND);
315#endif  /* CONFIG_SERIAL_M32R_PLDSIO */
316
317	/* INT#1: CFC IREQ on PLD */
318	irq_set_chip_and_handler(PLD_IRQ_CFIREQ, &opsput_pld_irq_type,
319				 handle_level_irq);
320	pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* 'L' level sense */
321	disable_opsput_pld_irq(PLD_IRQ_CFIREQ);
322
323	/* INT#1: CFC Insert on PLD */
324	irq_set_chip_and_handler(PLD_IRQ_CFC_INSERT, &opsput_pld_irq_type,
325				 handle_level_irq);
326	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00;	/* 'L' edge sense */
327	disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT);
328
329	/* INT#1: CFC Eject on PLD */
330	irq_set_chip_and_handler(PLD_IRQ_CFC_EJECT, &opsput_pld_irq_type,
331				 handle_level_irq);
332	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* 'H' edge sense */
333	disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT);
334
335	/*
336	 * INT0# is used for LAN, DIO
337	 * We enable it here.
338	 */
339	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
340	enable_opsput_irq(M32R_IRQ_INT0);
341
342	/*
343	 * INT1# is used for UART, MMC, CF Controller in FPGA.
344	 * We enable it here.
345	 */
346	icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
347	enable_opsput_irq(M32R_IRQ_INT1);
348
349#if defined(CONFIG_USB)
350	outw(USBCR_OTGS, USBCR);	/* USBCR: non-OTG */
351	irq_set_chip_and_handler(OPSPUT_LCD_IRQ_USB_INT1,
352				 &opsput_lcdpld_irq_type, handle_level_irq);
353	lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* "L" level sense */
354	disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1);
355#endif
356	/*
357	 * INT2# is used for BAT, USB, AUDIO
358	 * We enable it here.
359	 */
360	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
361	enable_opsput_irq(M32R_IRQ_INT2);
362
363#if defined(CONFIG_VIDEO_M32R_AR)
364	/*
365	 * INT3# is used for AR
366	 */
367	irq_set_chip_and_handler(M32R_IRQ_INT3, &opsput_irq_type,
368				 handle_level_irq);
369	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
370	disable_opsput_irq(M32R_IRQ_INT3);
371#endif /* CONFIG_VIDEO_M32R_AR */
372}
373
374#if defined(CONFIG_SMC91X)
375
376#define LAN_IOSTART     0x300
377#define LAN_IOEND       0x320
378static struct resource smc91x_resources[] = {
379	[0] = {
380		.start  = (LAN_IOSTART),
381		.end    = (LAN_IOEND),
382		.flags  = IORESOURCE_MEM,
383	},
384	[1] = {
385		.start  = OPSPUT_LAN_IRQ_LAN,
386		.end    = OPSPUT_LAN_IRQ_LAN,
387		.flags  = IORESOURCE_IRQ,
388	}
389};
390
391static struct platform_device smc91x_device = {
392	.name		= "smc91x",
393	.id		= 0,
394	.num_resources  = ARRAY_SIZE(smc91x_resources),
395	.resource       = smc91x_resources,
396};
397#endif
398
399#if defined(CONFIG_FB_S1D13XXX)
400
401#include <video/s1d13xxxfb.h>
402#include <asm/s1d13806.h>
403
404static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
405	.initregs		= s1d13xxxfb_initregs,
406	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
407	.platform_init_video	= NULL,
408#ifdef CONFIG_PM
409	.platform_suspend_video	= NULL,
410	.platform_resume_video	= NULL,
411#endif
412};
413
414static struct resource s1d13xxxfb_resources[] = {
415	[0] = {
416		.start  = 0x10600000UL,
417		.end    = 0x1073FFFFUL,
418		.flags  = IORESOURCE_MEM,
419	},
420	[1] = {
421		.start  = 0x10400000UL,
422		.end    = 0x104001FFUL,
423		.flags  = IORESOURCE_MEM,
424	}
425};
426
427static struct platform_device s1d13xxxfb_device = {
428	.name		= S1D_DEVICENAME,
429	.id		= 0,
430	.dev            = {
431		.platform_data  = &s1d13xxxfb_data,
432	},
433	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
434	.resource       = s1d13xxxfb_resources,
435};
436#endif
437
438static int __init platform_init(void)
439{
440#if defined(CONFIG_SMC91X)
441	platform_device_register(&smc91x_device);
442#endif
443#if defined(CONFIG_FB_S1D13XXX)
444	platform_device_register(&s1d13xxxfb_device);
445#endif
446	return 0;
447}
448arch_initcall(platform_init);
449