1/*
2 *  linux/arch/m32r/kernel/setup_opsput.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/system.h>
21#include <asm/m32r.h>
22#include <asm/io.h>
23
24/*
25 * OPSP Interrupt Control Unit (Level 1)
26 */
27#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
28
29icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
30
31static void disable_opsput_irq(unsigned int irq)
32{
33	unsigned long port, data;
34
35	port = irq2port(irq);
36	data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7;
37	outl(data, port);
38}
39
40static void enable_opsput_irq(unsigned int irq)
41{
42	unsigned long port, data;
43
44	port = irq2port(irq);
45	data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6;
46	outl(data, port);
47}
48
49static void mask_and_ack_opsput(unsigned int irq)
50{
51	disable_opsput_irq(irq);
52}
53
54static void end_opsput_irq(unsigned int irq)
55{
56	enable_opsput_irq(irq);
57}
58
59static unsigned int startup_opsput_irq(unsigned int irq)
60{
61	enable_opsput_irq(irq);
62	return (0);
63}
64
65static void shutdown_opsput_irq(unsigned int irq)
66{
67	unsigned long port;
68
69	port = irq2port(irq);
70	outl(M32R_ICUCR_ILEVEL7, port);
71}
72
73static struct hw_interrupt_type opsput_irq_type =
74{
75	.typename = "OPSPUT-IRQ",
76	.startup = startup_opsput_irq,
77	.shutdown = shutdown_opsput_irq,
78	.enable = enable_opsput_irq,
79	.disable = disable_opsput_irq,
80	.ack = mask_and_ack_opsput,
81	.end = end_opsput_irq
82};
83
84/*
85 * Interrupt Control Unit of PLD on OPSPUT (Level 2)
86 */
87#define irq2pldirq(x)		((x) - OPSPUT_PLD_IRQ_BASE)
88#define pldirq2port(x)		(unsigned long)((int)PLD_ICUCR1 + \
89				 (((x) - 1) * sizeof(unsigned short)))
90
91typedef struct {
92	unsigned short icucr;  /* ICU Control Register */
93} pld_icu_data_t;
94
95static pld_icu_data_t pld_icu_data[OPSPUT_NUM_PLD_IRQ];
96
97static void disable_opsput_pld_irq(unsigned int irq)
98{
99	unsigned long port, data;
100	unsigned int pldirq;
101
102	pldirq = irq2pldirq(irq);
103//	disable_opsput_irq(M32R_IRQ_INT1);
104	port = pldirq2port(pldirq);
105	data = pld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
106	outw(data, port);
107}
108
109static void enable_opsput_pld_irq(unsigned int irq)
110{
111	unsigned long port, data;
112	unsigned int pldirq;
113
114	pldirq = irq2pldirq(irq);
115//	enable_opsput_irq(M32R_IRQ_INT1);
116	port = pldirq2port(pldirq);
117	data = pld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
118	outw(data, port);
119}
120
121static void mask_and_ack_opsput_pld(unsigned int irq)
122{
123	disable_opsput_pld_irq(irq);
124//	mask_and_ack_opsput(M32R_IRQ_INT1);
125}
126
127static void end_opsput_pld_irq(unsigned int irq)
128{
129	enable_opsput_pld_irq(irq);
130	end_opsput_irq(M32R_IRQ_INT1);
131}
132
133static unsigned int startup_opsput_pld_irq(unsigned int irq)
134{
135	enable_opsput_pld_irq(irq);
136	return (0);
137}
138
139static void shutdown_opsput_pld_irq(unsigned int irq)
140{
141	unsigned long port;
142	unsigned int pldirq;
143
144	pldirq = irq2pldirq(irq);
145//	shutdown_opsput_irq(M32R_IRQ_INT1);
146	port = pldirq2port(pldirq);
147	outw(PLD_ICUCR_ILEVEL7, port);
148}
149
150static struct hw_interrupt_type opsput_pld_irq_type =
151{
152	.typename = "OPSPUT-PLD-IRQ",
153	.startup = startup_opsput_pld_irq,
154	.shutdown = shutdown_opsput_pld_irq,
155	.enable = enable_opsput_pld_irq,
156	.disable = disable_opsput_pld_irq,
157	.ack = mask_and_ack_opsput_pld,
158	.end = end_opsput_pld_irq
159};
160
161/*
162 * Interrupt Control Unit of PLD on OPSPUT-LAN (Level 2)
163 */
164#define irq2lanpldirq(x)	((x) - OPSPUT_LAN_PLD_IRQ_BASE)
165#define lanpldirq2port(x)	(unsigned long)((int)OPSPUT_LAN_ICUCR1 + \
166				 (((x) - 1) * sizeof(unsigned short)))
167
168static pld_icu_data_t lanpld_icu_data[OPSPUT_NUM_LAN_PLD_IRQ];
169
170static void disable_opsput_lanpld_irq(unsigned int irq)
171{
172	unsigned long port, data;
173	unsigned int pldirq;
174
175	pldirq = irq2lanpldirq(irq);
176	port = lanpldirq2port(pldirq);
177	data = lanpld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
178	outw(data, port);
179}
180
181static void enable_opsput_lanpld_irq(unsigned int irq)
182{
183	unsigned long port, data;
184	unsigned int pldirq;
185
186	pldirq = irq2lanpldirq(irq);
187	port = lanpldirq2port(pldirq);
188	data = lanpld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
189	outw(data, port);
190}
191
192static void mask_and_ack_opsput_lanpld(unsigned int irq)
193{
194	disable_opsput_lanpld_irq(irq);
195}
196
197static void end_opsput_lanpld_irq(unsigned int irq)
198{
199	enable_opsput_lanpld_irq(irq);
200	end_opsput_irq(M32R_IRQ_INT0);
201}
202
203static unsigned int startup_opsput_lanpld_irq(unsigned int irq)
204{
205	enable_opsput_lanpld_irq(irq);
206	return (0);
207}
208
209static void shutdown_opsput_lanpld_irq(unsigned int irq)
210{
211	unsigned long port;
212	unsigned int pldirq;
213
214	pldirq = irq2lanpldirq(irq);
215	port = lanpldirq2port(pldirq);
216	outw(PLD_ICUCR_ILEVEL7, port);
217}
218
219static struct hw_interrupt_type opsput_lanpld_irq_type =
220{
221	.typename = "OPSPUT-PLD-LAN-IRQ",
222	.startup = startup_opsput_lanpld_irq,
223	.shutdown = shutdown_opsput_lanpld_irq,
224	.enable = enable_opsput_lanpld_irq,
225	.disable = disable_opsput_lanpld_irq,
226	.ack = mask_and_ack_opsput_lanpld,
227	.end = end_opsput_lanpld_irq
228};
229
230/*
231 * Interrupt Control Unit of PLD on OPSPUT-LCD (Level 2)
232 */
233#define irq2lcdpldirq(x)	((x) - OPSPUT_LCD_PLD_IRQ_BASE)
234#define lcdpldirq2port(x)	(unsigned long)((int)OPSPUT_LCD_ICUCR1 + \
235				 (((x) - 1) * sizeof(unsigned short)))
236
237static pld_icu_data_t lcdpld_icu_data[OPSPUT_NUM_LCD_PLD_IRQ];
238
239static void disable_opsput_lcdpld_irq(unsigned int irq)
240{
241	unsigned long port, data;
242	unsigned int pldirq;
243
244	pldirq = irq2lcdpldirq(irq);
245	port = lcdpldirq2port(pldirq);
246	data = lcdpld_icu_data[pldirq].icucr|PLD_ICUCR_ILEVEL7;
247	outw(data, port);
248}
249
250static void enable_opsput_lcdpld_irq(unsigned int irq)
251{
252	unsigned long port, data;
253	unsigned int pldirq;
254
255	pldirq = irq2lcdpldirq(irq);
256	port = lcdpldirq2port(pldirq);
257	data = lcdpld_icu_data[pldirq].icucr|PLD_ICUCR_IEN|PLD_ICUCR_ILEVEL6;
258	outw(data, port);
259}
260
261static void mask_and_ack_opsput_lcdpld(unsigned int irq)
262{
263	disable_opsput_lcdpld_irq(irq);
264}
265
266static void end_opsput_lcdpld_irq(unsigned int irq)
267{
268	enable_opsput_lcdpld_irq(irq);
269	end_opsput_irq(M32R_IRQ_INT2);
270}
271
272static unsigned int startup_opsput_lcdpld_irq(unsigned int irq)
273{
274	enable_opsput_lcdpld_irq(irq);
275	return (0);
276}
277
278static void shutdown_opsput_lcdpld_irq(unsigned int irq)
279{
280	unsigned long port;
281	unsigned int pldirq;
282
283	pldirq = irq2lcdpldirq(irq);
284	port = lcdpldirq2port(pldirq);
285	outw(PLD_ICUCR_ILEVEL7, port);
286}
287
288static struct hw_interrupt_type opsput_lcdpld_irq_type =
289{
290	"OPSPUT-PLD-LCD-IRQ",
291	startup_opsput_lcdpld_irq,
292	shutdown_opsput_lcdpld_irq,
293	enable_opsput_lcdpld_irq,
294	disable_opsput_lcdpld_irq,
295	mask_and_ack_opsput_lcdpld,
296	end_opsput_lcdpld_irq
297};
298
299void __init init_IRQ(void)
300{
301#if defined(CONFIG_SMC91X)
302	/* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/
303	irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED;
304	irq_desc[OPSPUT_LAN_IRQ_LAN].chip = &opsput_lanpld_irq_type;
305	irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0;
306	irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1;	/* disable nested irq */
307	lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* "H" edge sense */
308	disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN);
309#endif  /* CONFIG_SMC91X */
310
311	/* MFT2 : system timer */
312	irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED;
313	irq_desc[M32R_IRQ_MFT2].chip = &opsput_irq_type;
314	irq_desc[M32R_IRQ_MFT2].action = 0;
315	irq_desc[M32R_IRQ_MFT2].depth = 1;
316	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
317	disable_opsput_irq(M32R_IRQ_MFT2);
318
319	/* SIO0 : receive */
320	irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
321	irq_desc[M32R_IRQ_SIO0_R].chip = &opsput_irq_type;
322	irq_desc[M32R_IRQ_SIO0_R].action = 0;
323	irq_desc[M32R_IRQ_SIO0_R].depth = 1;
324	icu_data[M32R_IRQ_SIO0_R].icucr = 0;
325	disable_opsput_irq(M32R_IRQ_SIO0_R);
326
327	/* SIO0 : send */
328	irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
329	irq_desc[M32R_IRQ_SIO0_S].chip = &opsput_irq_type;
330	irq_desc[M32R_IRQ_SIO0_S].action = 0;
331	irq_desc[M32R_IRQ_SIO0_S].depth = 1;
332	icu_data[M32R_IRQ_SIO0_S].icucr = 0;
333	disable_opsput_irq(M32R_IRQ_SIO0_S);
334
335	/* SIO1 : receive */
336	irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED;
337	irq_desc[M32R_IRQ_SIO1_R].chip = &opsput_irq_type;
338	irq_desc[M32R_IRQ_SIO1_R].action = 0;
339	irq_desc[M32R_IRQ_SIO1_R].depth = 1;
340	icu_data[M32R_IRQ_SIO1_R].icucr = 0;
341	disable_opsput_irq(M32R_IRQ_SIO1_R);
342
343	/* SIO1 : send */
344	irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED;
345	irq_desc[M32R_IRQ_SIO1_S].chip = &opsput_irq_type;
346	irq_desc[M32R_IRQ_SIO1_S].action = 0;
347	irq_desc[M32R_IRQ_SIO1_S].depth = 1;
348	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
349	disable_opsput_irq(M32R_IRQ_SIO1_S);
350
351	/* DMA1 : */
352	irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED;
353	irq_desc[M32R_IRQ_DMA1].chip = &opsput_irq_type;
354	irq_desc[M32R_IRQ_DMA1].action = 0;
355	irq_desc[M32R_IRQ_DMA1].depth = 1;
356	icu_data[M32R_IRQ_DMA1].icucr = 0;
357	disable_opsput_irq(M32R_IRQ_DMA1);
358
359#ifdef CONFIG_SERIAL_M32R_PLDSIO
360	/* INT#1: SIO0 Receive on PLD */
361	irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED;
362	irq_desc[PLD_IRQ_SIO0_RCV].chip = &opsput_pld_irq_type;
363	irq_desc[PLD_IRQ_SIO0_RCV].action = 0;
364	irq_desc[PLD_IRQ_SIO0_RCV].depth = 1;	/* disable nested irq */
365	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
366	disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV);
367
368	/* INT#1: SIO0 Send on PLD */
369	irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED;
370	irq_desc[PLD_IRQ_SIO0_SND].chip = &opsput_pld_irq_type;
371	irq_desc[PLD_IRQ_SIO0_SND].action = 0;
372	irq_desc[PLD_IRQ_SIO0_SND].depth = 1;	/* disable nested irq */
373	pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03;
374	disable_opsput_pld_irq(PLD_IRQ_SIO0_SND);
375#endif  /* CONFIG_SERIAL_M32R_PLDSIO */
376
377	/* INT#1: CFC IREQ on PLD */
378	irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED;
379	irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type;
380	irq_desc[PLD_IRQ_CFIREQ].action = 0;
381	irq_desc[PLD_IRQ_CFIREQ].depth = 1;	/* disable nested irq */
382	pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* 'L' level sense */
383	disable_opsput_pld_irq(PLD_IRQ_CFIREQ);
384
385	/* INT#1: CFC Insert on PLD */
386	irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
387	irq_desc[PLD_IRQ_CFC_INSERT].chip = &opsput_pld_irq_type;
388	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
389	irq_desc[PLD_IRQ_CFC_INSERT].depth = 1;	/* disable nested irq */
390	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00;	/* 'L' edge sense */
391	disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT);
392
393	/* INT#1: CFC Eject on PLD */
394	irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
395	irq_desc[PLD_IRQ_CFC_EJECT].chip = &opsput_pld_irq_type;
396	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
397	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
398	pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02;	/* 'H' edge sense */
399	disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT);
400
401	/*
402	 * INT0# is used for LAN, DIO
403	 * We enable it here.
404	 */
405	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
406	enable_opsput_irq(M32R_IRQ_INT0);
407
408	/*
409	 * INT1# is used for UART, MMC, CF Controller in FPGA.
410	 * We enable it here.
411	 */
412	icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11;
413	enable_opsput_irq(M32R_IRQ_INT1);
414
415#if defined(CONFIG_USB)
416	outw(USBCR_OTGS, USBCR); 	/* USBCR: non-OTG */
417
418    irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED;
419    irq_desc[OPSPUT_LCD_IRQ_USB_INT1].chip = &opsput_lcdpld_irq_type;
420    irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0;
421    irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1;
422    lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01;	/* "L" level sense */
423    disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1);
424#endif
425	/*
426	 * INT2# is used for BAT, USB, AUDIO
427	 * We enable it here.
428	 */
429	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
430	enable_opsput_irq(M32R_IRQ_INT2);
431
432#if defined(CONFIG_VIDEO_M32R_AR)
433	/*
434	 * INT3# is used for AR
435	 */
436	irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED;
437	irq_desc[M32R_IRQ_INT3].chip = &opsput_irq_type;
438	irq_desc[M32R_IRQ_INT3].action = 0;
439	irq_desc[M32R_IRQ_INT3].depth = 1;
440	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
441	disable_opsput_irq(M32R_IRQ_INT3);
442#endif /* CONFIG_VIDEO_M32R_AR */
443}
444
445#if defined(CONFIG_SMC91X)
446
447#define LAN_IOSTART     0x300
448#define LAN_IOEND       0x320
449static struct resource smc91x_resources[] = {
450	[0] = {
451		.start  = (LAN_IOSTART),
452		.end    = (LAN_IOEND),
453		.flags  = IORESOURCE_MEM,
454	},
455	[1] = {
456		.start  = OPSPUT_LAN_IRQ_LAN,
457		.end    = OPSPUT_LAN_IRQ_LAN,
458		.flags  = IORESOURCE_IRQ,
459	}
460};
461
462static struct platform_device smc91x_device = {
463	.name		= "smc91x",
464	.id		= 0,
465	.num_resources  = ARRAY_SIZE(smc91x_resources),
466	.resource       = smc91x_resources,
467};
468#endif
469
470#if defined(CONFIG_FB_S1D13XXX)
471
472#include <video/s1d13xxxfb.h>
473#include <asm/s1d13806.h>
474
475static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
476	.initregs		= s1d13xxxfb_initregs,
477	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
478	.platform_init_video	= NULL,
479#ifdef CONFIG_PM
480	.platform_suspend_video	= NULL,
481	.platform_resume_video	= NULL,
482#endif
483};
484
485static struct resource s1d13xxxfb_resources[] = {
486	[0] = {
487		.start  = 0x10600000UL,
488		.end    = 0x1073FFFFUL,
489		.flags  = IORESOURCE_MEM,
490	},
491	[1] = {
492		.start  = 0x10400000UL,
493		.end    = 0x104001FFUL,
494		.flags  = IORESOURCE_MEM,
495	}
496};
497
498static struct platform_device s1d13xxxfb_device = {
499	.name		= S1D_DEVICENAME,
500	.id		= 0,
501	.dev            = {
502		.platform_data  = &s1d13xxxfb_data,
503	},
504	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
505	.resource       = s1d13xxxfb_resources,
506};
507#endif
508
509static int __init platform_init(void)
510{
511#if defined(CONFIG_SMC91X)
512	platform_device_register(&smc91x_device);
513#endif
514#if defined(CONFIG_FB_S1D13XXX)
515	platform_device_register(&s1d13xxxfb_device);
516#endif
517	return 0;
518}
519arch_initcall(platform_init);
520