ARM: EXYNOS5: add sysmmu devices from device tree
[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/i2c.h>
18 #include <linux/pwm_backlight.h>
19 #include <linux/mfd/wm8994/pdata.h>
20 #include <linux/regulator/machine.h>
21
22 #include <asm/mach/arch.h>
23 #include <asm/hardware/gic.h>
24 #include <mach/map.h>
25 #include <mach/ohci.h>
26 #include <mach/regs-pmu.h>
27 #include <mach/sysmmu.h>
28
29 #include <plat/cpu.h>
30 #include <plat/regs-serial.h>
31 #include <plat/regs-srom.h>
32 #include <plat/backlight.h>
33 #include <plat/devs.h>
34 #include <plat/usb-phy.h>
35
36 #include <video/platform_lcd.h>
37
38 #include "drm/exynos_drm.h"
39 #include "common.h"
40
41 static void __init smsc911x_init(int ncs)
42 {
43         u32 data;
44
45         /* configure nCS1 width to 16 bits */
46         data = __raw_readl(S5P_SROM_BW) &
47                 ~(S5P_SROM_BW__CS_MASK << (ncs * 4));
48         data |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
49                 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
50                 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) << (ncs * 4);
51         __raw_writel(data, S5P_SROM_BW);
52
53         /* set timing for nCS1 suitable for ethernet chip */
54         __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
55                 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
56                 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
57                 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
58                 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
59                 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
60                 (0x1 << S5P_SROM_BCX__TACS__SHIFT),
61                 S5P_SROM_BC0 + (ncs * 4));
62 }
63
64 static struct platform_device exynos_drm_device = {
65         .name           = "exynos-drm",
66         .dev = {
67                 .dma_mask = &exynos_drm_device.dev.coherent_dma_mask,
68                 .coherent_dma_mask = 0xffffffffUL,
69         }
70 };
71
72 static void lcd_set_power(struct plat_lcd_data *pd,
73                         unsigned int power)
74 {
75         /* reset */
76         gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
77
78         mdelay(20);
79         if (power) {
80                 /* fire nRESET on power up */
81                 gpio_set_value(EXYNOS5_GPX1(5), 0);
82                 mdelay(20);
83                 gpio_set_value(EXYNOS5_GPX1(5), 1);
84                 mdelay(20);
85                 gpio_free(EXYNOS5_GPX1(5));
86         } else {
87                 /* fire nRESET on power off */
88                 gpio_set_value(EXYNOS5_GPX1(5), 0);
89                 mdelay(20);
90                 gpio_set_value(EXYNOS5_GPX1(5), 1);
91                 mdelay(20);
92                 gpio_free(EXYNOS5_GPX1(5));
93         }
94         mdelay(20);
95         /*
96          * Request lcd_bl_en GPIO for smdk5250_bl_notify().
97          * TODO: Fix this so we are not at risk of requesting the GPIO
98          * multiple times, this should be done with device tree, and
99          * likely integrated into the plat-samsung/dev-backlight.c init.
100          */
101         gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
102 }
103
104 static int smdk5250_match_fb(struct plat_lcd_data *pd, struct fb_info *info)
105 {
106         /* Don't call .set_power callback while unblanking */
107         return 0;
108 }
109
110 static struct plat_lcd_data smdk5250_lcd_data = {
111         .set_power      = lcd_set_power,
112         .match_fb       = smdk5250_match_fb,
113 };
114
115 static struct platform_device smdk5250_lcd = {
116         .name                   = "platform-lcd",
117         .dev.platform_data      = &smdk5250_lcd_data,
118 };
119
120 static int smdk5250_bl_notify(struct device *unused, int brightness)
121 {
122         /* manage lcd_bl_en signal */
123         if (brightness)
124                 gpio_set_value(EXYNOS5_GPX3(0), 1);
125         else
126                 gpio_set_value(EXYNOS5_GPX3(0), 0);
127
128         return brightness;
129 }
130
131 /* LCD Backlight data */
132 static struct samsung_bl_gpio_info smdk5250_bl_gpio_info = {
133         .no     = EXYNOS5_GPB2(0),
134         .func   = S3C_GPIO_SFN(2),
135 };
136
137 static struct platform_pwm_backlight_data smdk5250_bl_data = {
138         .pwm_period_ns  = 1000,
139         .notify         = smdk5250_bl_notify,
140 };
141
142 struct platform_device exynos_device_md0 = {
143         .name = "exynos-mdev",
144         .id = 0,
145 };
146
147 struct platform_device exynos_device_md1 = {
148         .name = "exynos-mdev",
149         .id = 1,
150 };
151
152 struct platform_device exynos_device_md2 = {
153         .name = "exynos-mdev",
154         .id = 2,
155 };
156
157 static struct regulator_consumer_supply wm8994_avdd1_supply =
158         REGULATOR_SUPPLY("AVDD1", "1-001a");
159
160 static struct regulator_consumer_supply wm8994_dcvdd_supply =
161         REGULATOR_SUPPLY("DCVDD", "1-001a");
162
163 static struct regulator_init_data wm8994_ldo1_data = {
164         .constraints    = {
165                 .name           = "AVDD1",
166         },
167         .num_consumer_supplies  = 1,
168         .consumer_supplies      = &wm8994_avdd1_supply,
169 };
170
171 static struct regulator_init_data wm8994_ldo2_data = {
172         .constraints    = {
173         .name                   = "DCVDD",
174                 },
175         .num_consumer_supplies  = 1,
176         .consumer_supplies      = &wm8994_dcvdd_supply,
177 };
178
179 static struct wm8994_pdata wm8994_platform_data = {
180         /* configure gpio1 function: 0x0001(Logic level input/output) */
181         .gpio_defaults[0] = 0x0001,
182         /* If the i2s0 and i2s2 is enabled simultaneously */
183         .gpio_defaults[7] = 0x8100, /* GPIO8  DACDAT3 in */
184         .gpio_defaults[8] = 0x0100, /* GPIO9  ADCDAT3 out */
185         .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3  out */
186         .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3   out */
187         .ldo[0] = { 0, &wm8994_ldo1_data },
188         .ldo[1] = { 0, &wm8994_ldo2_data },
189 };
190
191 static struct i2c_board_info i2c_devs1[] __initdata = {
192         {
193                 I2C_BOARD_INFO("wm8994", 0x1a),
194                 .platform_data  = &wm8994_platform_data,
195         },
196 };
197
198 struct sysmmu_platform_data platdata_sysmmu_mfc_l = {
199         .dbgname = "mfc_l",
200         .clockname = "sysmmu",
201 };
202
203 struct sysmmu_platform_data platdata_sysmmu_mfc_r = {
204         .dbgname = "mfc_r",
205         .clockname = "sysmmu",
206 };
207
208 struct sysmmu_platform_data platdata_sysmmu_gsc = {
209         .dbgname = "gsc",
210         .clockname = "sysmmu",
211 };
212
213 struct sysmmu_platform_data platdata_sysmmu_g2d = {
214         .dbgname = "g2d",
215         .clockname = "sysmmu",
216 };
217
218 struct sysmmu_platform_data platdata_sysmmu_fimd = {
219         .dbgname = "fimd",
220         .clockname = "sysmmu",
221 };
222
223 struct sysmmu_platform_data platdata_sysmmu_tv = {
224         .dbgname = "tv",
225         .clockname = "sysmmu",
226 };
227
228 /*
229  * The following lookup table is used to override device names when devices
230  * are registered from device tree. This is temporarily added to enable
231  * device tree support addition for the EXYNOS5 architecture.
232  *
233  * For drivers that require platform data to be provided from the machine
234  * file, a platform data pointer can also be supplied along with the
235  * devices names. Usually, the platform data elements that cannot be parsed
236  * from the device tree by the drivers (example: function pointers) are
237  * supplied. But it should be noted that this is a temporary mechanism and
238  * at some point, the drivers should be capable of parsing all the platform
239  * data from the device tree.
240  */
241 static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
242         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0,
243                                 "exynos4210-uart.0", NULL),
244         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1,
245                                 "exynos4210-uart.1", NULL),
246         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2,
247                                 "exynos4210-uart.2", NULL),
248         OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
249                                 "exynos4210-uart.3", NULL),
250         OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
251                                 "s3c2440-i2c.0", NULL),
252         OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
253                                 "s3c2440-i2c.1", NULL),
254         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12200000,
255                                 "dw_mmc.0", NULL),
256         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12210000,
257                                 "dw_mmc.1", NULL),
258         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12220000,
259                                 "dw_mmc.2", NULL),
260         OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12230000,
261                                 "dw_mmc.3", NULL),
262         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
263         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
264         OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
265         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x10A60000,
266                                 "s5p-sysmmu.2", &platdata_sysmmu_g2d),
267         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11210000,
268                                 "s5p-sysmmu.3", &platdata_sysmmu_mfc_l),
269         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11200000,
270                                 "s5p-sysmmu.4", &platdata_sysmmu_mfc_r),
271         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14640000,
272                                 "s5p-sysmmu.27", &platdata_sysmmu_fimd),
273         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14650000,
274                                 "s5p-sysmmu.28", &platdata_sysmmu_tv),
275         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E80000,
276                                 "s5p-sysmmu.23", &platdata_sysmmu_gsc),
277         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E90000,
278                                 "s5p-sysmmu.24", &platdata_sysmmu_gsc),
279         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EA0000,
280                                 "s5p-sysmmu.25", &platdata_sysmmu_gsc),
281         OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EB0000,
282                                 "s5p-sysmmu.26", &platdata_sysmmu_gsc),
283         {},
284 };
285
286 static struct platform_device *smdk5250_devices[] __initdata = {
287         &smdk5250_lcd, /* for platform_lcd device */
288         &exynos_device_md0, /* for media device framework */
289         &exynos_device_md1, /* for media device framework */
290         &exynos_device_md2, /* for media device framework */
291         &samsung_asoc_dma,  /* for audio dma interface device */
292         &exynos_drm_device,
293 };
294
295 static void __init exynos5250_dt_map_io(void)
296 {
297         exynos_init_io(NULL, 0);
298         s3c24xx_init_clocks(24000000);
299 }
300
301 static void __init exynos5_reserve(void)
302 {
303         /* required to have enough address range to remap the IOMMU
304          * allocated buffers */
305         init_consistent_dma_size(SZ_64M);
306 }
307
308 static void s5p_tv_setup(void)
309 {
310         /* direct HPD to HDMI chip */
311         gpio_request(EXYNOS5_GPX3(7), "hpd-plug");
312
313         gpio_direction_input(EXYNOS5_GPX3(7));
314         s3c_gpio_cfgpin(EXYNOS5_GPX3(7), S3C_GPIO_SFN(0x3));
315         s3c_gpio_setpull(EXYNOS5_GPX3(7), S3C_GPIO_PULL_NONE);
316 }
317
318 static void exynos5_i2c_setup(void)
319 {
320         /* Setup the low-speed i2c controller interrupts */
321         writel(0x0, EXYNOS5_SYS_I2C_CFG);
322 }
323
324 static void __init exynos5250_dt_machine_init(void)
325 {
326         if (of_machine_is_compatible("samsung,smdk5250"))
327                 smsc911x_init(1);
328         samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
329
330         if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
331                 "HOST_VBUS_CONTROL")) {
332                 printk(KERN_ERR "failed to request gpio_host_vbus\n");
333         } else {
334                 s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
335                 gpio_free(EXYNOS5_GPX2(6));
336         }
337
338         exynos5_i2c_setup();
339
340         i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
341
342         of_platform_populate(NULL, of_default_bus_match_table,
343                                 exynos5250_auxdata_lookup, NULL);
344
345         s5p_tv_setup();
346
347         platform_add_devices(smdk5250_devices, ARRAY_SIZE(smdk5250_devices));
348 }
349
350 static char const *exynos5250_dt_compat[] __initdata = {
351         "samsung,exynos5250",
352         NULL
353 };
354
355 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
356         /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
357         .init_irq       = exynos5_init_irq,
358         .reserve        = exynos5_reserve,
359         .map_io         = exynos5250_dt_map_io,
360         .handle_irq     = gic_handle_irq,
361         .init_machine   = exynos5250_dt_machine_init,
362         .timer          = &exynos4_timer,
363         .dt_compat      = exynos5250_dt_compat,
364         .restart        = exynos5_restart,
365 MACHINE_END