blob: a575b38016a47a21a39728a6c3a6601cddb7f4c9 [file] [log] [blame]
Kuninori Morimoto4138b742009-08-19 12:08:33 +00001/*
2 * Copyright (C) 2009 Renesas Solutions Corp.
3 *
4 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/init.h>
12#include <linux/device.h>
13#include <linux/platform_device.h>
14#include <linux/mtd/physmap.h>
15#include <linux/gpio.h>
16#include <linux/interrupt.h>
Kuninori Morimoto35a35402009-08-26 11:04:26 +000017#include <linux/io.h>
18#include <linux/delay.h>
Kuninori Morimoto907050a2009-08-26 11:04:31 +000019#include <linux/usb/r8a66597.h>
Kuninori Morimotofa3ba512009-08-26 11:04:34 +000020#include <video/sh_mobile_lcdc.h>
Kuninori Morimoto4138b742009-08-19 12:08:33 +000021#include <asm/heartbeat.h>
Kuninori Morimoto35a35402009-08-26 11:04:26 +000022#include <asm/sh_eth.h>
Kuninori Morimoto4138b742009-08-19 12:08:33 +000023#include <cpu/sh7724.h>
24
25/*
Kuninori Morimotob7056bc2009-08-26 11:04:22 +000026 * Address Interface BusWidth
27 *-----------------------------------------
28 * 0x0000_0000 uboot 16bit
29 * 0x0004_0000 Linux romImage 16bit
30 * 0x0014_0000 MTD for Linux 16bit
31 * 0x0400_0000 Internal I/O 16/32bit
32 * 0x0800_0000 DRAM 32bit
33 * 0x1800_0000 MFI 16bit
Kuninori Morimoto4138b742009-08-19 12:08:33 +000034 */
35
36/* Heartbeat */
37static unsigned char led_pos[] = { 0, 1, 2, 3 };
38static struct heartbeat_data heartbeat_data = {
39 .regsize = 8,
40 .nr_bits = 4,
41 .bit_pos = led_pos,
42};
43
44static struct resource heartbeat_resources[] = {
45 [0] = {
46 .start = 0xA405012C, /* PTG */
47 .end = 0xA405012E - 1,
48 .flags = IORESOURCE_MEM,
49 },
50};
51
52static struct platform_device heartbeat_device = {
53 .name = "heartbeat",
54 .id = -1,
55 .dev = {
56 .platform_data = &heartbeat_data,
57 },
58 .num_resources = ARRAY_SIZE(heartbeat_resources),
59 .resource = heartbeat_resources,
60};
61
62/* MTD */
63static struct mtd_partition nor_flash_partitions[] = {
64 {
Kuninori Morimotob7056bc2009-08-26 11:04:22 +000065 .name = "boot loader",
Kuninori Morimoto4138b742009-08-19 12:08:33 +000066 .offset = 0,
Kuninori Morimotob7056bc2009-08-26 11:04:22 +000067 .size = (5 * 1024 * 1024),
Kuninori Morimoto4138b742009-08-19 12:08:33 +000068 .mask_flags = MTD_CAP_ROM,
69 }, {
Kuninori Morimoto4138b742009-08-19 12:08:33 +000070 .name = "free-area",
71 .offset = MTDPART_OFS_APPEND,
72 .size = MTDPART_SIZ_FULL,
73 },
74};
75
76static struct physmap_flash_data nor_flash_data = {
77 .width = 2,
78 .parts = nor_flash_partitions,
79 .nr_parts = ARRAY_SIZE(nor_flash_partitions),
80};
81
82static struct resource nor_flash_resources[] = {
83 [0] = {
84 .name = "NOR Flash",
85 .start = 0x00000000,
86 .end = 0x03ffffff,
87 .flags = IORESOURCE_MEM,
88 }
89};
90
91static struct platform_device nor_flash_device = {
92 .name = "physmap-flash",
93 .resource = nor_flash_resources,
94 .num_resources = ARRAY_SIZE(nor_flash_resources),
95 .dev = {
96 .platform_data = &nor_flash_data,
97 },
98};
99
Kuninori Morimoto35a35402009-08-26 11:04:26 +0000100/* SH Eth */
101#define SH_ETH_ADDR (0xA4600000)
102#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0)
103#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8)
104static struct resource sh_eth_resources[] = {
105 [0] = {
106 .start = SH_ETH_ADDR,
107 .end = SH_ETH_ADDR + 0x1FC,
108 .flags = IORESOURCE_MEM,
109 },
110 [1] = {
111 .start = 91,
112 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
113 },
114};
115
116struct sh_eth_plat_data sh_eth_plat = {
117 .phy = 0x1f, /* SMSC LAN8700 */
118 .edmac_endian = EDMAC_LITTLE_ENDIAN,
119};
120
121static struct platform_device sh_eth_device = {
122 .name = "sh-eth",
123 .id = 0,
124 .dev = {
125 .platform_data = &sh_eth_plat,
126 },
127 .num_resources = ARRAY_SIZE(sh_eth_resources),
128 .resource = sh_eth_resources,
129};
130
Kuninori Morimoto907050a2009-08-26 11:04:31 +0000131/* USB0 host */
132void usb0_port_power(int port, int power)
133{
134 gpio_set_value(GPIO_PTB4, power);
135}
136
137static struct r8a66597_platdata usb0_host_data = {
138 .on_chip = 1,
139 .port_power = usb0_port_power,
140};
141
142static struct resource usb0_host_resources[] = {
143 [0] = {
144 .start = 0xa4d80000,
145 .end = 0xa4d80124 - 1,
146 .flags = IORESOURCE_MEM,
147 },
148 [1] = {
149 .start = 65,
150 .end = 65,
151 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
152 },
153};
154
155static struct platform_device usb0_host_device = {
156 .name = "r8a66597_hcd",
157 .id = 0,
158 .dev = {
159 .dma_mask = NULL, /* not use dma */
160 .coherent_dma_mask = 0xffffffff,
161 .platform_data = &usb0_host_data,
162 },
163 .num_resources = ARRAY_SIZE(usb0_host_resources),
164 .resource = usb0_host_resources,
165};
166
167/*
168 * USB1
169 *
170 * CN5 can use both host/function,
171 * and we can determine it by checking PTB[3]
172 *
173 * This time only USB1 host is supported.
174 */
175void usb1_port_power(int port, int power)
176{
177 if (!gpio_get_value(GPIO_PTB3)) {
178 printk(KERN_ERR "USB1 function is not supported\n");
179 return;
180 }
181
182 gpio_set_value(GPIO_PTB5, power);
183}
184
185static struct r8a66597_platdata usb1_host_data = {
186 .on_chip = 1,
187 .port_power = usb1_port_power,
188};
189
190static struct resource usb1_host_resources[] = {
191 [0] = {
192 .start = 0xa4d90000,
193 .end = 0xa4d90124 - 1,
194 .flags = IORESOURCE_MEM,
195 },
196 [1] = {
197 .start = 66,
198 .end = 66,
199 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
200 },
201};
202
203static struct platform_device usb1_host_device = {
204 .name = "r8a66597_hcd",
205 .id = 1,
206 .dev = {
207 .dma_mask = NULL, /* not use dma */
208 .coherent_dma_mask = 0xffffffff,
209 .platform_data = &usb1_host_data,
210 },
211 .num_resources = ARRAY_SIZE(usb1_host_resources),
212 .resource = usb1_host_resources,
213};
214
Kuninori Morimotofa3ba512009-08-26 11:04:34 +0000215/* LCDC */
216static struct sh_mobile_lcdc_info lcdc_info = {
217 .ch[0] = {
218 .interface_type = RGB18,
219 .chan = LCDC_CHAN_MAINLCD,
220 .bpp = 16,
221 .clock_divider = 1,
222 .lcd_cfg = {
223 .sync = 0, /* hsync and vsync are active low */
224 },
225 .lcd_size_cfg = { /* 7.0 inch */
226 .width = 152,
227 .height = 91,
228 },
229 .board_cfg = {
230 },
231 }
232};
233
234static struct resource lcdc_resources[] = {
235 [0] = {
236 .name = "LCDC",
237 .start = 0xfe940000,
238 .end = 0xfe941fff,
239 .flags = IORESOURCE_MEM,
240 },
241 [1] = {
242 .start = 106,
243 .flags = IORESOURCE_IRQ,
244 },
245};
246
247static struct platform_device lcdc_device = {
248 .name = "sh_mobile_lcdc_fb",
249 .num_resources = ARRAY_SIZE(lcdc_resources),
250 .resource = lcdc_resources,
251 .dev = {
252 .platform_data = &lcdc_info,
253 },
254 .archdata = {
255 .hwblk_id = HWBLK_LCDC,
256 },
257};
258
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000259static struct platform_device *ecovec_devices[] __initdata = {
260 &heartbeat_device,
261 &nor_flash_device,
Kuninori Morimoto35a35402009-08-26 11:04:26 +0000262 &sh_eth_device,
Kuninori Morimoto907050a2009-08-26 11:04:31 +0000263 &usb0_host_device,
264 &usb1_host_device, /* USB1 host support */
Kuninori Morimotofa3ba512009-08-26 11:04:34 +0000265 &lcdc_device,
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000266};
267
Kuninori Morimotofa3ba512009-08-26 11:04:34 +0000268#define PORT_HIZA 0xA4050158
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000269static int __init devices_setup(void)
270{
271 /* enable SCIFA0 */
272 gpio_request(GPIO_FN_SCIF0_TXD, NULL);
273 gpio_request(GPIO_FN_SCIF0_RXD, NULL);
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000274
275 /* enable debug LED */
276 gpio_request(GPIO_PTG0, NULL);
277 gpio_request(GPIO_PTG1, NULL);
278 gpio_request(GPIO_PTG2, NULL);
279 gpio_request(GPIO_PTG3, NULL);
Kuninori Morimotob7056bc2009-08-26 11:04:22 +0000280 gpio_direction_output(GPIO_PTG0, 0);
281 gpio_direction_output(GPIO_PTG1, 0);
282 gpio_direction_output(GPIO_PTG2, 0);
283 gpio_direction_output(GPIO_PTG3, 0);
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000284
Kuninori Morimoto35a35402009-08-26 11:04:26 +0000285 /* enable SH-Eth */
286 gpio_request(GPIO_PTA1, NULL);
287 gpio_direction_output(GPIO_PTA1, 1);
288 mdelay(20);
289
290 gpio_request(GPIO_FN_RMII_RXD0, NULL);
291 gpio_request(GPIO_FN_RMII_RXD1, NULL);
292 gpio_request(GPIO_FN_RMII_TXD0, NULL);
293 gpio_request(GPIO_FN_RMII_TXD1, NULL);
294 gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
295 gpio_request(GPIO_FN_RMII_TX_EN, NULL);
296 gpio_request(GPIO_FN_RMII_RX_ER, NULL);
297 gpio_request(GPIO_FN_RMII_CRS_DV, NULL);
298 gpio_request(GPIO_FN_MDIO, NULL);
299 gpio_request(GPIO_FN_MDC, NULL);
300 gpio_request(GPIO_FN_LNKSTA, NULL);
301
Kuninori Morimoto907050a2009-08-26 11:04:31 +0000302 /* enable USB */
303 gpio_request(GPIO_PTB3, NULL);
304 gpio_request(GPIO_PTB4, NULL);
305 gpio_request(GPIO_PTB5, NULL);
306 gpio_direction_input(GPIO_PTB3);
307 gpio_direction_output(GPIO_PTB4, 0);
308 gpio_direction_output(GPIO_PTB5, 0);
309 ctrl_outw(0x0600, 0xa40501d4);
310 ctrl_outw(0x0600, 0xa4050192);
311
Kuninori Morimotofa3ba512009-08-26 11:04:34 +0000312 /* enable LCDC */
313 gpio_request(GPIO_FN_LCDD23, NULL);
314 gpio_request(GPIO_FN_LCDD22, NULL);
315 gpio_request(GPIO_FN_LCDD21, NULL);
316 gpio_request(GPIO_FN_LCDD20, NULL);
317 gpio_request(GPIO_FN_LCDD19, NULL);
318 gpio_request(GPIO_FN_LCDD18, NULL);
319 gpio_request(GPIO_FN_LCDD17, NULL);
320 gpio_request(GPIO_FN_LCDD16, NULL);
321 gpio_request(GPIO_FN_LCDD15, NULL);
322 gpio_request(GPIO_FN_LCDD14, NULL);
323 gpio_request(GPIO_FN_LCDD13, NULL);
324 gpio_request(GPIO_FN_LCDD12, NULL);
325 gpio_request(GPIO_FN_LCDD11, NULL);
326 gpio_request(GPIO_FN_LCDD10, NULL);
327 gpio_request(GPIO_FN_LCDD9, NULL);
328 gpio_request(GPIO_FN_LCDD8, NULL);
329 gpio_request(GPIO_FN_LCDD7, NULL);
330 gpio_request(GPIO_FN_LCDD6, NULL);
331 gpio_request(GPIO_FN_LCDD5, NULL);
332 gpio_request(GPIO_FN_LCDD4, NULL);
333 gpio_request(GPIO_FN_LCDD3, NULL);
334 gpio_request(GPIO_FN_LCDD2, NULL);
335 gpio_request(GPIO_FN_LCDD1, NULL);
336 gpio_request(GPIO_FN_LCDD0, NULL);
337 gpio_request(GPIO_FN_LCDDISP, NULL);
338 gpio_request(GPIO_FN_LCDHSYN, NULL);
339 gpio_request(GPIO_FN_LCDDCK, NULL);
340 gpio_request(GPIO_FN_LCDVSYN, NULL);
341 gpio_request(GPIO_FN_LCDDON, NULL);
342 gpio_request(GPIO_FN_LCDLCLK, NULL);
343 ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
344
345 gpio_request(GPIO_PTE6, NULL);
346 gpio_request(GPIO_PTU1, NULL);
347 gpio_request(GPIO_PTR1, NULL);
348 gpio_request(GPIO_PTA2, NULL);
349 gpio_direction_input(GPIO_PTE6);
350 gpio_direction_output(GPIO_PTU1, 0);
351 gpio_direction_output(GPIO_PTR1, 0);
352 gpio_direction_output(GPIO_PTA2, 0);
353
354 if (gpio_get_value(GPIO_PTE6)) {
355 /* DVI */
356 lcdc_info.clock_source = LCDC_CLK_EXTERNAL;
357 lcdc_info.ch[0].lcd_cfg.name = "DVI";
358 lcdc_info.ch[0].lcd_cfg.xres = 1280;
359 lcdc_info.ch[0].lcd_cfg.yres = 720;
360 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
361 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
362 lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
363 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
364 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
365 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
366
367 gpio_set_value(GPIO_PTA2, 1);
368 gpio_set_value(GPIO_PTU1, 1);
369 } else {
370 /* Panel */
371 /* not supported */
372 }
373
Kuninori Morimoto4138b742009-08-19 12:08:33 +0000374 return platform_add_devices(ecovec_devices,
375 ARRAY_SIZE(ecovec_devices));
376}
377device_initcall(devices_setup);
378
379static struct sh_machine_vector mv_ecovec __initmv = {
380 .mv_name = "R0P7724 (EcoVec)",
381};