CHROMIUM: Remove "DP Hotplug" in mach-exynos.
[cascardo/linux.git] / arch / arm / mach-exynos / mach-exynos5-dt.c
index cd753f1..0d12546 100644 (file)
 */
 
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dwc3-exynos.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/serial_core.h>
 #include <linux/smsc911x.h>
 #include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/memblock.h>
+#include <linux/of_fdt.h>
+#include <linux/err.h>
+#include <linux/platform_data/ntc_thermistor.h>
+
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
+#include <mach/bitfix-snow.h>
 #include <mach/map.h>
+#include <mach/ppmu.h>
+#include <mach/dev.h>
+#include <mach/ohci.h>
+#include <mach/regs-pmu.h>
+#include <mach/sysmmu.h>
+#include <mach/ohci.h>
+#include <mach/regs-audss.h>
+#include <mach/regs-pmu.h>
 
+#include <plat/audio.h>
+#include <plat/adc.h>  /* for s3c_adc_register and friends */
 #include <plat/cpu.h>
+#include <plat/dsim.h>
+#include <plat/fb.h>
+#include <plat/mipi_dsi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-fb.h>
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
+#include <plat/backlight.h>
+#include <plat/devs.h>
+#include <plat/usb-phy.h>
+#include <plat/ehci.h>
+#include <plat/dp.h>
+#include <plat/s3c64xx-spi.h>
 
 #include <video/platform_lcd.h>
 
+#include "drm/exynos_drm.h"
 #include "common.h"
 
 static void __init smsc911x_init(int ncs)
@@ -49,36 +86,299 @@ static void __init smsc911x_init(int ncs)
                S5P_SROM_BC0 + (ncs * 4));
 }
 
