1 /***************************************************************************/
2 
3 /*
4  *	linux/arch/m68knommu/platform/5407/config.c
5  *
6  *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
7  *	Copyright (C) 2000, Lineo (www.lineo.com)
8  */
9 
10 /***************************************************************************/
11 
12 #include <linux/kernel.h>
13 #include <linux/param.h>
14 #include <linux/init.h>
15 #include <linux/io.h>
16 #include <asm/machdep.h>
17 #include <asm/coldfire.h>
18 #include <asm/mcfsim.h>
19 #include <asm/mcfuart.h>
20 
21 /***************************************************************************/
22 
23 static struct mcf_platform_uart m5407_uart_platform[] = {
24 	{
25 		.mapbase	= MCF_MBAR + MCFUART_BASE1,
26 		.irq		= 73,
27 	},
28 	{
29 		.mapbase 	= MCF_MBAR + MCFUART_BASE2,
30 		.irq		= 74,
31 	},
32 	{ },
33 };
34 
35 static struct platform_device m5407_uart = {
36 	.name			= "mcfuart",
37 	.id			= 0,
38 	.dev.platform_data	= m5407_uart_platform,
39 };
40 
41 static struct platform_device *m5407_devices[] __initdata = {
42 	&m5407_uart,
43 };
44 
45 /***************************************************************************/
46 
m5407_uart_init_line(int line,int irq)47 static void __init m5407_uart_init_line(int line, int irq)
48 {
49 	if (line == 0) {
50 		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
51 		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
52 		mcf_mapirq2imr(irq, MCFINTC_UART0);
53 	} else if (line == 1) {
54 		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
55 		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
56 		mcf_mapirq2imr(irq, MCFINTC_UART1);
57 	}
58 }
59 
m5407_uarts_init(void)60 static void __init m5407_uarts_init(void)
61 {
62 	const int nrlines = ARRAY_SIZE(m5407_uart_platform);
63 	int line;
64 
65 	for (line = 0; (line < nrlines); line++)
66 		m5407_uart_init_line(line, m5407_uart_platform[line].irq);
67 }
68 
69 /***************************************************************************/
70 
m5407_timers_init(void)71 static void __init m5407_timers_init(void)
72 {
73 	/* Timer1 is always used as system timer */
74 	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
75 		MCF_MBAR + MCFSIM_TIMER1ICR);
76 	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
77 
78 #ifdef CONFIG_HIGHPROFILE
79 	/* Timer2 is to be used as a high speed profile timer  */
80 	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
81 		MCF_MBAR + MCFSIM_TIMER2ICR);
82 	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
83 #endif
84 }
85 
86 /***************************************************************************/
87 
m5407_cpu_reset(void)88 void m5407_cpu_reset(void)
89 {
90 	local_irq_disable();
91 	/* set watchdog to soft reset, and enabled */
92 	__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
93 	for (;;)
94 		/* wait for watchdog to timeout */;
95 }
96 
97 /***************************************************************************/
98 
config_BSP(char * commandp,int size)99 void __init config_BSP(char *commandp, int size)
100 {
101 	mach_reset = m5407_cpu_reset;
102 	m5407_timers_init();
103 	m5407_uarts_init();
104 
105 	/* Only support the external interrupts on their primary level */
106 	mcf_mapirq2imr(25, MCFINTC_EINT1);
107 	mcf_mapirq2imr(27, MCFINTC_EINT3);
108 	mcf_mapirq2imr(29, MCFINTC_EINT5);
109 	mcf_mapirq2imr(31, MCFINTC_EINT7);
110 }
111 
112 /***************************************************************************/
113 
init_BSP(void)114 static int __init init_BSP(void)
115 {
116 	platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
117 	return 0;
118 }
119 
120 arch_initcall(init_BSP);
121 
122 /***************************************************************************/
123