ARM: EXYNOS5: add machine specific device tree node for media layer
[cascardo/linux.git] / arch / arm / mach-exynos / mach-exynos5-dt.c
1 /*
2  * SAMSUNG EXYNOS5250 Flattened Device Tree enabled machine
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5  *              http://www.samsung.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 version 2 as
9  * published by the Free Software Foundation.
10 */
11
12 #include <linux/gpio.h>
13 #include <linux/of_platform.h>
14 #include <linux/serial_core.h>
15 #include <linux/smsc911x.h>
16 #include <linux/delay.h>
17 #include <linux/pwm_backlight.h>
18
19 #include <asm/mach/arch.h>
20 #include <asm/hardware/gic.h>
21 #include <mach/map.h>
22
23 #include <plat/cpu.h>
24 #include <plat/regs-serial.h>
25 #include <plat/regs-srom.h>
26 #include <plat/backlight.h>
27 #include <plat/devs.h>
28
29 #include <video/platform_lcd.h>
30
31 #include "common.h"
32
33 static void __init smsc911x_init(int ncs)
34 {
35         u32 data;
36
37         /* configure nCS1 width to 16 bits */
38         data = __raw_readl(S5P_SROM_BW) &
39                 ~(S5P_SROM_BW__CS_MASK << (ncs * 4));
40         data |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
41                 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
42                 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) << (ncs * 4);
43         __raw_writel(data, S5P_SROM_BW);
44
45         /* set timing for nCS1 suitable for ethernet chip */
46         __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
47                 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
48                 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
49                 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
50                 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
51                 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
52                 (0x1 << S5P_SROM_BCX__TACS__SHIFT),
53                 S5P_SROM_BC0 + (ncs * 4));
54 }
55
56 static void mipi_lcd_set_power(struct plat_lcd_data *pd,
57                         unsigned int power)
58 {
59         /* reset */
60         gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
61
62         mdelay(20);
63         if (power) {
64                 /* fire nRESET on power up */
65                 gpio_set_value(EXYNOS5_GPX1(5), 0);
66                 mdelay(20);
67                 gpio_set_value(EXYNOS5_GPX1(5), 1);
68                 mdelay(20);
69                 gpio_free(EXYNOS5_GPX1(5));
70         } else {
71                 /* fire nRESET on power off */
72                 gpio_set_value(EXYNOS5_GPX1(5), 0);
73                 mdelay(20);
74                 gpio_set_value(EXYNOS5_GPX1(5), 1);
75                 mdelay(20);
76                 gpio_free(EXYNOS5_GPX1(5));
77         }
78         mdelay(20);
79         /*
80          * Request lcd_bl_en GPIO for smdk5250_bl_notify().
81          * TODO: Fix this so we are not at risk of requesting the GPIO
82          * multiple times, this should be done with device tree, and
83          * likely integrated into the plat-samsung/dev-backlight.c init.
84          */
85         gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
86 }
87
88 static int smdk5250_match_fb(struct plat_lcd_data *pd, struct fb_info *info)
89 {
90         /* Don't call .set_power callback while unblanking */
91         return 0;
92 }
93
94 static struct plat_lcd_data smdk5250_mipi_lcd_data = {
95         .set_power      = mipi_lcd_set_power,
96         .match_fb       = smdk5250_match_fb,
97 };
98
99 static struct platform_device smdk5250_mipi_lcd = {
100         .name                   = "platform-lcd",
101         .dev.platform_data      = &smdk5250_mipi_lcd_data,
102 };
103
104 static int smdk5250_bl_notify(struct device *unused, int brightness)
105 {
106         /* manage lcd_bl_en signal */
107         if (brightness)
108                 gpio_set_value(EXYNOS5_GPX3(0), 1);
109         else
110                 gpio_set_value(EXYNOS5_GPX3(0), 0);
111
112         return brightness;
113 }
114
115 /* LCD Backlight data */
116 static struct samsung_bl_gpio_info smdk5250_bl_gpio_info = {
117         .no     = EXYNOS5_GPB2(0),
118         .func   = S3C_GPIO_SFN(2),
119 };
120
121 static struct platform_pwm_backlight_data smdk5250_bl_data = {
122         .pwm_period_ns  = 1000,
123         .notify         = smdk5250_bl_notify,
124 };
125
126 struct platform_device exynos_device_md0 = {
127         .name = "exynos-mdev",
128         .id = 0,
129 };
130
131 struct platform_device exynos_device_md1 = {
132         .name = "exynos-mdev",
133         .id = 1,
134 };
135
136 struct platform_device exynos_device_md2 = {
137         .name = "exynos-mdev",
138         .id = 2,
139 };
140
141 /*
142  * The following lookup table is used to override device names when devices
143  * are registered from device tree. This is temporarily added to enable
144  * device tree support addition for the EXYNOS5 architecture.
145  *
146  * For drivers that require platform data to be provided from the machine
147  * file, a platform data pointer can also be supplied along with the
148  * devices names. Usually, the platform data elements that cannot be parsed
149  * from the device tree by the drivers (example: function pointers) are
150  * supplied. But it should be noted that this is a temporary mechanism and
151  * at some point, the drivers should be capable of parsing all the platform
152  * data from the device tree.
153  */
154 static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
155         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0,
156                                 "exynos4210-uart.0", NULL),
157         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1,
158                                 "exynos4210-uart.1", NULL),
159         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2,
160                                 "exynos4210-uart.2", NULL),
161         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
162                                 "exynos4210-uart.3", NULL),
163         OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
164                                 "s3c2440-i2c.0", NULL),
165         OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
166                                 "s3c2440-i2c.1", NULL),
167         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12200000,
168                                 "dw_mmc.0", NULL),
169         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12210000,
170                                 "dw_mmc.1", NULL),
171         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12220000,
172                                 "dw_mmc.2", NULL),
173         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12230000,
174                                 "dw_mmc.3", NULL),
175         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
176         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
177         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
178         {},
179 };
180
181 static struct platform_device *smdk5250_devices[] __initdata = {
182         &smdk5250_mipi_lcd, /* for platform_lcd device */
183         &exynos_device_md0, /* for media device framework */
184         &exynos_device_md1, /* for media device framework */
185         &exynos_device_md2, /* for media device framework */
186 };
187
188 static void __init exynos5250_dt_map_io(void)
189 {
190         exynos_init_io(NULL, 0);
191         s3c24xx_init_clocks(24000000);
192 }
193
194 static void __init exynos5250_dt_machine_init(void)
195 {
196         if (of_machine_is_compatible("samsung,smdk5250"))
197                 smsc911x_init(1);
198         samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
199
200         of_platform_populate(NULL, of_default_bus_match_table,
201                                 exynos5250_auxdata_lookup, NULL);
202
203         platform_add_devices(smdk5250_devices, ARRAY_SIZE(smdk5250_devices));
204 }
205
206 static char const *exynos5250_dt_compat[] __initdata = {
207         "samsung,exynos5250",
208         NULL
209 };
210
211 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
212         /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
213         .init_irq       = exynos5_init_irq,
214         .map_io         = exynos5250_dt_map_io,
215         .handle_irq     = gic_handle_irq,
216         .init_machine   = exynos5250_dt_machine_init,
217         .timer          = &exynos4_timer,
218         .dt_compat      = exynos5250_dt_compat,
219         .restart        = exynos5_restart,
220 MACHINE_END