-static void mipi_lcd_set_power(struct plat_lcd_data *pd,
+#ifndef CONFIG_DRM_EXYNOS_FIMD
+static struct s3c_fb_pd_win smdk5250_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 4,
+               .right_margin   = 4,
+               .upper_margin   = 4,
+               .lower_margin   = 4,
+               .hsync_len      = 4,
+               .vsync_len      = 4,
+               .xres           = 1280,
+               .yres           = 800,
+       },
+       .virtual_x              = 1280,
+       .virtual_y              = 800 * 2,
+       .width                  = 223,
+       .height                 = 125,
+       .max_bpp                = 32,
+       .default_bpp            = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win1 = {
+       .win_mode = {
+               .left_margin    = 4,
+               .right_margin   = 4,
+               .upper_margin   = 4,
+               .lower_margin   = 4,
+               .hsync_len      = 4,
+               .vsync_len      = 4,
+               .xres           = 1280,
+               .yres           = 800,
+       },
+       .virtual_x              = 1280,
+       .virtual_y              = 800 * 2,
+       .width                  = 223,
+       .height                 = 125,
+       .max_bpp                = 32,
+       .default_bpp            = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win2 = {
+       .win_mode = {
+               .left_margin    = 0x4,
+               .right_margin   = 0x4,
+               .upper_margin   = 4,
+               .lower_margin   = 4,
+               .hsync_len      = 4,
+               .vsync_len      = 4,
+               .xres           = 1280,
+               .yres           = 800,
+       },
+       .virtual_x              = 1280,
+       .virtual_y              = 800 * 2,
+       .width                  = 223,
+       .height                 = 125,
+       .max_bpp                = 32,
+       .default_bpp            = 24,
+};
+#endif
+
+/*
+ * - 70250000. / ((1366 + 40 + 40 + 32) * (768 + 10 + 10 + 5))
+ * - 59.93751141159025
+ * - 70500000. / ((1366 + 40 + 40 + 32) * (768 + 10 + 10 + 5))
+ * - 60.150812163944664
+ * - 70500000. / ((1366 + 40 + 40 + 32) * (768 + 10 + 12 + 6))
+ *   59.92411312312578
+ */
+static struct fb_videomode snow_fb_window = {
+               .left_margin    = 40,
+               .right_margin   = 40,
+               .upper_margin   = 10,
+               .lower_margin   = 12,
+               .hsync_len      = 32,
+               .vsync_len      = 6,
+               .xres           = 1366,
+               .yres           = 768,
+               .refresh        = 60,
+               .pixclock       = 70500000,
+};
+
+static void exynos_fimd_gpio_setup_24bpp(void)
+{
+       unsigned int reg = 0;
+
+       /*
+        * Set DISP1BLK_CFG register for Display path selection
+        * FIMD of DISP1_BLK Bypass selection : DISP1BLK_CFG[15]
+        * ---------------------
+        * 0 | MIE/MDNIE
+        * 1 | FIMD : selected
+        */
+       reg = __raw_readl(S3C_VA_SYS + 0x0214);
+       reg &= ~(1 << 15);      /* To save other reset values */
+       __raw_writel(reg, S3C_VA_SYS + 0x0214);
+}
+
+static void exynos_dp_gpio_setup_24bpp(void)
+{
+       exynos_fimd_gpio_setup_24bpp();
+
+       /* Set Hotplug detect for DP */
+       gpio_request(EXYNOS5_GPX0(7), "DP hotplug");
+       s3c_gpio_cfgpin(EXYNOS5_GPX0(7), S3C_GPIO_SFN(3));
+}
+
+#ifdef CONFIG_DRM_EXYNOS_HDMI
+static struct platform_device exynos_drm_hdmi_device = {
+       .name           = "exynos-drm-hdmi",
+};
+
+static struct exynos_drm_hdmi_pdata drm_mixer_pdata = {
+       .timing = {
+               .xres    = 1920,
+               .yres    = 1080,
+               .refresh = 60,
+       },
+       .default_win    = 0,
+       .bpp            = 32,
+       .is_v13         = 0,
+       .is_soc_exynos5 = 1,
+};
+
+static struct exynos_drm_hdmi_pdata drm_hdmi_pdata = {
+       .timing = {
+               .xres    = 1920,
+               .yres    = 1080,
+               .refresh    = 60,
+       },
+       .default_win    = 0,
+       .bpp            = 32,
+       .is_v13         = 0,
+       .is_soc_exynos5 = 1,
+};
+#endif
+
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+static struct exynos_drm_fimd_pdata smdk5250_lcd1_pdata = {
+       .panel = {
+               .timing   = {
+                       .xres           = 1280,
+                       .yres           = 800,
+                       .hsync_len      = 4,
+                       .left_margin    = 0x4,
+                       .right_margin   = 0x4,
+                       .vsync_len      = 4,
+                       .upper_margin   = 4,
+                       .lower_margin   = 4,
+                       .refresh        = 60,
+               },
+       },
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_VCLK,
+       .default_win    = 0,
+       .bpp            = 32,
+       .clock_rate     = 800 * 1000 * 1000,
+};
+#else
+static struct s3c_fb_platdata smdk5250_lcd1_pdata __initdata = {
+       .win[0]         = &smdk5250_fb_win0,
+       .win[1]         = &smdk5250_fb_win1,
+       .win[2]         = &smdk5250_fb_win2,
+       .default_win    = 0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_VCLK,
+       .setup_gpio     = exynos_fimd_gpio_setup_24bpp,
+       .clock_rate     = 800 * 1000 * 1000,
+};
+#endif
+
+static struct mipi_dsim_config dsim_info = {
+       .e_interface            = DSIM_VIDEO,
+       .e_pixel_format         = DSIM_24BPP_888,
+       /* main frame fifo auto flush at VSYNC pulse */
+       .auto_flush             = false,
+       .eot_disable            = false,
+       .auto_vertical_cnt      = false,
+       .hse                    = false,
+       .hfp                    = false,
+       .hbp                    = false,
+       .hsa                    = false,
+
+       .e_no_data_lane         = DSIM_DATA_LANE_4,
+       .e_byte_clk             = DSIM_PLL_OUT_DIV8,
+       .e_burst_mode           = DSIM_BURST,
+
+       .p                      = 3,
+       .m                      = 115,
+       .s                      = 1,
+
+       /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+       .pll_stable_time        = 500,
+
+       .esc_clk                = 0.4 * 1000000, /* escape clk : 10MHz */
+
+       /* stop state holding counter after bta change count 0 ~ 0xfff */
+       .stop_holding_cnt       = 0x0f,
+       .bta_timeout            = 0xff,         /* bta timeout 0 ~ 0xff */
+       .rx_timeout             = 0xffff,       /* lp rx timeout 0 ~ 0xffff */
+
+       .dsim_ddi_pd = &tc358764_mipi_lcd_driver,
+};
+
+static struct mipi_dsim_lcd_config dsim_lcd_info = {
+       .rgb_timing.left_margin         = 0x4,
+       .rgb_timing.right_margin        = 0x4,
+       .rgb_timing.upper_margin        = 0x4,
+       .rgb_timing.lower_margin        =  0x4,
+       .rgb_timing.hsync_len           = 0x4,
+       .rgb_timing.vsync_len           = 0x4,
+       .cpu_timing.cs_setup            = 0,
+       .cpu_timing.wr_setup            = 1,
+       .cpu_timing.wr_act              = 0,
+       .cpu_timing.wr_hold             = 0,
+       .lcd_size.width                 = 1280,
+       .lcd_size.height                = 800,
+};
+
+static struct s5p_platform_mipi_dsim dsim_platform_data = {
+       .clk_name               = "dsim0",
+       .dsim_config            = &dsim_info,
+       .dsim_lcd_config        = &dsim_lcd_info,
+
+       .part_reset             = s5p_dsim_part_reset,
+       .init_d_phy             = s5p_dsim_init_d_phy,
+       .get_fb_frame_done      = NULL,
+       .trigger                = NULL,
+
+       /*
+        * the stable time of needing to write data on SFR
+        * when the mipi mode becomes LP mode.
+        */
+       .delay_for_stabilization = 600,
+};
+
+static struct platform_device exynos_drm_device = {
+       .name           = "exynos-drm",
+       .dev = {
+               .dma_mask = &exynos_drm_device.dev.coherent_dma_mask,
+               .coherent_dma_mask = 0xffffffffUL,
+       }
+};
+
+static void exynos_wifi_bt_set_power(u32, u32);        /* TODO(sleffler) hack */
+
+static void lcd_set_power(struct plat_lcd_data *pd,
                        unsigned int power)
 {
-       /* reset */
-       gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
+       if (of_machine_is_compatible("google,daisy") ||
+                       of_machine_is_compatible("google,snow")) {
+               struct regulator *lcd_fet;
 
-       mdelay(20);
-       if (power) {
-               /* fire nRESET on power up */
-               gpio_set_value(EXYNOS5_GPX1(5), 0);
-               mdelay(20);
-               gpio_set_value(EXYNOS5_GPX1(5), 1);
+               lcd_fet = regulator_get(NULL, "lcd_vdd");
+               if (!IS_ERR(lcd_fet)) {
+                       if (power)
+                               regulator_enable(lcd_fet);
+                       else
+                               regulator_disable(lcd_fet);
+
+                       regulator_put(lcd_fet);
+               }
+       }
+
+       if (!of_machine_is_compatible("google,snow")) {
+               /* reset */
+               gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
                mdelay(20);
-               gpio_free(EXYNOS5_GPX1(5));
-       } else {
-               /* fire nRESET on power off */
                gpio_set_value(EXYNOS5_GPX1(5), 0);
                mdelay(20);
                gpio_set_value(EXYNOS5_GPX1(5), 1);
                mdelay(20);
                gpio_free(EXYNOS5_GPX1(5));
+               mdelay(20);
        }
-       mdelay(20);
-       /*
-        * Request lcd_bl_en GPIO for smdk5250_bl_notify().
-        * TODO: Fix this so we are not at risk of requesting the GPIO
-        * multiple times, this should be done with device tree, and
-        * likely integrated into the plat-samsung/dev-backlight.c init.
-        */
-       gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
+
+
+       /* Turn on regulator for backlight */
+       if (of_machine_is_compatible("google,daisy") ||
+                       of_machine_is_compatible("google,snow")) {
+               struct regulator *backlight_fet;
+
+               backlight_fet = regulator_get(NULL, "vcd_led");
+               if (!IS_ERR(backlight_fet)) {
+                       if (power)
+                               regulator_enable(backlight_fet);
+                       else
+                               regulator_disable(backlight_fet);
+
+                       regulator_put(backlight_fet);
+               }
+               /* Wait 10 ms between regulator on and PWM start per spec */
+               mdelay(10);
+       }
+       exynos_wifi_bt_set_power(0, power);     /* TODO(sleffler) hack */
 }
 
 static int smdk5250_match_fb(struct plat_lcd_data *pd, struct fb_info *info)
@@ -87,14 +387,420 @@ static int smdk5250_match_fb(struct plat_lcd_data *pd, struct fb_info *info)
        return 0;
 }
 
-static struct plat_lcd_data smdk5250_mipi_lcd_data = {
-       .set_power      = mipi_lcd_set_power,
+static struct plat_lcd_data smdk5250_lcd_data = {
+       .set_power      = lcd_set_power,
        .match_fb       = smdk5250_match_fb,
 };
 
-static struct platform_device smdk5250_mipi_lcd = {
+static struct platform_device smdk5250_lcd = {
        .name                   = "platform-lcd",
-       .dev.platform_data      = &smdk5250_mipi_lcd_data,
+       .dev.platform_data      = &smdk5250_lcd_data,
+};
+
+static int smdk5250_bl_notify(struct device *unused, int brightness)
+{
+       /* manage lcd_bl_en signal */
+       if (brightness)
+               gpio_set_value(EXYNOS5_GPX3(0), 1);
+       else
+               gpio_set_value(EXYNOS5_GPX3(0), 0);
+
+       return brightness;
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk5250_bl_gpio_info = {
+       .no     = EXYNOS5_GPB2(0),
+       .func   = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk5250_bl_data = {
+       .pwm_period_ns  = 1000000,
+       .notify         = smdk5250_bl_notify,
+};
+
+struct platform_device exynos_device_md0 = {
+       .name = "exynos-mdev",
+       .id = 0,
+};
+
+struct platform_device exynos_device_md1 = {
+       .name = "exynos-mdev",
+       .id = 1,
+};
+
+struct platform_device exynos_device_md2 = {
+       .name = "exynos-mdev",
+       .id = 2,
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+       REGULATOR_SUPPLY("AVDD1", "1-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+       REGULATOR_SUPPLY("DCVDD", "1-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+       .constraints    = {
+               .name           = "AVDD1",
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+       .constraints    = {
+       .name                   = "DCVDD",
+               },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+       /* configure gpio1 function: 0x0001(Logic level input/output) */
+       .gpio_defaults[0] = 0x0001,
+       /* If the i2s0 and i2s2 is enabled simultaneously */
+       .gpio_defaults[7] = 0x8100, /* GPIO8  DACDAT3 in */
+       .gpio_defaults[8] = 0x0100, /* GPIO9  ADCDAT3 out */
+       .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3  out */
+       .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3   out */
+       .ldo[0] = { 0, &wm8994_ldo1_data },
+       .ldo[1] = { 0, &wm8994_ldo2_data },
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+       {
+               I2C_BOARD_INFO("wm8994", 0x1a),
+               .platform_data  = &wm8994_platform_data,
+       },
+};
+
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+       [0] = {
+               .line           = EXYNOS5_GPA2(5),
+               .fb_delay       = 0x2,
+       },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+       {
+               .modalias               = "spidev",
+               .platform_data          = NULL,
+               .max_speed_hz           = 10*1000*1000,
+               .bus_num                = 1,
+               .chip_select            = 0,
+               .mode                   = SPI_MODE_0,
+               .controller_data        = spi1_csi,
+       }
+};
+
+struct sysmmu_platform_data platdata_sysmmu_mfc_l = {
+       .dbgname = "mfc_l",
+       .clockname = "sysmmu",
+};
+
+struct sysmmu_platform_data platdata_sysmmu_mfc_r = {
+       .dbgname = "mfc_r",
+       .clockname = "sysmmu",
+};
+
+struct sysmmu_platform_data platdata_sysmmu_gsc = {
+       .dbgname = "gsc",
+       .clockname = "sysmmu",
+};
+
+struct sysmmu_platform_data platdata_sysmmu_g2d = {
+       .dbgname = "g2d",
+       .clockname = "sysmmu",
+};
+
+struct sysmmu_platform_data platdata_sysmmu_fimd = {
+       .dbgname = "fimd",
+       .clockname = "sysmmu",
+};
+
+struct sysmmu_platform_data platdata_sysmmu_tv = {
+       .dbgname = "tv",
+       .clockname = "sysmmu",
+};
+
+#ifdef CONFIG_VIDEO_FIMG2D4X
+static struct fimg2d_platdata fimg2d_data __initdata = {
+       .hw_ver         = 0x42,
+       .gate_clkname   = "fimg2d",
+};
+#endif
+
+static struct exynos4_ohci_platdata smdk5250_ohci_pdata = {
+       .phy_init = s5p_usb_phy_init,
+       .phy_exit = s5p_usb_phy_exit,
+};
+
+static struct s5p_ehci_platdata smdk5250_ehci_pdata = {
+       .phy_init = s5p_usb_phy_init,
+       .phy_exit = s5p_usb_phy_exit,
+};
+
+static struct dwc3_exynos_data smdk5250_xhci_pdata = {
+       .phy_type = S5P_USB_PHY_DRD,
+       .phy_init = s5p_usb_phy_init,
+       .phy_exit = s5p_usb_phy_exit,
+       .phyclk_switch = exynos5_dwc_phyclk_switch,
+       .use_ext_clk = s5p_usb_phy_use_ext_clk,
+};
+
+struct exynos_gpio_cfg {
+       unsigned int    addr;
+       unsigned int    num;
+       unsigned int    bit;
+};
+
+static const char *rclksrc[] = {
+       [0] = "busclk",
+       [1] = "i2sclk",
+};
+
+static struct video_info ptn3460_dp_config = {
+       .name                   = "eDP-LVDS NXP PTN3460",
+
+       .h_sync_polarity        = 0,
+       .v_sync_polarity        = 0,
+       .interlaced             = 0,
+
+       .color_space            = COLOR_RGB,
+       .dynamic_range          = VESA,
+       .ycbcr_coeff            = COLOR_YCBCR601,
+       .color_depth            = COLOR_8,
+
+       .link_rate              = LINK_RATE_2_70GBPS,
+       .lane_count             = LANE_COUNT2,
+};
+
+static struct video_info ps8622_dp_config = {
+       .name                   = "eDP-LVDS Parade PS8622",
+
+       .h_sync_polarity        = 0,
+       .v_sync_polarity        = 0,
+       .interlaced             = 0,
+
+       .color_space            = COLOR_RGB,
+       .dynamic_range          = VESA,
+       .ycbcr_coeff            = COLOR_YCBCR601,
+       .color_depth            = COLOR_8,
+
+       .link_rate              = LINK_RATE_2_70GBPS,
+       .lane_count             = LANE_COUNT1,
+};
+
+static struct exynos_dp_platdata smdk5250_dp_data = {
+       .video_info             = &ptn3460_dp_config,
+       .training_type          = SW_LINK_TRAINING,
+       .hpd_gpio               = -ENODEV,
+       .force_connected        = true,
+       .phy_init               = s5p_dp_phy_init,
+       .phy_exit               = s5p_dp_phy_exit,
+};
+
+#define S5P_PMU_DEBUG                          S5P_PMUREG(0x0A00)
+/* PMU_DEBUG bits [12:8] = 0x10000 selects XXTI clock source */
+#define PMU_DEBUG_XXTI                         (0x10 << 8)
+/* Mask bit[12:8] for xxti clock selection */
+#define PMU_DEBUG_CLKOUT_SEL_MASK              0x1f00
+
+static void __init enable_xclkout(void)
+{
+       unsigned int tmp;
+
+       tmp = readl(S5P_PMU_DEBUG);
+       tmp &= ~PMU_DEBUG_CLKOUT_SEL_MASK;
+       tmp |= PMU_DEBUG_XXTI;
+       writel(tmp, S5P_PMU_DEBUG);
+}
+
+static int exynos_cfg_i2s_gpio(struct platform_device *pdev)
+{
+       int id;
+       /* configure GPIO for i2s port */
+       struct exynos_gpio_cfg exynos5_cfg[3] = {
+               { EXYNOS5_GPZ(0),  7, S3C_GPIO_SFN(2) },
+               { EXYNOS5_GPB0(0), 5, S3C_GPIO_SFN(2) },
+               { EXYNOS5_GPB1(0), 5, S3C_GPIO_SFN(2) }
+       };
+
+       if (pdev->dev.of_node) {
+               id = of_alias_get_id(pdev->dev.of_node, "i2s");
+               if (id < 0)
+                       dev_err(&pdev->dev, "failed to get alias id:%d\n", id);
+       } else {
+               id = pdev->id;
+       }
+
+       if (id < 0 || id > 2) {
+               printk(KERN_ERR "Invalid Device %d\n", id);
+               return -EINVAL;
+       }
+
+       s3c_gpio_cfgpin_range(exynos5_cfg[id].addr,
+               exynos5_cfg[id].num, exynos5_cfg[id].bit);
+
+       return 0;
+}
+
+static struct s3c_audio_pdata i2sv5_pdata = {
+       .cfg_gpio = exynos_cfg_i2s_gpio,
+       .type = {
+               .i2s = {
+                       .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+                                        | QUIRK_NEED_RSTCLR,
+                       .src_clk = rclksrc,
+                       .idma_addr = EXYNOS4_AUDSS_INT_MEM,
+               },
+       },
+};
+
+/*
+ * Hack to do power-on sequence after the 32khz SLP_CLK is
+ * running as doing this entirely in the DT is problematic.
+ * We attach an auxdata record to dw_mmc2 with a set_power
+ * method that frobs the regulators.  This work is not board
+ * specific but must be done before the device is recognized
+ * so cannot go in the driver.
+ */
+static bool enable_mwi87xx(void)
+{
+       struct regulator *wifi_en, *wifi_rst;
+       bool ok;
+
+       wifi_en = regulator_get(NULL, "wifi-en");
+       wifi_rst = regulator_get(NULL, "wifi-rst-l");
+       ok = !IS_ERR(wifi_en) && !IS_ERR(wifi_rst);
+       if (ok) {
+               /*
+                * This assumes SLP_CLK is enabled and stable by the
+                * time we get here.  Also any delay required between
+                * RESETn and PDn should be set in startup-delay-us
+                * in the DT.
+                */
+               regulator_enable(wifi_rst);
+               regulator_enable(wifi_en);
+       }
+
+       if (!IS_ERR(wifi_rst))
+               regulator_put(wifi_rst);
+       if (!IS_ERR(wifi_en))
+               regulator_put(wifi_en);
+       return ok;
+}
+
+static void exynos_wifi_bt_set_power(u32 slot_id, u32 volt)
+{
+       if (volt == 0 || (!of_machine_is_compatible("google,snow") &&
+                         !of_machine_is_compatible("google,spring") &&
+                         !of_machine_is_compatible("google,daisy")))
+               return;
+       if (!enable_mwi87xx())
+               pr_err("%s: problem enabling WiFi+BT\n", __func__);
+       /* NB: bt-reset-l is tied to wifi-rst-l so BT should be ready too */
+}
+
+
+/* NTC Thermistor. Attached to S3C-ADC in some Samsung SoC Devices */
+struct s3c_adc_client *ntc_adc_clients[4];
+struct mutex ntc_adc_locks[] = {
+       __MUTEX_INITIALIZER(ntc_adc_locks[0]),
+       __MUTEX_INITIALIZER(ntc_adc_locks[1]),
+       __MUTEX_INITIALIZER(ntc_adc_locks[2]),
+       __MUTEX_INITIALIZER(ntc_adc_locks[3]),
+};
+
+static int __init s3c_adc_ntc_init(struct platform_device *pdev)
+{
+       struct s3c_adc_client *ntc_adc_client;
+
+       ntc_adc_client = s3c_adc_register(pdev, NULL, NULL, 0);
+       if (IS_ERR(ntc_adc_client))
+               return PTR_ERR(ntc_adc_client);
+
+       ntc_adc_clients[pdev->id] = ntc_adc_client;
+
+       return 0;
+}
+
+/*
+ * read_thermistor_uV: is a call back from ntc_thermistor driver.
+ * returns the temperature of the thermistor in celsius
+ */
+static int read_thermistor_uV(struct platform_device *pdev)
+{
+       static unsigned int ntc_adc_ports[] = {3, 4, 5, 6};
+       s64 converted;
+       unsigned int port = ntc_adc_ports[pdev->id];
+       struct s3c_adc_client *client = ntc_adc_clients[pdev->id];
+       struct ntc_thermistor_platform_data *pdata = pdev->dev.platform_data;
+       struct mutex *lock = ntc_adc_locks + pdev->id;
+       int ret;
+
+       /* Arrays are sized; make sure we haven't blown over */
+       BUG_ON(pdev->id >= ARRAY_SIZE(ntc_adc_locks));
+
+       /*
+        * s3c_adc_read() assumes two processes aren't using the same client
+        * at the same time (yes, it's a bad design), so grab a per-client
+        * mutex to ensure this is OK.
+        */
+       mutex_lock(lock);
+       ret = s3c_adc_read(client, port);
+       mutex_unlock(lock);
+
+       if (ret < 0) {
+               dev_warn(&pdev->dev, "Thermistor read err: 0x%08x\n", ret);
+               return ret;
+       }
+
+       converted = pdata->pullup_uV * (s64) ret;
+       converted >>= 12;
+
+       return (int) converted;
+}
+
+static struct ntc_thermistor_platform_data ntc_adc_pdata = {
+       .read_uV        = read_thermistor_uV,
+       .pullup_uV      = 1800000, /* voltage of vdd for ADC */
+       .pullup_ohm     = 47000,
+       .pulldown_ohm   = 0,
+       .connect        = NTC_CONNECTED_GROUND,
+};
+
+struct platform_device s3c_device_adc_ntc_thermistor0 = {
+       .name                   = "ncp15wb473",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data = &ntc_adc_pdata,
+       },
+};
+
+struct platform_device s3c_device_adc_ntc_thermistor1 = {
+       .name                   = "ncp15wb473",
+       .id                     = 1,
+       .dev                    = {
+       .platform_data = &ntc_adc_pdata,
+       },
+};
+
+struct platform_device s3c_device_adc_ntc_thermistor2 = {
+       .name                   = "ncp15wb473",
+       .id                     = 2,
+       .dev                    = {
+               .platform_data = &ntc_adc_pdata,
+       },
+};
+
+struct platform_device s3c_device_adc_ntc_thermistor3 = {
+       .name                   = "ncp15wb473",
+       .id                     = 3,
+       .dev                    = {
+               .platform_data = &ntc_adc_pdata,
+       },
 };
 
 /*
@@ -123,6 +829,26 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
                                "s3c2440-i2c.0", NULL),
        OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
                                "s3c2440-i2c.1", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(2),
+                               "s3c2440-i2c.2", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(3),
+                               "s3c2440-i2c.3", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(4),
+                               "s3c2440-i2c.4", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(5),
+                               "s3c2440-i2c.5", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(6),
+                               "s3c2440-i2c.6", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(7),
+                               "s3c2440-i2c.7", NULL),
+       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(8),
+                               "s3c2440-hdmiphy-i2c", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI0,
+                               "exynos4210-spi.0", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI1,
+                               "exynos4210-spi.1", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI2,
+                               "exynos4210-spi.2", NULL),
        OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12200000,
                                "dw_mmc.0", NULL),
        OF_DEV_AUXDATA("synopsis,dw-mshc-exynos5250", 0x12210000,
@@ -134,11 +860,100 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
        OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
        OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
        OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x10A60000,
+                               "s5p-sysmmu.2", &platdata_sysmmu_g2d),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11210000,
+                               "s5p-sysmmu.3", &platdata_sysmmu_mfc_l),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x11200000,
+                               "s5p-sysmmu.4", &platdata_sysmmu_mfc_r),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14640000,
+                               "s5p-sysmmu.27", &platdata_sysmmu_fimd),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x14650000,
+                               "s5p-sysmmu.28", &platdata_sysmmu_tv),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E80000,
+                               "s5p-sysmmu.23", &platdata_sysmmu_gsc),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13E90000,
+                               "s5p-sysmmu.24", &platdata_sysmmu_gsc),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EA0000,
+                               "s5p-sysmmu.25", &platdata_sysmmu_gsc),
+       OF_DEV_AUXDATA("samsung,s5p-sysmmu", 0x13EB0000,
+                               "s5p-sysmmu.26", &platdata_sysmmu_gsc),
+       OF_DEV_AUXDATA("samsung,exynos5-fb", 0x14400000,
+                               "exynos5-fb", &smdk5250_lcd1_pdata),
+       OF_DEV_AUXDATA("samsung,exynos5-mipi", 0x14500000,
+                               "s5p-mipi-dsim", &dsim_platform_data),
+       OF_DEV_AUXDATA("samsung,exynos5-dp", 0x145B0000,
+                               "s5p-dp", &smdk5250_dp_data),
+       OF_DEV_AUXDATA("samsung,s5p-mfc-v6", 0x11000000, "s5p-mfc-v6", NULL),
+       OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E00000,
+                               "exynos-gsc.0", NULL),
+       OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E10000,
+                               "exynos-gsc.1", NULL),
+       OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E20000,
+                               "exynos-gsc.2", NULL),
+       OF_DEV_AUXDATA("samsung,exynos-gsc", 0x13E30000,
+                               "exynos-gsc.3", NULL),
+#ifdef CONFIG_VIDEO_FIMG2D4X
+       OF_DEV_AUXDATA("samsung,s5p-g2d", 0x10850000,
+                               "s5p-g2d", &fimg2d_data),
+#endif
+       OF_DEV_AUXDATA("samsung,exynos-ohci", 0x12120000,
+                               "exynos-ohci", &smdk5250_ohci_pdata),
+       OF_DEV_AUXDATA("samsung,exynos-ehci", 0x12110000,
+                               "s5p-ehci", &smdk5250_ehci_pdata),
+       OF_DEV_AUXDATA("samsung,exynos-xhci", 0x12000000,
+                               "exynos-dwc3", &smdk5250_xhci_pdata),
+       OF_DEV_AUXDATA("samsung,i2s", 0x03830000,
+                               "samsung-i2s.0", &i2sv5_pdata),
+#ifdef CONFIG_DRM_EXYNOS_HDMI
+       OF_DEV_AUXDATA("samsung,exynos5-hdmi", 0x14530000,
+                               "exynos5-hdmi", &drm_hdmi_pdata),
+       OF_DEV_AUXDATA("samsung,s5p-mixer", 0x14450000,
+                               "s5p-mixer", &drm_mixer_pdata),
+#else
+       OF_DEV_AUXDATA("samsung,exynos5-hdmi", 0x14530000,
+                               "exynos5-hdmi", NULL),
+       OF_DEV_AUXDATA("samsung,s5p-mixer", 0x14450000,
+                               "s5p-mixer", NULL),
+#endif
        {},
 };
 
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+
+static struct platform_device exynos5_busfreq = {
+       .id = -1,
+       .name = "exynos-busfreq",
+};
+#endif
+
 static struct platform_device *smdk5250_devices[] __initdata = {
-       &smdk5250_mipi_lcd,
+       &smdk5250_lcd, /* for platform_lcd device */
+       &exynos_device_md0, /* for media device framework */
+       &exynos_device_md1, /* for media device framework */
+       &exynos_device_md2, /* for media device framework */
+       &samsung_asoc_dma,  /* for audio dma interface device */
+       &exynos_drm_device,
+#ifdef CONFIG_DRM_EXYNOS_HDMI
+       &exynos_drm_hdmi_device,
+#endif
+#ifdef CONFIG_BUSFREQ_OPP
+       &exynos5_busfreq,
+#endif
+};
+
+static struct platform_device *thermistor_devices[] __initdata = {
+       &s3c_device_adc_ntc_thermistor0,
+       &s3c_device_adc_ntc_thermistor1,
+       &s3c_device_adc_ntc_thermistor2,
+       &s3c_device_adc_ntc_thermistor3,
+};
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+       REGULATOR_SUPPLY("vddvario", "7000000.lan9215"),
+       REGULATOR_SUPPLY("vdd33a", "7000000.lan9215"),
 };
 
 static void __init exynos5250_dt_map_io(void)
@@ -147,15 +962,248 @@ static void __init exynos5250_dt_map_io(void)
        s3c24xx_init_clocks(24000000);
 }
 
+static unsigned long ramoops_dt_start, ramoops_dt_size;
+static int __init init_dt_scan_ramoops(unsigned long node, const char *uname,
+                                       int depth, void *data)
+{
+       __be32 *reg, *endp;
+       unsigned long l;
+
+       if (!of_flat_dt_is_compatible(node, "ramoops"))
+               return 0;
+
+       reg = of_get_flat_dt_prop(node, "reg", &l);
+       if (!reg)
+               return 0;
+       endp = reg + (l / sizeof(__be32));
+
+       /* This architecture uses single cells for address and size.
+        * Other architectures may differ. */
+       ramoops_dt_start = be32_to_cpu(reg[0]);
+       ramoops_dt_size = be32_to_cpu(reg[1]);
+       return 0;
+}
+
+static void __init exynos5_ramoops_reserve(void)
+{
+       unsigned long start, size;
+
+       of_scan_flat_dt(init_dt_scan_ramoops, NULL);
+
+       /* If necessary, lower start and raise size to align to 1M. */
+       start = round_down(ramoops_dt_start, SZ_1M);
+       size = ramoops_dt_size + ramoops_dt_start - start;
+       size = round_up(size, SZ_1M);
+
+       if (memblock_remove(start, size)) {
+               pr_err("Failed to remove ramoops %08lx@%08lx from memory\n",
+                       size, start);
+       } else {
+               pr_info("Ramoops: %08lx - %08lx\n", start, start + size - 1);
+       }
+}
+
+static void __init exynos5_reserve(void)
+{
+       /* required to have enough address range to remap the IOMMU
+        * allocated buffers */
+       init_consistent_dma_size(SZ_64M);
+
+       exynos5_ramoops_reserve();
+       bitfix_reserve();
+}
+
+static void s5p_tv_setup(void)
+{
+       /* direct HPD to HDMI chip */
+       gpio_request(EXYNOS5_GPX3(7), "hpd-plug");
+
+       gpio_direction_input(EXYNOS5_GPX3(7));
+       s3c_gpio_cfgpin(EXYNOS5_GPX3(7), S3C_GPIO_SFN(0x3));
+       s3c_gpio_setpull(EXYNOS5_GPX3(7), S3C_GPIO_PULL_NONE);
+}
+
+static void exynos5_i2c_setup(void)
+{
+       /* Setup the low-speed i2c controller interrupts */
+       writel(0x0, EXYNOS5_SYS_I2C_CFG);
+}
+
 static void __init exynos5250_dt_machine_init(void)
 {
-       if (of_machine_is_compatible("samsung,smdk5250"))
-               smsc911x_init(1);
+       struct device_node *srom_np, *np;
+
+       regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
+       /* Setup pins for any SMSC 911x controller on the SROMC bus */
+       srom_np = of_find_node_by_path("/sromc-bus");
+       if (!srom_np) {
+               printk(KERN_ERR "No /sromc-bus property.\n");
+               goto out;
+       }
+       for_each_child_of_node(srom_np, np) {
+               if (of_device_is_compatible(np, "smsc,lan9115")) {
+                       u32 reg;
+                       of_property_read_u32(np, "reg", &reg);
+                       smsc911x_init(reg);
+               }
+       }
+
+       /*
+        * Set the backlight on LCD_PWM pin only for boards not using the
+        * Parade eDP bridge which has an internal PWN for the backlight.
+        */
+       if (!of_find_compatible_node(NULL, NULL, "parade,ps8622")) {
+               if (of_machine_is_compatible("google,snow")) {
+                       smdk5250_bl_data.max_brightness = 2800;
+                       smdk5250_bl_data.dft_brightness = 2800;
+               }
+
+               /*
+                * Request lcd_bl_en GPIO for smdk5250_bl_notify().
+                * TODO: Fix this so we are not at risk of requesting the GPIO
+                * multiple times, this should be done with device tree, and
+                * likely integrated into the plat-samsung/dev-backlight.c init.
+                */
+               gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_HIGH,
+                                "lcd_bl_en");
+
+               samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
+       }
+
+       /*
+        * HACK ALERT! TODO: FIXME!
+        *
+        * We're going to hack in Daisy LCD info here for bringup purposes.
+        * Lots of things wrong with what we're doing here, but it works for
+        * bringup purposes.
+        */
+
+       if (of_machine_is_compatible("google,daisy")) {
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+               smdk5250_lcd1_pdata.panel.timing.xres = 1366;
+               smdk5250_lcd1_pdata.panel.timing.yres = 768;
+               smdk5250_lcd1_pdata.panel_type = MIPI_LCD;
+#else
+               smdk5250_fb_win0.win_mode.xres = 1366;
+               smdk5250_fb_win0.win_mode.yres = 768;
+               smdk5250_fb_win0.virtual_x = 1366;
+               smdk5250_fb_win0.virtual_y = 768 * 2;
+
+               smdk5250_fb_win1.win_mode.xres = 1366;
+               smdk5250_fb_win1.win_mode.yres = 768;
+               smdk5250_fb_win1.virtual_x = 1366;
+               smdk5250_fb_win1.virtual_y = 768 * 2;
+
+               smdk5250_fb_win2.win_mode.xres = 1366;
+               smdk5250_fb_win2.win_mode.yres = 768;
+               smdk5250_fb_win2.virtual_x = 1366;
+               smdk5250_fb_win2.virtual_y = 768 * 2;
+#endif
+               dsim_lcd_info.lcd_size.width = 1366;
+               dsim_lcd_info.lcd_size.height = 768;
+       } else if ((of_machine_is_compatible("google,snow")) ||
+                  (of_machine_is_compatible("google,spring"))) {
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+               smdk5250_lcd1_pdata.panel.timing = snow_fb_window;
+
+               smdk5250_lcd1_pdata.panel_type = DP_LCD;
+               smdk5250_lcd1_pdata.vidcon1 = 0;
+               smdk5250_lcd1_pdata.clock_rate =
+                       smdk5250_lcd1_pdata.panel.timing.pixclock;
+#endif
+       }
+
+       /* put the DP output configuration matching the eDP-LVDS bridge */
+       if (of_find_compatible_node(NULL, NULL, "nxp,ptn3460")) {
+               smdk5250_dp_data.video_info = &ptn3460_dp_config;
+       } else {
+               struct device_node *node =
+                       of_find_compatible_node(NULL, NULL, "parade,ps8622");
+               if (node) {
+                       smdk5250_dp_data.video_info = &ps8622_dp_config;
+                       smdk5250_dp_data.hpd_gpio =
+                               of_get_named_gpio(node, "hpd-gpio", 0);
+               }
+       }
+
+       if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
+               "HOST_VBUS_CONTROL")) {
+               printk(KERN_ERR "failed to request gpio_host_vbus\n");
+       } else {
+               s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+               gpio_free(EXYNOS5_GPX2(6));
+       }
+
+       exynos5_i2c_setup();
+
+       /*
+        * MAX77686 PMIC interrupt setup code
+        * TODO: Convert the device tree wakeup_int domain to support
+        * pull-up flags
+        */
+       s3c_gpio_setpull(EXYNOS5_GPX3(2), S3C_GPIO_PULL_NONE);
+
+       /*
+        * BIG HACK: The wm8994 is not device tree enabled apparently, so
+        * needs to be added manually.  ...but it's only on SMDK5250.
+        */
+       if (of_machine_is_compatible("samsung,smdk5250")) {
+               i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+       }
+
+       /* XCLKOUT needs to be moved over to the clock interface, but enable it
+        * here for now.
+        */
+       enable_xclkout();
+
+       if (gpio_request_one(EXYNOS5_GPA2(5), GPIOF_OUT_INIT_HIGH, "SPI1_CS")) {
+               printk(KERN_ERR "Spidev ChipSelect unavailable\n");
+       } else {
+               s3c_gpio_cfgpin(EXYNOS5_GPA2(5), S3C_GPIO_SFN(0x1));
+               s3c_gpio_setpull(EXYNOS5_GPA2(5), S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(EXYNOS5_GPA2(5), S5P_GPIO_DRVSTR_LV4);
+               spi_register_board_info(spi1_board_info,
+                                       ARRAY_SIZE(spi1_board_info));
+       }
 
        of_platform_populate(NULL, of_default_bus_match_table,
                                exynos5250_auxdata_lookup, NULL);
 
+#ifdef CONFIG_DRM_EXYNOS_FIMD
+       if (of_machine_is_compatible("google,snow"))
+               exynos_dp_gpio_setup_24bpp();
+       else
+               exynos_fimd_gpio_setup_24bpp();
+#endif
+       s5p_tv_setup();
+
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos5-adc");
+       if (np && of_device_is_available(np)) {
+               /* Enable power to ADC */
+               __raw_writel(0x1, S5P_ADC_PHY_CONTROL);
+
+               s3c_adc_ntc_init(&s3c_device_adc_ntc_thermistor0);
+               s3c_adc_ntc_init(&s3c_device_adc_ntc_thermistor1);
+               s3c_adc_ntc_init(&s3c_device_adc_ntc_thermistor2);
+               s3c_adc_ntc_init(&s3c_device_adc_ntc_thermistor3);
+
+               platform_add_devices(thermistor_devices,
+                                    ARRAY_SIZE(thermistor_devices));
+       }
+
+#ifdef CONFIG_BUSFREQ_OPP
+       dev_add(&busfreq, &exynos5_busfreq.dev);
+       ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos5_busfreq.dev);
+       ppmu_init(&exynos_ppmu[PPMU_DDR_C], &exynos5_busfreq.dev);
+       ppmu_init(&exynos_ppmu[PPMU_DDR_R1], &exynos5_busfreq.dev);
+       ppmu_init(&exynos_ppmu[PPMU_DDR_L], &exynos5_busfreq.dev);
+       ppmu_init(&exynos_ppmu[PPMU_RIGHT0_BUS], &exynos5_busfreq.dev);
+#endif
        platform_add_devices(smdk5250_devices, ARRAY_SIZE(smdk5250_devices));
+out:
+       of_node_put(srom_np);
+       return;
 }
 
 static char const *exynos5250_dt_compat[] __initdata = {
@@ -166,6 +1214,7 @@ static char const *exynos5250_dt_compat[] __initdata = {
 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
        /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
        .init_irq       = exynos5_init_irq,
+       .reserve        = exynos5_reserve,
        .map_io         = exynos5250_dt_map_io,
        .handle_irq     = gic_handle_irq,
        .init_machine   = exynos5250_dt_machine_init,