Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
setup-sh4-202.c
Go to the documentation of this file.
1 /*
2  * SH4-202 Setup
3  *
4  * Copyright (C) 2006 Paul Mundt
5  * Copyright (C) 2009 Magnus Damm
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License. See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11 #include <linux/platform_device.h>
12 #include <linux/init.h>
13 #include <linux/serial.h>
14 #include <linux/serial_sci.h>
15 #include <linux/sh_timer.h>
16 #include <linux/sh_intc.h>
17 #include <linux/io.h>
18 
19 static struct plat_sci_port scif0_platform_data = {
20  .mapbase = 0xffe80000,
21  .flags = UPF_BOOT_AUTOCONF,
22  .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
23  .scbrr_algo_id = SCBRR_ALGO_2,
24  .type = PORT_SCIF,
25  .irqs = { evt2irq(0x700),
26  evt2irq(0x720),
27  evt2irq(0x760),
28  evt2irq(0x740) },
29 };
30 
31 static struct platform_device scif0_device = {
32  .name = "sh-sci",
33  .id = 0,
34  .dev = {
35  .platform_data = &scif0_platform_data,
36  },
37 };
38 
39 static struct sh_timer_config tmu0_platform_data = {
40  .channel_offset = 0x04,
41  .timer_bit = 0,
42  .clockevent_rating = 200,
43 };
44 
45 static struct resource tmu0_resources[] = {
46  [0] = {
47  .start = 0xffd80008,
48  .end = 0xffd80013,
49  .flags = IORESOURCE_MEM,
50  },
51  [1] = {
52  .start = evt2irq(0x400),
53  .flags = IORESOURCE_IRQ,
54  },
55 };
56 
57 static struct platform_device tmu0_device = {
58  .name = "sh_tmu",
59  .id = 0,
60  .dev = {
61  .platform_data = &tmu0_platform_data,
62  },
63  .resource = tmu0_resources,
64  .num_resources = ARRAY_SIZE(tmu0_resources),
65 };
66 
67 static struct sh_timer_config tmu1_platform_data = {
68  .channel_offset = 0x10,
69  .timer_bit = 1,
70  .clocksource_rating = 200,
71 };
72 
73 static struct resource tmu1_resources[] = {
74  [0] = {
75  .start = 0xffd80014,
76  .end = 0xffd8001f,
77  .flags = IORESOURCE_MEM,
78  },
79  [1] = {
80  .start = evt2irq(0x420),
81  .flags = IORESOURCE_IRQ,
82  },
83 };
84 
85 static struct platform_device tmu1_device = {
86  .name = "sh_tmu",
87  .id = 1,
88  .dev = {
89  .platform_data = &tmu1_platform_data,
90  },
91  .resource = tmu1_resources,
92  .num_resources = ARRAY_SIZE(tmu1_resources),
93 };
94 
95 static struct sh_timer_config tmu2_platform_data = {
96  .channel_offset = 0x1c,
97  .timer_bit = 2,
98 };
99 
100 static struct resource tmu2_resources[] = {
101  [0] = {
102  .start = 0xffd80020,
103  .end = 0xffd8002f,
104  .flags = IORESOURCE_MEM,
105  },
106  [1] = {
107  .start = evt2irq(0x440),
108  .flags = IORESOURCE_IRQ,
109  },
110 };
111 
112 static struct platform_device tmu2_device = {
113  .name = "sh_tmu",
114  .id = 2,
115  .dev = {
116  .platform_data = &tmu2_platform_data,
117  },
118  .resource = tmu2_resources,
119  .num_resources = ARRAY_SIZE(tmu2_resources),
120 };
121 
122 static struct platform_device *sh4202_devices[] __initdata = {
123  &scif0_device,
124  &tmu0_device,
125  &tmu1_device,
126  &tmu2_device,
127 };
128 
129 static int __init sh4202_devices_setup(void)
130 {
131  return platform_add_devices(sh4202_devices,
132  ARRAY_SIZE(sh4202_devices));
133 }
134 arch_initcall(sh4202_devices_setup);
135 
136 static struct platform_device *sh4202_early_devices[] __initdata = {
137  &scif0_device,
138  &tmu0_device,
139  &tmu1_device,
140  &tmu2_device,
141 };
142 
144 {
145  early_platform_add_devices(sh4202_early_devices,
146  ARRAY_SIZE(sh4202_early_devices));
147 }
148 
149 enum {
150  UNUSED = 0,
151 
152  /* interrupt sources */
153  IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
155 };
156 
157 static struct intc_vect vectors[] __initdata = {
158  INTC_VECT(HUDI, 0x600),
159  INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
160  INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
161  INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
162  INTC_VECT(RTC, 0x4c0),
163  INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720),
164  INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760),
165  INTC_VECT(WDT, 0x560),
166 };
167 
168 static struct intc_prio_reg prio_registers[] __initdata = {
169  { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
170  { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, 0, 0, 0 } },
171  { 0xffd0000c, 0, 16, 4, /* IPRC */ { 0, 0, SCIF, HUDI } },
172  { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
173 };
174 
175 static DECLARE_INTC_DESC(intc_desc, "sh4-202", vectors, NULL,
176  NULL, prio_registers, NULL);
177 
178 static struct intc_vect vectors_irlm[] __initdata = {
179  INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
180  INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
181 };
182 
183 static DECLARE_INTC_DESC(intc_desc_irlm, "sh4-202_irlm", vectors_irlm, NULL,
184  NULL, prio_registers, NULL);
185 
187 {
189 }
190 
191 #define INTC_ICR 0xffd00000UL
192 #define INTC_ICR_IRLM (1<<7)
193 
195 {
196  switch (mode) {
197  case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
199  register_intc_controller(&intc_desc_irlm);
200  break;
201  default:
202  BUG();
203  }
204 }