2 * SAMSUNG EXYNOS5250 Flattened Device Tree enabled machine
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
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.
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>
22 #include <asm/mach/arch.h>
23 #include <asm/hardware/gic.h>
25 #include <mach/ohci.h>
26 #include <mach/regs-pmu.h>
27 #include <mach/sysmmu.h>
28 #include <mach/ohci.h>
31 #include <plat/dsim.h>
33 #include <plat/mipi_dsi.h>
34 #include <plat/gpio-cfg.h>
35 #include <plat/regs-fb.h>
36 #include <plat/regs-serial.h>
37 #include <plat/regs-srom.h>
38 #include <plat/backlight.h>
39 #include <plat/devs.h>
40 #include <plat/usb-phy.h>
41 #include <plat/ehci.h>
43 #include <video/platform_lcd.h>
45 #include "drm/exynos_drm.h"
48 static void __init smsc911x_init(int ncs)
52 /* configure nCS1 width to 16 bits */
53 data = __raw_readl(S5P_SROM_BW) &
54 ~(S5P_SROM_BW__CS_MASK << (ncs * 4));
55 data |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
56 (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
57 (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) << (ncs * 4);
58 __raw_writel(data, S5P_SROM_BW);
60 /* set timing for nCS1 suitable for ethernet chip */
61 __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
62 (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
63 (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
64 (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
65 (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
66 (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
67 (0x1 << S5P_SROM_BCX__TACS__SHIFT),
68 S5P_SROM_BC0 + (ncs * 4));
71 static struct s3c_fb_pd_win smdk5250_fb_win0 = {
90 static struct s3c_fb_pd_win smdk5250_fb_win1 = {
102 .virtual_y = 800 * 2,
109 static struct s3c_fb_pd_win smdk5250_fb_win2 = {
121 .virtual_y = 800 * 2,
128 static void exynos_fimd_gpio_setup_24bpp(void)
130 unsigned int reg = 0;
133 * Set DISP1BLK_CFG register for Display path selection
134 * FIMD of DISP1_BLK Bypass selection : DISP1BLK_CFG[15]
135 * ---------------------
137 * 1 | FIMD : selected
139 reg = __raw_readl(S3C_VA_SYS + 0x0214);
140 reg &= ~(1 << 15); /* To save other reset values */
142 __raw_writel(reg, S3C_VA_SYS + 0x0214);
145 static struct s3c_fb_platdata smdk5250_lcd1_pdata __initdata = {
146 .win[0] = &smdk5250_fb_win0,
147 .win[1] = &smdk5250_fb_win1,
148 .win[2] = &smdk5250_fb_win2,
150 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
151 .vidcon1 = VIDCON1_INV_VCLK,
152 .setup_gpio = exynos_fimd_gpio_setup_24bpp,
155 static struct mipi_dsim_config dsim_info = {
156 .e_interface = DSIM_VIDEO,
157 .e_pixel_format = DSIM_24BPP_888,
158 /* main frame fifo auto flush at VSYNC pulse */
160 .eot_disable = false,
161 .auto_vertical_cnt = false,
167 .e_no_data_lane = DSIM_DATA_LANE_4,
168 .e_byte_clk = DSIM_PLL_OUT_DIV8,
169 .e_burst_mode = DSIM_BURST,
175 /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
176 .pll_stable_time = 500,
178 .esc_clk = 0.4 * 1000000, /* escape clk : 10MHz */
180 /* stop state holding counter after bta change count 0 ~ 0xfff */
181 .stop_holding_cnt = 0x0f,
182 .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */
183 .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */
185 .dsim_ddi_pd = &tc358764_mipi_lcd_driver,
188 static struct mipi_dsim_lcd_config dsim_lcd_info = {
189 .rgb_timing.left_margin = 0x4,
190 .rgb_timing.right_margin = 0x4,
191 .rgb_timing.upper_margin = 0x4,
192 .rgb_timing.lower_margin = 0x4,
193 .rgb_timing.hsync_len = 0x4,
194 .rgb_timing.vsync_len = 0x4,
195 .cpu_timing.cs_setup = 0,
196 .cpu_timing.wr_setup = 1,
197 .cpu_timing.wr_act = 0,
198 .cpu_timing.wr_hold = 0,
199 .lcd_size.width = 1280,
200 .lcd_size.height = 800,
203 static struct s5p_platform_mipi_dsim dsim_platform_data = {
205 .dsim_config = &dsim_info,
206 .dsim_lcd_config = &dsim_lcd_info,
208 .part_reset = s5p_dsim_part_reset,
209 .init_d_phy = s5p_dsim_init_d_phy,
210 .get_fb_frame_done = NULL,
214 * the stable time of needing to write data on SFR
215 * when the mipi mode becomes LP mode.
217 .delay_for_stabilization = 600,
220 static struct platform_device exynos_drm_device = {
221 .name = "exynos-drm",
223 .dma_mask = &exynos_drm_device.dev.coherent_dma_mask,
224 .coherent_dma_mask = 0xffffffffUL,
228 static void lcd_set_power(struct plat_lcd_data *pd,
232 gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
236 /* fire nRESET on power up */
237 gpio_set_value(EXYNOS5_GPX1(5), 0);
239 gpio_set_value(EXYNOS5_GPX1(5), 1);
241 gpio_free(EXYNOS5_GPX1(5));
243 /* fire nRESET on power off */
244 gpio_set_value(EXYNOS5_GPX1(5), 0);
246 gpio_set_value(EXYNOS5_GPX1(5), 1);
248 gpio_free(EXYNOS5_GPX1(5));
252 * Request lcd_bl_en GPIO for smdk5250_bl_notify().
253 * TODO: Fix this so we are not at risk of requesting the GPIO
254 * multiple times, this should be done with device tree, and
255 * likely integrated into the plat-samsung/dev-backlight.c init.
257 gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
260 static int smdk5250_match_fb(struct plat_lcd_data *pd, struct fb_info *info)
262 /* Don't call .set_power callback while unblanking */
266 static struct plat_lcd_data smdk5250_lcd_data = {
267 .set_power = lcd_set_power,
268 .match_fb = smdk5250_match_fb,
271 static struct platform_device smdk5250_lcd = {
272 .name = "platform-lcd",
273 .dev.platform_data = &smdk5250_lcd_data,
276 static int smdk5250_bl_notify(struct device *unused, int brightness)
278 /* manage lcd_bl_en signal */
280 gpio_set_value(EXYNOS5_GPX3(0), 1);
282 gpio_set_value(EXYNOS5_GPX3(0), 0);
287 /* LCD Backlight data */
288 static struct samsung_bl_gpio_info smdk5250_bl_gpio_info = {
289 .no = EXYNOS5_GPB2(0),
290 .func = S3C_GPIO_SFN(2),
293 static struct platform_pwm_backlight_data smdk5250_bl_data = {
294 .pwm_period_ns = 1000,
295 .notify = smdk5250_bl_notify,
298 struct platform_device exynos_device_md0 = {
299 .name = "exynos-mdev",
303 struct platform_device exynos_device_md1 = {
304 .name = "exynos-mdev",
308 struct platform_device exynos_device_md2 = {
309 .name = "exynos-mdev",
313 static struct regulator_consumer_supply wm8994_avdd1_supply =
314 REGULATOR_SUPPLY("AVDD1", "1-001a");
316 static struct regulator_consumer_supply wm8994_dcvdd_supply =
317 REGULATOR_SUPPLY("DCVDD", "1-001a");
319 static struct regulator_init_data wm8994_ldo1_data = {
323 .num_consumer_supplies = 1,
324 .consumer_supplies = &wm8994_avdd1_supply,
327 static struct regulator_init_data wm8994_ldo2_data = {
331 .num_consumer_supplies = 1,
332 .consumer_supplies = &wm8994_dcvdd_supply,
335 static struct wm8994_pdata wm8994_platform_data = {
336 /* configure gpio1 function: 0x0001(Logic level input/output) */
337 .gpio_defaults[0] = 0x0001,
338 /* If the i2s0 and i2s2 is enabled simultaneously */
339 .gpio_defaults[7] = 0x8100, /* GPIO8 DACDAT3 in */
340 .gpio_defaults[8] = 0x0100, /* GPIO9 ADCDAT3 out */
341 .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3 out */
342 .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3 out */
343 .ldo[0] = { 0, &wm8994_ldo1_data },
344 .ldo[1] = { 0, &wm8994_ldo2_data },
347 static struct i2c_board_info i2c_devs1[] __initdata = {
349 I2C_BOARD_INFO("wm8994", 0x1a),
350 .platform_data = &wm8994_platform_data,
354 struct sysmmu_platform_data platdata_sysmmu_mfc_l = {
356 .clockname = "sysmmu",
359 struct sysmmu_platform_data platdata_sysmmu_mfc_r = {
361 .clockname = "sysmmu",
364 struct sysmmu_platform_data platdata_sysmmu_gsc = {
366 .clockname = "sysmmu",
369 struct sysmmu_platform_data platdata_sysmmu_g2d = {
371 .clockname = "sysmmu",
374 struct sysmmu_platform_data platdata_sysmmu_fimd = {
376 .clockname = "sysmmu",
379 struct sysmmu_platform_data platdata_sysmmu_tv = {
381 .clockname = "sysmmu",
384 #ifdef CONFIG_VIDEO_FIMG2D4X
385 static struct fimg2d_platdata fimg2d_data __initdata = {
387 .gate_clkname = "fimg2d",
391 static struct exynos4_ohci_platdata smdk5250_ohci_pdata = {
392 .phy_init = s5p_usb_phy_init,
393 .phy_exit = s5p_usb_phy_exit,
396 static struct s5p_ehci_platdata smdk5250_ehci_pdata = {
397 .phy_init = s5p_usb_phy_init,
398 .phy_exit = s5p_usb_phy_exit,
402 * The following lookup table is used to override device names when devices
403 * are registered from device tree. This is temporarily added to enable
404 * device tree support addition for the EXYNOS5 architecture.
406 * For drivers that require platform data to be provided from the machine
407 * file, a platform data pointer can also be supplied along with the
408 * devices names. Usually, the platform data elements that cannot be parsed
409 * from the device tree by the drivers (example: function pointers) are
410 * supplied. But it should be noted that this is a temporary mechanism and
411 * at some point, the drivers should be capable of parsing all the platform
412 * data from the device tree.
414 static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
415 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0,
416 "exynos4210-uart.0", NULL),
417 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1,
418 "exynos4210-uart.1", NULL),
419 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2,
420 "exynos4210-uart.2", NULL),
421 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
422 "exynos4210-uart.3", NULL),
423 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
424 "s3c2440-i2c.0", NULL),
425 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
426 "s3c2440-i2c.1", NULL),
427 OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12200000,
429 OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12210000,
431 OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12220000,
433 OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12230000,
435 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
436 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
437 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
438 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x10A60000,
439 "s5p-sysmmu.2", &platdata_sysmmu_g2d),
440 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11210000,
441 "s5p-sysmmu.3", &platdata_sysmmu_mfc_l),
442 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11200000,
443 "s5p-sysmmu.4", &platdata_sysmmu_mfc_r),
444 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14640000,
445 "s5p-sysmmu.27", &platdata_sysmmu_fimd),
446 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14650000,
447 "s5p-sysmmu.28", &platdata_sysmmu_tv),
448 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E80000,
449 "s5p-sysmmu.23", &platdata_sysmmu_gsc),
450 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E90000,
451 "s5p-sysmmu.24", &platdata_sysmmu_gsc),
452 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EA0000,
453 "s5p-sysmmu.25", &platdata_sysmmu_gsc),
454 OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EB0000,
455 "s5p-sysmmu.26", &platdata_sysmmu_gsc),
456 OF_DEV_AUXDATA("samsung,exynos5-fb", 0x14400000,
457 "exynos5-fb", &smdk5250_lcd1_pdata),
458 OF_DEV_AUXDATA("samsung,exynos5-mipi", 0x14500000,
459 "s5p-mipi-dsim", &dsim_platform_data),
460 OF_DEV_AUXDATA("samsung,s5p-mfc-v6", 0x11000000, "s5p-mfc-v6", NULL),
461 OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E00000,
462 "exynos-gsc.0", NULL),
463 OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E10000,
464 "exynos-gsc.1", NULL),
465 OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E20000,
466 "exynos-gsc.2", NULL),
467 OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E30000,
468 "exynos-gsc.3", NULL),
469 #ifdef CONFIG_VIDEO_FIMG2D4X
470 OF_DEV_AUXDATA("samsung,s5p-g2d", 0x10850000,
471 "s5p-g2d", &fimg2d_data),
473 OF_DEV_AUXDATA("samsung,exynos-ohci", 0x12120000,
474 "exynos-ohci", &smdk5250_ohci_pdata),
475 OF_DEV_AUXDATA("samsung,exynos-ehci", 0x12110000,
476 "s5p-ehci", &smdk5250_ehci_pdata),
480 static struct platform_device *smdk5250_devices[] __initdata = {
481 &smdk5250_lcd, /* for platform_lcd device */
482 &exynos_device_md0, /* for media device framework */
483 &exynos_device_md1, /* for media device framework */
484 &exynos_device_md2, /* for media device framework */
485 &samsung_asoc_dma, /* for audio dma interface device */
489 static void __init exynos5250_dt_map_io(void)
491 exynos_init_io(NULL, 0);
492 s3c24xx_init_clocks(24000000);
495 static void __init exynos5_reserve(void)
497 /* required to have enough address range to remap the IOMMU
498 * allocated buffers */
499 init_consistent_dma_size(SZ_64M);
502 static void s5p_tv_setup(void)
504 /* direct HPD to HDMI chip */
505 gpio_request(EXYNOS5_GPX3(7), "hpd-plug");
507 gpio_direction_input(EXYNOS5_GPX3(7));
508 s3c_gpio_cfgpin(EXYNOS5_GPX3(7), S3C_GPIO_SFN(0x3));
509 s3c_gpio_setpull(EXYNOS5_GPX3(7), S3C_GPIO_PULL_NONE);
512 static void exynos5_i2c_setup(void)
514 /* Setup the low-speed i2c controller interrupts */
515 writel(0x0, EXYNOS5_SYS_I2C_CFG);
518 static void __init exynos5250_dt_machine_init(void)
520 if (of_machine_is_compatible("samsung,smdk5250"))
522 samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
524 if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
525 "HOST_VBUS_CONTROL")) {
526 printk(KERN_ERR "failed to request gpio_host_vbus\n");
528 s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
529 gpio_free(EXYNOS5_GPX2(6));
534 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
536 of_platform_populate(NULL, of_default_bus_match_table,
537 exynos5250_auxdata_lookup, NULL);
541 platform_add_devices(smdk5250_devices, ARRAY_SIZE(smdk5250_devices));
544 static char const *exynos5250_dt_compat[] __initdata = {
545 "samsung,exynos5250",
549 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
550 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
551 .init_irq = exynos5_init_irq,
552 .reserve = exynos5_reserve,
553 .map_io = exynos5250_dt_map_io,
554 .handle_irq = gic_handle_irq,
555 .init_machine = exynos5250_dt_machine_init,
556 .timer = &exynos4_timer,
557 .dt_compat = exynos5250_dt_compat,
558 .restart = exynos5_restart,