Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
platform.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2010, Lars-Peter Clausen <[email protected]>
3  * JZ4740 platform devices
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * You should have received a copy of the GNU General Public License along
11  * with this program; if not, write to the Free Software Foundation, Inc.,
12  * 675 Mass Ave, Cambridge, MA 02139, USA.
13  *
14  */
15 
16 #include <linux/device.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/platform_device.h>
20 #include <linux/resource.h>
21 
22 #include <linux/dma-mapping.h>
23 
25 #include <asm/mach-jz4740/base.h>
26 #include <asm/mach-jz4740/irq.h>
27 
28 #include <linux/serial_core.h>
29 #include <linux/serial_8250.h>
30 
31 #include "serial.h"
32 #include "clock.h"
33 
34 /* OHCI controller */
35 static struct resource jz4740_usb_ohci_resources[] = {
36  {
37  .start = JZ4740_UHC_BASE_ADDR,
38  .end = JZ4740_UHC_BASE_ADDR + 0x1000 - 1,
39  .flags = IORESOURCE_MEM,
40  },
41  {
42  .start = JZ4740_IRQ_UHC,
43  .end = JZ4740_IRQ_UHC,
44  .flags = IORESOURCE_IRQ,
45  },
46 };
47 
49  .name = "jz4740-ohci",
50  .id = -1,
51  .dev = {
52  .dma_mask = &jz4740_usb_ohci_device.dev.coherent_dma_mask,
53  .coherent_dma_mask = DMA_BIT_MASK(32),
54  },
55  .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources),
56  .resource = jz4740_usb_ohci_resources,
57 };
58 
59 /* UDC (USB gadget controller) */
60 static struct resource jz4740_usb_gdt_resources[] = {
61  {
62  .start = JZ4740_UDC_BASE_ADDR,
63  .end = JZ4740_UDC_BASE_ADDR + 0x1000 - 1,
64  .flags = IORESOURCE_MEM,
65  },
66  {
67  .start = JZ4740_IRQ_UDC,
68  .end = JZ4740_IRQ_UDC,
69  .flags = IORESOURCE_IRQ,
70  },
71 };
72 
74  .name = "jz-udc",
75  .id = -1,
76  .dev = {
77  .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask,
78  .coherent_dma_mask = DMA_BIT_MASK(32),
79  },
80  .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources),
81  .resource = jz4740_usb_gdt_resources,
82 };
83 
84 /* MMC/SD controller */
85 static struct resource jz4740_mmc_resources[] = {
86  {
87  .start = JZ4740_MSC_BASE_ADDR,
88  .end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1,
89  .flags = IORESOURCE_MEM,
90  },
91  {
92  .start = JZ4740_IRQ_MSC,
93  .end = JZ4740_IRQ_MSC,
94  .flags = IORESOURCE_IRQ,
95  }
96 };
97 
99  .name = "jz4740-mmc",
100  .id = 0,
101  .dev = {
102  .dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask,
103  .coherent_dma_mask = DMA_BIT_MASK(32),
104  },
105  .num_resources = ARRAY_SIZE(jz4740_mmc_resources),
106  .resource = jz4740_mmc_resources,
107 };
108 
109 /* RTC controller */
110 static struct resource jz4740_rtc_resources[] = {
111  {
112  .start = JZ4740_RTC_BASE_ADDR,
113  .end = JZ4740_RTC_BASE_ADDR + 0x38 - 1,
114  .flags = IORESOURCE_MEM,
115  },
116  {
117  .start = JZ4740_IRQ_RTC,
118  .end = JZ4740_IRQ_RTC,
119  .flags = IORESOURCE_IRQ,
120  },
121 };
122 
124  .name = "jz4740-rtc",
125  .id = -1,
126  .num_resources = ARRAY_SIZE(jz4740_rtc_resources),
127  .resource = jz4740_rtc_resources,
128 };
129 
130 /* I2C controller */
131 static struct resource jz4740_i2c_resources[] = {
132  {
133  .start = JZ4740_I2C_BASE_ADDR,
134  .end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1,
135  .flags = IORESOURCE_MEM,
136  },
137  {
138  .start = JZ4740_IRQ_I2C,
139  .end = JZ4740_IRQ_I2C,
140  .flags = IORESOURCE_IRQ,
141  }
142 };
143 
145  .name = "jz4740-i2c",
146  .id = 0,
147  .num_resources = ARRAY_SIZE(jz4740_i2c_resources),
148  .resource = jz4740_i2c_resources,
149 };
150 
151 /* NAND controller */
152 static struct resource jz4740_nand_resources[] = {
153  {
154  .name = "mmio",
155  .start = JZ4740_EMC_BASE_ADDR,
156  .end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1,
157  .flags = IORESOURCE_MEM,
158  },
159  {
160  .name = "bank1",
161  .start = 0x18000000,
162  .end = 0x180C0000 - 1,
163  .flags = IORESOURCE_MEM,
164  },
165  {
166  .name = "bank2",
167  .start = 0x14000000,
168  .end = 0x140C0000 - 1,
169  .flags = IORESOURCE_MEM,
170  },
171  {
172  .name = "bank3",
173  .start = 0x0C000000,
174  .end = 0x0C0C0000 - 1,
175  .flags = IORESOURCE_MEM,
176  },
177  {
178  .name = "bank4",
179  .start = 0x08000000,
180  .end = 0x080C0000 - 1,
181  .flags = IORESOURCE_MEM,
182  },
183 };
184 
186  .name = "jz4740-nand",
187  .num_resources = ARRAY_SIZE(jz4740_nand_resources),
188  .resource = jz4740_nand_resources,
189 };
190 
191 /* LCD controller */
192 static struct resource jz4740_framebuffer_resources[] = {
193  {
194  .start = JZ4740_LCD_BASE_ADDR,
195  .end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1,
196  .flags = IORESOURCE_MEM,
197  },
198 };
199 
201  .name = "jz4740-fb",
202  .id = -1,
203  .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
204  .resource = jz4740_framebuffer_resources,
205  .dev = {
206  .dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask,
207  .coherent_dma_mask = DMA_BIT_MASK(32),
208  },
209 };
210 
211 /* I2S controller */
212 static struct resource jz4740_i2s_resources[] = {
213  {
214  .start = JZ4740_AIC_BASE_ADDR,
215  .end = JZ4740_AIC_BASE_ADDR + 0x38 - 1,
216  .flags = IORESOURCE_MEM,
217  },
218 };
219 
221  .name = "jz4740-i2s",
222  .id = -1,
223  .num_resources = ARRAY_SIZE(jz4740_i2s_resources),
224  .resource = jz4740_i2s_resources,
225 };
226 
227 /* PCM */
229  .name = "jz4740-pcm-audio",
230  .id = -1,
231 };
232 
233 /* Codec */
234 static struct resource jz4740_codec_resources[] = {
235  {
236  .start = JZ4740_AIC_BASE_ADDR + 0x80,
237  .end = JZ4740_AIC_BASE_ADDR + 0x88 - 1,
238  .flags = IORESOURCE_MEM,
239  },
240 };
241 
243  .name = "jz4740-codec",
244  .id = -1,
245  .num_resources = ARRAY_SIZE(jz4740_codec_resources),
246  .resource = jz4740_codec_resources,
247 };
248 
249 /* ADC controller */
250 static struct resource jz4740_adc_resources[] = {
251  {
252  .start = JZ4740_SADC_BASE_ADDR,
253  .end = JZ4740_SADC_BASE_ADDR + 0x30,
254  .flags = IORESOURCE_MEM,
255  },
256  {
257  .start = JZ4740_IRQ_SADC,
258  .end = JZ4740_IRQ_SADC,
259  .flags = IORESOURCE_IRQ,
260  },
261  {
262  .start = JZ4740_IRQ_ADC_BASE,
263  .end = JZ4740_IRQ_ADC_BASE,
264  .flags = IORESOURCE_IRQ,
265  },
266 };
267 
269  .name = "jz4740-adc",
270  .id = -1,
271  .num_resources = ARRAY_SIZE(jz4740_adc_resources),
272  .resource = jz4740_adc_resources,
273 };
274 
275 /* Serial */
276 #define JZ4740_UART_DATA(_id) \
277  { \
278  .flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
279  .iotype = UPIO_MEM, \
280  .regshift = 2, \
281  .serial_out = jz4740_serial_out, \
282  .type = PORT_16550, \
283  .mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
284  .irq = JZ4740_IRQ_UART ## _id, \
285  }
286 
287 static struct plat_serial8250_port jz4740_uart_data[] = {
288  JZ4740_UART_DATA(0),
289  JZ4740_UART_DATA(1),
290  {},
291 };
292 
293 static struct platform_device jz4740_uart_device = {
294  .name = "serial8250",
295  .id = 0,
296  .dev = {
297  .platform_data = jz4740_uart_data,
298  },
299 };
300 
302 {
303  struct plat_serial8250_port *p;
304 
305  for (p = jz4740_uart_data; p->flags != 0; ++p)
306  p->uartclk = jz4740_clock_bdata.ext_rate;
307 
308  platform_device_register(&jz4740_uart_device);
309 }
310 
311 /* Watchdog */
312 static struct resource jz4740_wdt_resources[] = {
313  {
314  .start = JZ4740_WDT_BASE_ADDR,
315  .end = JZ4740_WDT_BASE_ADDR + 0x10 - 1,
316  .flags = IORESOURCE_MEM,
317  },
318 };
319 
321  .name = "jz4740-wdt",
322  .id = -1,
323  .num_resources = ARRAY_SIZE(jz4740_wdt_resources),
324  .resource = jz4740_wdt_resources,
325 };
326 
327 /* PWM */
329  .name = "jz4740-pwm",
330  .id = -1,
331 };