blob: 1d25d5fee605273fc80fdff7af0e530006ec9c50 [file] [log] [blame]
Kuninori Morimoto4d22e562012-04-06 01:28:59 -07001/*
2 * armadillo 800 eva board support
3 *
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
Kuninori Morimoto1c962932012-04-24 02:09:08 -070023#include <linux/delay.h>
Kuninori Morimoto4d22e562012-04-06 01:28:59 -070024#include <linux/err.h>
25#include <linux/kernel.h>
Kuninori Morimotof7e7d312012-04-06 01:31:33 -070026#include <linux/input.h>
Kuninori Morimoto1c962932012-04-24 02:09:08 -070027#include <linux/irq.h>
Kuninori Morimoto4d22e562012-04-06 01:28:59 -070028#include <linux/platform_device.h>
29#include <linux/gpio.h>
Kuninori Morimotof7e7d312012-04-06 01:31:33 -070030#include <linux/gpio_keys.h>
Kuninori Morimotod8fed1e2012-04-06 01:32:02 -070031#include <linux/sh_eth.h>
Kuninori Morimotodad29d12012-04-06 01:30:09 -070032#include <linux/videodev2.h>
Kuninori Morimoto1c962932012-04-24 02:09:08 -070033#include <linux/usb/renesas_usbhs.h>
Kuninori Morimoto4d22e562012-04-06 01:28:59 -070034#include <mach/common.h>
35#include <mach/irqs.h>
36#include <asm/page.h>
37#include <asm/mach-types.h>
38#include <asm/mach/arch.h>
39#include <asm/mach/map.h>
40#include <asm/mach/time.h>
41#include <asm/hardware/cache-l2x0.h>
42#include <mach/r8a7740.h>
Kuninori Morimotodad29d12012-04-06 01:30:09 -070043#include <video/sh_mobile_lcdc.h>
Kuninori Morimoto4d22e562012-04-06 01:28:59 -070044
45/*
46 * CON1 Camera Module
47 * CON2 Extension Bus
48 * CON3 HDMI Output
49 * CON4 Composite Video Output
50 * CON5 H-UDI JTAG
51 * CON6 ARM JTAG
52 * CON7 SD1
53 * CON8 SD2
54 * CON9 RTC BackUp
55 * CON10 Monaural Mic Input
56 * CON11 Stereo Headphone Output
57 * CON12 Audio Line Output(L)
58 * CON13 Audio Line Output(R)
59 * CON14 AWL13 Module
60 * CON15 Extension
61 * CON16 LCD1
62 * CON17 LCD2
63 * CON19 Power Input
64 * CON20 USB1
65 * CON21 USB2
66 * CON22 Serial
67 * CON23 LAN
68 * CON24 USB3
69 * LED1 Camera LED(Yellow)
70 * LED2 Power LED (Green)
71 * ED3-LED6 User LED(Yellow)
72 * LED7 LAN link LED(Green)
73 * LED8 LAN activity LED(Yellow)
74 */
75
76/*
77 * DipSwitch
78 *
79 * SW1
80 *
81 * -12345678-+---------------+----------------------------
82 * 1 | boot | hermit
83 * 0 | boot | OS auto boot
84 * -12345678-+---------------+----------------------------
85 * 00 | boot device | eMMC
86 * 10 | boot device | SDHI0 (CON7)
87 * 01 | boot device | -
88 * 11 | boot device | Extension Buss (CS0)
89 * -12345678-+---------------+----------------------------
90 * 0 | Extension Bus | D8-D15 disable, eMMC enable
91 * 1 | Extension Bus | D8-D15 enable, eMMC disable
92 * -12345678-+---------------+----------------------------
93 * 0 | SDHI1 | COM8 enable, COM14 disable
94 * 1 | SDHI1 | COM8 enable, COM14 disable
95 * -12345678-+---------------+----------------------------
Kuninori Morimoto1c962932012-04-24 02:09:08 -070096 * 0 | USB0 | COM20 enable, COM24 disable
97 * 1 | USB0 | COM20 disable, COM24 enable
98 * -12345678-+---------------+----------------------------
Kuninori Morimoto4d22e562012-04-06 01:28:59 -070099 * 00 | JTAG | SH-X2
100 * 10 | JTAG | ARM
101 * 01 | JTAG | -
102 * 11 | JTAG | Boundary Scan
103 *-----------+---------------+----------------------------
104 */
105
Kuninori Morimoto1c962932012-04-24 02:09:08 -0700106/*
107 * USB function
108 *
109 * When you use USB Function,
110 * set SW1.6 ON, and connect cable to CN24.
111 *
112 * USBF needs workaround on R8A7740 chip.
113 * These are a little bit complex.
114 * see
115 * usbhsf_power_ctrl()
116 *
117 * CAUTION
118 *
119 * It uses autonomy mode for USB hotplug at this point
120 * (= usbhs_private.platform_callback.get_vbus is NULL),
121 * since we don't know what's happen on PM control
122 * on this workaround.
123 */
124#define USBCR1 0xe605810a
125#define USBH 0xC6700000
126#define USBH_USBCTR 0x10834
127
128struct usbhsf_private {
129 struct clk *phy;
130 struct clk *usb24;
131 struct clk *pci;
132 struct clk *func;
133 struct clk *host;
134 void __iomem *usbh_base;
135 struct renesas_usbhs_platform_info info;
136};
137
138#define usbhsf_get_priv(pdev) \
139 container_of(renesas_usbhs_get_info(pdev), \
140 struct usbhsf_private, info)
141
142static int usbhsf_get_id(struct platform_device *pdev)
143{
144 return USBHS_GADGET;
145}
146
147static void usbhsf_power_ctrl(struct platform_device *pdev,
148 void __iomem *base, int enable)
149{
150 struct usbhsf_private *priv = usbhsf_get_priv(pdev);
151
152 /*
153 * Work around for USB Function.
154 * It needs USB host clock, and settings
155 */
156 if (enable) {
157 /*
158 * enable all the related usb clocks
159 * for usb workaround
160 */
161 clk_enable(priv->usb24);
162 clk_enable(priv->pci);
163 clk_enable(priv->host);
164 clk_enable(priv->func);
165 clk_enable(priv->phy);
166
167 /*
168 * set USBCR1
169 *
170 * Port1 is driven by USB function,
171 * Port2 is driven by USB HOST
172 * One HOST (Port1 or Port2 is HOST)
173 * USB PLL input clock = 24MHz
174 */
175 __raw_writew(0xd750, USBCR1);
176 mdelay(1);
177
178 /*
179 * start USB Host
180 */
181 __raw_writel(0x0000000c, priv->usbh_base + USBH_USBCTR);
182 __raw_writel(0x00000008, priv->usbh_base + USBH_USBCTR);
183 mdelay(10);
184
185 /*
186 * USB PHY Power ON
187 */
188 __raw_writew(0xd770, USBCR1);
189 __raw_writew(0x4000, base + 0x102); /* USBF :: SUSPMODE */
190
191 } else {
192 __raw_writel(0x0000010f, priv->usbh_base + USBH_USBCTR);
193 __raw_writew(0xd7c0, USBCR1); /* GPIO */
194
195 clk_disable(priv->phy);
196 clk_disable(priv->func); /* usb work around */
197 clk_disable(priv->host); /* usb work around */
198 clk_disable(priv->pci); /* usb work around */
199 clk_disable(priv->usb24); /* usb work around */
200 }
201}
202
203static void usbhsf_hardware_exit(struct platform_device *pdev)
204{
205 struct usbhsf_private *priv = usbhsf_get_priv(pdev);
206
207 if (!IS_ERR(priv->phy))
208 clk_put(priv->phy);
209 if (!IS_ERR(priv->usb24))
210 clk_put(priv->usb24);
211 if (!IS_ERR(priv->pci))
212 clk_put(priv->pci);
213 if (!IS_ERR(priv->host))
214 clk_put(priv->host);
215 if (!IS_ERR(priv->func))
216 clk_put(priv->func);
217 if (priv->usbh_base)
218 iounmap(priv->usbh_base);
219
220 priv->phy = NULL;
221 priv->usb24 = NULL;
222 priv->pci = NULL;
223 priv->host = NULL;
224 priv->func = NULL;
225 priv->usbh_base = NULL;
226}
227
228static int usbhsf_hardware_init(struct platform_device *pdev)
229{
230 struct usbhsf_private *priv = usbhsf_get_priv(pdev);
231
232 priv->phy = clk_get(&pdev->dev, "phy");
233 priv->usb24 = clk_get(&pdev->dev, "usb24");
234 priv->pci = clk_get(&pdev->dev, "pci");
235 priv->func = clk_get(&pdev->dev, "func");
236 priv->host = clk_get(&pdev->dev, "host");
237 priv->usbh_base = ioremap_nocache(USBH, 0x20000);
238
239 if (IS_ERR(priv->phy) ||
240 IS_ERR(priv->usb24) ||
241 IS_ERR(priv->pci) ||
242 IS_ERR(priv->host) ||
243 IS_ERR(priv->func) ||
244 !priv->usbh_base) {
245 dev_err(&pdev->dev, "USB clock setting failed\n");
246 usbhsf_hardware_exit(pdev);
247 return -EIO;
248 }
249
250 /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
251 clk_set_rate(priv->usb24,
252 clk_get_rate(clk_get_parent(priv->usb24)));
253
254 return 0;
255}
256
257static struct usbhsf_private usbhsf_private = {
258 .info = {
259 .platform_callback = {
260 .get_id = usbhsf_get_id,
261 .hardware_init = usbhsf_hardware_init,
262 .hardware_exit = usbhsf_hardware_exit,
263 .power_ctrl = usbhsf_power_ctrl,
264 },
265 .driver_param = {
266 .buswait_bwait = 5,
267 .detection_delay = 5,
268 },
269 }
270};
271
272static struct resource usbhsf_resources[] = {
273 {
274 .name = "USBHS",
275 .start = 0xe6890000,
276 .end = 0xe6890104 - 1,
277 .flags = IORESOURCE_MEM,
278 },
279 {
280 .start = evt2irq(0x0A20),
281 .flags = IORESOURCE_IRQ,
282 },
283};
284
285static struct platform_device usbhsf_device = {
286 .name = "renesas_usbhs",
287 .dev = {
288 .platform_data = &usbhsf_private.info,
289 },
290 .id = -1,
291 .num_resources = ARRAY_SIZE(usbhsf_resources),
292 .resource = usbhsf_resources,
293};
294
Kuninori Morimotod8fed1e2012-04-06 01:32:02 -0700295/* Ether */
296static struct sh_eth_plat_data sh_eth_platdata = {
297 .phy = 0x00, /* LAN8710A */
298 .edmac_endian = EDMAC_LITTLE_ENDIAN,
299 .register_type = SH_ETH_REG_GIGABIT,
300 .phy_interface = PHY_INTERFACE_MODE_MII,
301};
302
303static struct resource sh_eth_resources[] = {
304 {
305 .start = 0xe9a00000,
306 .end = 0xe9a00800 - 1,
307 .flags = IORESOURCE_MEM,
308 }, {
309 .start = 0xe9a01800,
310 .end = 0xe9a02000 - 1,
311 .flags = IORESOURCE_MEM,
312 }, {
313 .start = evt2irq(0x0500),
314 .flags = IORESOURCE_IRQ,
315 },
316};
317
318static struct platform_device sh_eth_device = {
319 .name = "sh-eth",
320 .dev = {
321 .platform_data = &sh_eth_platdata,
322 },
323 .resource = sh_eth_resources,
324 .num_resources = ARRAY_SIZE(sh_eth_resources),
325};
326
Kuninori Morimotodad29d12012-04-06 01:30:09 -0700327/* LCDC */
328static struct fb_videomode lcdc0_mode = {
329 .name = "AMPIER/AM-800480",
330 .xres = 800,
331 .yres = 480,
332 .left_margin = 88,
333 .right_margin = 40,
334 .hsync_len = 128,
335 .upper_margin = 20,
336 .lower_margin = 5,
337 .vsync_len = 5,
338 .sync = 0,
339};
340
341static struct sh_mobile_lcdc_info lcdc0_info = {
342 .clock_source = LCDC_CLK_BUS,
343 .ch[0] = {
344 .chan = LCDC_CHAN_MAINLCD,
345 .fourcc = V4L2_PIX_FMT_RGB565,
346 .interface_type = RGB24,
347 .clock_divider = 5,
348 .flags = 0,
349 .lcd_modes = &lcdc0_mode,
350 .num_modes = 1,
351 .panel_cfg = {
352 .width = 111,
353 .height = 68,
354 },
355 },
356};
357
358static struct resource lcdc0_resources[] = {
359 [0] = {
360 .name = "LCD0",
361 .start = 0xfe940000,
362 .end = 0xfe943fff,
363 .flags = IORESOURCE_MEM,
364 },
365 [1] = {
366 .start = intcs_evt2irq(0x580),
367 .flags = IORESOURCE_IRQ,
368 },
369};
370
371static struct platform_device lcdc0_device = {
372 .name = "sh_mobile_lcdc_fb",
373 .num_resources = ARRAY_SIZE(lcdc0_resources),
374 .resource = lcdc0_resources,
375 .id = 0,
376 .dev = {
377 .platform_data = &lcdc0_info,
378 .coherent_dma_mask = ~0,
379 },
380};
381
Kuninori Morimotof7e7d312012-04-06 01:31:33 -0700382/* GPIO KEY */
383#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
384
385static struct gpio_keys_button gpio_buttons[] = {
386 GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW1"),
387 GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW2"),
388 GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW3"),
389 GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW4"),
390};
391
392static struct gpio_keys_platform_data gpio_key_info = {
393 .buttons = gpio_buttons,
394 .nbuttons = ARRAY_SIZE(gpio_buttons),
395};
396
397static struct platform_device gpio_keys_device = {
398 .name = "gpio-keys",
399 .id = -1,
400 .dev = {
401 .platform_data = &gpio_key_info,
402 },
403};
404
Kuninori Morimoto46cf6682012-04-06 01:30:42 -0700405/* I2C */
406static struct i2c_board_info i2c0_devices[] = {
407 {
408 I2C_BOARD_INFO("st1232-ts", 0x55),
409 .irq = evt2irq(0x0340),
410 },
411};
412
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700413/*
414 * board devices
415 */
416static struct platform_device *eva_devices[] __initdata = {
Kuninori Morimotodad29d12012-04-06 01:30:09 -0700417 &lcdc0_device,
Kuninori Morimotof7e7d312012-04-06 01:31:33 -0700418 &gpio_keys_device,
Kuninori Morimotod8fed1e2012-04-06 01:32:02 -0700419 &sh_eth_device,
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700420};
421
Kuninori Morimoto1c962932012-04-24 02:09:08 -0700422static void __init eva_clock_init(void)
423{
424 struct clk *system = clk_get(NULL, "system_clk");
425 struct clk *xtal1 = clk_get(NULL, "extal1");
426 struct clk *usb24s = clk_get(NULL, "usb24s");
427
428 if (IS_ERR(system) ||
429 IS_ERR(xtal1) ||
430 IS_ERR(usb24s)) {
431 pr_err("armadillo800eva board clock init failed\n");
432 goto clock_error;
433 }
434
435 /* armadillo 800 eva extal1 is 24MHz */
436 clk_set_rate(xtal1, 24000000);
437
438 /* usb24s use extal1 (= system) clock (= 24MHz) */
439 clk_set_parent(usb24s, system);
440
441clock_error:
442 if (!IS_ERR(system))
443 clk_put(system);
444 if (!IS_ERR(xtal1))
445 clk_put(xtal1);
446 if (!IS_ERR(usb24s))
447 clk_put(usb24s);
448}
449
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700450/*
451 * board init
452 */
453static void __init eva_init(void)
454{
Kuninori Morimoto1c962932012-04-24 02:09:08 -0700455 eva_clock_init();
456
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700457 r8a7740_pinmux_init();
458
459 /* SCIFA1 */
460 gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
461 gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
462
Kuninori Morimotodad29d12012-04-06 01:30:09 -0700463 /* LCDC0 */
464 gpio_request(GPIO_FN_LCDC0_SELECT, NULL);
465 gpio_request(GPIO_FN_LCD0_D0, NULL);
466 gpio_request(GPIO_FN_LCD0_D1, NULL);
467 gpio_request(GPIO_FN_LCD0_D2, NULL);
468 gpio_request(GPIO_FN_LCD0_D3, NULL);
469 gpio_request(GPIO_FN_LCD0_D4, NULL);
470 gpio_request(GPIO_FN_LCD0_D5, NULL);
471 gpio_request(GPIO_FN_LCD0_D6, NULL);
472 gpio_request(GPIO_FN_LCD0_D7, NULL);
473 gpio_request(GPIO_FN_LCD0_D8, NULL);
474 gpio_request(GPIO_FN_LCD0_D9, NULL);
475 gpio_request(GPIO_FN_LCD0_D10, NULL);
476 gpio_request(GPIO_FN_LCD0_D11, NULL);
477 gpio_request(GPIO_FN_LCD0_D12, NULL);
478 gpio_request(GPIO_FN_LCD0_D13, NULL);
479 gpio_request(GPIO_FN_LCD0_D14, NULL);
480 gpio_request(GPIO_FN_LCD0_D15, NULL);
481 gpio_request(GPIO_FN_LCD0_D16, NULL);
482 gpio_request(GPIO_FN_LCD0_D17, NULL);
483 gpio_request(GPIO_FN_LCD0_D18_PORT40, NULL);
484 gpio_request(GPIO_FN_LCD0_D19_PORT4, NULL);
485 gpio_request(GPIO_FN_LCD0_D20_PORT3, NULL);
486 gpio_request(GPIO_FN_LCD0_D21_PORT2, NULL);
487 gpio_request(GPIO_FN_LCD0_D22_PORT0, NULL);
488 gpio_request(GPIO_FN_LCD0_D23_PORT1, NULL);
489 gpio_request(GPIO_FN_LCD0_DCK, NULL);
490 gpio_request(GPIO_FN_LCD0_VSYN, NULL);
491 gpio_request(GPIO_FN_LCD0_HSYN, NULL);
492 gpio_request(GPIO_FN_LCD0_DISP, NULL);
493 gpio_request(GPIO_FN_LCD0_LCLK_PORT165, NULL);
494
495 gpio_request(GPIO_PORT61, NULL); /* LCDDON */
496 gpio_direction_output(GPIO_PORT61, 1);
497
498 gpio_request(GPIO_PORT202, NULL); /* LCD0_LED_CONT */
499 gpio_direction_output(GPIO_PORT202, 0);
500
Kuninori Morimoto46cf6682012-04-06 01:30:42 -0700501 /* Touchscreen */
502 gpio_request(GPIO_FN_IRQ10, NULL); /* TP_INT */
503 gpio_request(GPIO_PORT166, NULL); /* TP_RST_B */
504 gpio_direction_output(GPIO_PORT166, 1);
505
Kuninori Morimotod8fed1e2012-04-06 01:32:02 -0700506 /* GETHER */
507 gpio_request(GPIO_FN_ET_CRS, NULL);
508 gpio_request(GPIO_FN_ET_MDC, NULL);
509 gpio_request(GPIO_FN_ET_MDIO, NULL);
510 gpio_request(GPIO_FN_ET_TX_ER, NULL);
511 gpio_request(GPIO_FN_ET_RX_ER, NULL);
512 gpio_request(GPIO_FN_ET_ERXD0, NULL);
513 gpio_request(GPIO_FN_ET_ERXD1, NULL);
514 gpio_request(GPIO_FN_ET_ERXD2, NULL);
515 gpio_request(GPIO_FN_ET_ERXD3, NULL);
516 gpio_request(GPIO_FN_ET_TX_CLK, NULL);
517 gpio_request(GPIO_FN_ET_TX_EN, NULL);
518 gpio_request(GPIO_FN_ET_ETXD0, NULL);
519 gpio_request(GPIO_FN_ET_ETXD1, NULL);
520 gpio_request(GPIO_FN_ET_ETXD2, NULL);
521 gpio_request(GPIO_FN_ET_ETXD3, NULL);
522 gpio_request(GPIO_FN_ET_PHY_INT, NULL);
523 gpio_request(GPIO_FN_ET_COL, NULL);
524 gpio_request(GPIO_FN_ET_RX_DV, NULL);
525 gpio_request(GPIO_FN_ET_RX_CLK, NULL);
526
527 gpio_request(GPIO_PORT18, NULL); /* PHY_RST */
528 gpio_direction_output(GPIO_PORT18, 1);
529
Kuninori Morimoto1c962932012-04-24 02:09:08 -0700530 /* USB */
531 gpio_request(GPIO_PORT159, NULL); /* USB_DEVICE_MODE */
532 gpio_direction_input(GPIO_PORT159);
533
534 if (gpio_get_value(GPIO_PORT159)) {
535 /* USB Host */
536 } else {
537 /* USB Func */
538 gpio_request(GPIO_FN_VBUS, NULL);
539 platform_device_register(&usbhsf_device);
540 }
541
Kuninori Morimotodad29d12012-04-06 01:30:09 -0700542 /*
543 * CAUTION
544 *
545 * DBGMD/LCDC0/FSIA MUX
546 * DBGMD_SELECT_B should be set after setting PFC Function.
547 */
548 gpio_request(GPIO_PORT176, NULL);
549 gpio_direction_output(GPIO_PORT176, 1);
550
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700551#ifdef CONFIG_CACHE_L2X0
552 /* Early BRESP enable, Shared attribute override enable, 32K*8way */
553 l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
554#endif
555
Kuninori Morimoto46cf6682012-04-06 01:30:42 -0700556 i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
557
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700558 r8a7740_add_standard_devices();
559
560 platform_add_devices(eva_devices,
561 ARRAY_SIZE(eva_devices));
562}
563
564static void __init eva_earlytimer_init(void)
565{
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700566 r8a7740_clock_init(MD_CK0 | MD_CK2);
Kuninori Morimoto4d22e562012-04-06 01:28:59 -0700567 shmobile_earlytimer_init();
568}
569
570static void __init eva_add_early_devices(void)
571{
572 r8a7740_add_early_devices();
573
574 /* override timer setup with board-specific code */
575 shmobile_timer.init = eva_earlytimer_init;
576}
577
578MACHINE_START(ARMADILLO800EVA, "armadillo800eva")
579 .map_io = r8a7740_map_io,
580 .init_early = eva_add_early_devices,
581 .init_irq = r8a7740_init_irq,
582 .handle_irq = shmobile_handle_irq_intc,
583 .init_machine = eva_init,
584 .timer = &shmobile_timer,
585MACHINE_END