Ronald G. Minnich ([email protected]) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/2570

-gerrit

commit f3086b25780a55e0af86a02ba667fbce2e9fe097
Author: Ronald G. Minnich <[email protected]>
Date:   Fri Mar 1 10:18:14 2013 -0800

    samsung/exynos5: add display port and framebuffer defines and 
initialization functions.
    
    These are essential functions for setting up the display port and
    framebuffer, and enable such things as aux channel communications.
    
    Change-Id: I56400ec9016ecb8716ec5a5dae41fdfbfff4817a
    Signed-off-by: Ronald G. Minnich <[email protected]>
---
 src/cpu/samsung/exynos5-common/Makefile.inc  |   2 +
 src/cpu/samsung/exynos5-common/exynos-fb.c   | 597 +++++++++++++++++++++++++++
 src/cpu/samsung/exynos5-common/s5p-dp-core.h | 256 ++++++++++++
 src/cpu/samsung/exynos5-common/s5p-dp-reg.c  | 481 +++++++++++++++++++++
 src/mainboard/google/snow/bootblock.c        |   4 +
 src/mainboard/google/snow/romstage.c         |  20 +-
 6 files changed, 1359 insertions(+), 1 deletion(-)

diff --git a/src/cpu/samsung/exynos5-common/Makefile.inc 
b/src/cpu/samsung/exynos5-common/Makefile.inc
index 47abe0f..6911b70 100644
--- a/src/cpu/samsung/exynos5-common/Makefile.inc
+++ b/src/cpu/samsung/exynos5-common/Makefile.inc
@@ -19,3 +19,5 @@ ramstage-y += pwm.c   # needed by timer.c
 ramstage-y += timer.c
 ramstage-y += gpio.c
 ramstage-y += i2c.c
+ramstage-y += s5p-dp-reg.c
+ramstage-y += exynos-fb.c
diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c 
b/src/cpu/samsung/exynos5-common/exynos-fb.c
new file mode 100644
index 0000000..0ff7c24
--- /dev/null
+++ b/src/cpu/samsung/exynos5-common/exynos-fb.c
@@ -0,0 +1,597 @@
+/*
+ * LCD driver for Exynos
+ *
+ * Copyright 2013 Google Inc.
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <arch/io.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console/console.h>
+#include <cpu/samsung/exynos5250/cpu.h>
+#include <cpu/samsung/exynos5250/power.h>
+#include <cpu/samsung/exynos5250/sysreg.h>
+#include <drivers/maxim/max77686/max77686.h>
+
+#include "device/i2c.h"
+#include "cpu/samsung/exynos5-common/i2c.h"
+#include "cpu/samsung/exynos5250/dsim.h"
+#include "cpu/samsung/exynos5250/fimd.h"
+
+#include "cpu/samsung/exynos5250/s5p-dp.h"
+#include "s5p-dp-core.h"
+
+/* To help debug any init errors here, define a list of possible errors */
+enum {
+       ERR_PLL_NOT_UNLOCKED = 2,
+       ERR_VIDEO_CLOCK_BAD,
+       ERR_VIDEO_STREAM_BAD,
+       ERR_DPCD_READ_ERROR1,           /* 5 */
+
+       ERR_DPCD_WRITE_ERROR1,
+       ERR_DPCD_READ_ERROR2,
+       ERR_DPCD_WRITE_ERROR2,
+       ERR_INVALID_LANE,
+       ERR_PLL_NOT_LOCKED,             /* 10 */
+
+       ERR_PRE_EMPHASIS_LEVELS,
+       ERR_LINK_RATE_ABNORMAL,
+       ERR_MAX_LANE_COUNT_ABNORMAL,
+       ERR_LINK_TRAINING_FAILURE,
+       ERR_MISSING_DP_BASE,            /* 15 */
+
+       ERR_NO_FDT_NODE,
+};
+/* ok, this is stupid, but we're going to leave the variables in here until we 
know it works.
+ * one cleanup task at a time.
+ */
+enum stage_t {
+       STAGE_START = 0,
+       STAGE_LCD_VDD,
+       STAGE_BRIDGE_SETUP,
+       STAGE_BRIDGE_INIT,
+       STAGE_BRIDGE_RESET,
+       STAGE_HOTPLUG,
+       STAGE_DP_CONTROLLER,
+       STAGE_BACKLIGHT_VDD,
+       STAGE_BACKLIGHT_PWM,
+       STAGE_BACKLIGHT_EN,
+       STAGE_DONE,
+};
+
+int lcd_line_length;
+int lcd_color_fg;
+int lcd_color_bg;
+
+void *lcd_base;                /* Start of framebuffer memory */
+void *lcd_console_address;     /* Start of console buffer */
+
+short console_col;
+short console_row;
+
+
+#ifdef CONFIG_EXYNOS_DISPLAYPORT
+static struct s5p_dp_device dp_device;
+
+#endif
+
+/* Bypass FIMD of DISP1_BLK */
+static void fimd_bypass(void)
+{
+#if 0
+       struct exynos5_sysreg *sysreg =
+               (struct exynos5_sysreg *)samsung_get_base_sysreg();
+
+       setbits_le32(&sysreg->disp1blk_cfg, FIMDBYPASS_DISP1);
+#endif
+}
+
+/* Calculate the size of Framebuffer from the resolution */
+static u32 calc_fbsize(vidinfo_t *panel_info)
+{
+       /* They had PAGE_SIZE here instead of 4096.
+        * but that's a totally arbitrary number -- everything nowadays
+        * has lots of page sizes.
+        * So keep it obvious.
+        */
+       return ALIGN((panel_info->vl_col * panel_info->vl_row *
+                     ((1<<panel_info->vl_bpix) / 8)), 4096);
+}
+
+/*
+ * Initialize display controller.
+ *
+ * @param lcdbase      pointer to the base address of framebuffer.
+ * @pd                 pointer to the main panel_data structure
+ */
+void fb_init(vidinfo_t *panel_info, void *lcdbase, struct exynos5_fimd_panel 
*pd)
+{
+       unsigned int val;
+       u32 fbsize;
+       struct exynos5_fimd *fimd =
+               (struct exynos5_fimd *)samsung_get_base_fimd();
+       struct exynos5_disp_ctrl *disp_ctrl =
+               (struct exynos5_disp_ctrl *)samsung_get_base_disp_ctrl();
+
+       writel(pd->ivclk | pd->fixvclk, &disp_ctrl->vidcon1);
+       val = ENVID_ON | ENVID_F_ON | (pd->clkval_f << CLKVAL_F_OFFSET);
+       writel(val, &fimd->vidcon0);
+
+       val = (pd->vsync << VSYNC_PULSE_WIDTH_OFFSET) |
+               (pd->lower_margin << V_FRONT_PORCH_OFFSET) |
+               (pd->upper_margin << V_BACK_PORCH_OFFSET);
+       writel(val, &disp_ctrl->vidtcon0);
+
+       val = (pd->hsync << HSYNC_PULSE_WIDTH_OFFSET) |
+               (pd->right_margin << H_FRONT_PORCH_OFFSET) |
+               (pd->left_margin << H_BACK_PORCH_OFFSET);
+       writel(val, &disp_ctrl->vidtcon1);
+
+       val = ((pd->xres - 1) << HOZVAL_OFFSET) |
+               ((pd->yres - 1) << LINEVAL_OFFSET);
+       writel(val, &disp_ctrl->vidtcon2);
+
+       writel((unsigned int)lcd_base, &fimd->vidw00add0b0);
+
+       fbsize = calc_fbsize(panel_info);
+       writel((unsigned int)lcd_base + fbsize, &fimd->vidw00add1b0);
+
+       writel(pd->xres * 2, &fimd->vidw00add2);
+
+       val = ((pd->xres - 1) << OSD_RIGHTBOTX_F_OFFSET);
+       val |= ((pd->yres - 1) << OSD_RIGHTBOTY_F_OFFSET);
+       writel(val, &fimd->vidosd0b);
+       writel(pd->xres * pd->yres, &fimd->vidosd0c);
+
+       setbits_le32(&fimd->shadowcon, CHANNEL0_EN);
+
+       val = BPPMODE_F_RGB_16BIT_565 << BPPMODE_F_OFFSET;
+       val |= ENWIN_F_ENABLE | HALF_WORD_SWAP_EN;
+       writel(val, &fimd->wincon0);
+
+       /* DPCLKCON_ENABLE */
+       writel(1 << 1, &fimd->dpclkcon);
+}
+
+#if 0
+static void exynos_fimd_disable(void)
+{
+       struct exynos5_fimd *fimd =
+               (struct exynos5_fimd *)samsung_get_base_fimd();
+
+       writel(0, &fimd->wincon0);
+       clrbits_le32(&fimd->shadowcon, CHANNEL0_EN);
+}
+#endif
+/*
+ * Configure DP in slave mode and wait for video stream.
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param video_info    pointer to main video_info structure.
+ * return              status
+ */
+static int s5p_dp_config_video(struct s5p_dp_device *dp,
+                              struct video_info *video_info)
+{
+       int timeout = 0;
+       u32 start;
+       struct exynos5_dp *base = dp->base;
+
+       s5p_dp_config_video_slave_mode(dp, video_info);
+
+       s5p_dp_set_video_color_format(dp, video_info->color_depth,
+                                     video_info->color_space,
+                                     video_info->dynamic_range,
+                                     video_info->ycbcr_coeff);
+
+       if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+               debug("PLL is not locked yet.\n");
+               return -ERR_PLL_NOT_UNLOCKED;
+       }
+
+       start = get_timer(0);
+       do {
+               if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
+                       timeout++;
+                       break;
+               }
+       } while (get_timer(start) <= STREAM_ON_TIMEOUT);
+
+       if (!timeout) {
+               debug("Video Clock Not ok\n");
+               return -ERR_VIDEO_CLOCK_BAD;
+       }
+
+       /* Set to use the register calculated M/N video */
+       s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
+
+       clrbits_le32(&base->video_ctl_10, FORMAT_SEL);
+
+       /* Disable video mute */
+       clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);
+
+       /* Configure video slave mode */
+       s5p_dp_enable_video_master(dp);
+
+       /* Enable video */
+       setbits_le32(&base->video_ctl_1, VIDEO_EN);
+       timeout = s5p_dp_is_video_stream_on(dp);
+
+       if (timeout) {
+               debug("Video Stream Not on\n");
+               return -ERR_VIDEO_STREAM_BAD;
+       }
+
+       return 0;
+}
+
+/*
+ * Set DP to enhanced mode. We use this for EVT1
+ * param dp    pointer to main s5p-dp structure
+ * return      status
+ */
+static int s5p_dp_enable_rx_to_enhanced_mode(struct s5p_dp_device *dp)
+{
+       u8 data;
+
+       if (s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data)) {
+               debug("DPCD read error\n");
+               return -ERR_DPCD_READ_ERROR1;
+       }
+
+       if (s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
+                                     DPCD_ENHANCED_FRAME_EN |
+                                     (data & DPCD_LANE_COUNT_SET_MASK))) {
+               debug("DPCD write error\n");
+               return -ERR_DPCD_WRITE_ERROR1;
+       }
+
+       return 0;
+}
+
+/*
+ * Enable scrambles mode. We use this for EVT1
+ * param dp    pointer to main s5p-dp structure
+ * return      status
+ */
+static int s5p_dp_enable_scramble(struct s5p_dp_device *dp)
+{
+       u8 data;
+       struct exynos5_dp *base = dp->base;
+
+       clrbits_le32(&base->dp_training_ptn_set, SCRAMBLING_DISABLE);
+
+       if (s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TRAINING_PATTERN_SET,
+                                      &data)) {
+               debug("DPCD read error\n");
+               return -ERR_DPCD_READ_ERROR2;
+       }
+
+       if (s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_TRAINING_PATTERN_SET,
+                                     (u8)(data & ~DPCD_SCRAMBLING_DISABLED))) {
+               debug("DPCD write error\n");
+               return -ERR_DPCD_WRITE_ERROR2;
+       }
+
+       return 0;
+}
+
+/*
+ * Reset DP and prepare DP for init training
+ * param dp    pointer to main s5p-dp structure
+ */
+static int s5p_dp_init_dp(struct s5p_dp_device *dp)
+{
+       int ret, i;
+       struct exynos5_dp *base = dp->base;
+
+       for (i = 0; i < DP_INIT_TRIES; i++) {
+               s5p_dp_reset(dp);
+
+               /* SW defined function Normal operation */
+               clrbits_le32(&base->func_en_1, SW_FUNC_EN_N);
+
+               ret = s5p_dp_init_analog_func(dp);
+               if (!ret)
+                       break;
+
+               udelay(5000);
+               debug("LCD retry init, attempt=%d ret=%d\n", i, ret);
+       }
+       if (i == DP_INIT_TRIES) {
+               debug("LCD initialization failed, ret=%d\n", ret);
+               return ret;
+       }
+
+       s5p_dp_init_aux(dp);
+
+       return ret;
+}
+
+/*
+ * Set pre-emphasis level
+ * param dp            pointer to main s5p-dp structure
+ * param pre_emphasis  pre-emphasis level
+ * param lane          lane number(0 - 3)
+ * return              status
+ */
+static int s5p_dp_set_lane_lane_pre_emphasis(struct s5p_dp_device *dp,
+                                            int pre_emphasis, int lane)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = pre_emphasis << PRE_EMPHASIS_SET_SHIFT;
+       switch (lane) {
+       case 0:
+               writel(reg, &base->ln0_link_trn_ctl);
+               break;
+       case 1:
+               writel(reg, &base->ln1_link_trn_ctl);
+               break;
+
+       case 2:
+               writel(reg, &base->ln2_link_trn_ctl);
+               break;
+
+       case 3:
+               writel(reg, &base->ln3_link_trn_ctl);
+               break;
+       default:
+               debug("%s: Invalid lane %d\n", __func__, lane);
+               return -ERR_INVALID_LANE;
+       }
+       return 0;
+}
+
+/*
+ * Read supported bandwidth type
+ * param dp            pointer to main s5p-dp structure
+ * param bandwidth     pointer to variable holding bandwidth type
+ */
+static void s5p_dp_get_max_rx_bandwidth(struct s5p_dp_device *dp,
+                                       u8 *bandwidth)
+{
+       u8 data;
+
+       /*
+        * For DP rev.1.1, Maximum link rate of Main Link lanes
+        * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+        */
+       s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data);
+       *bandwidth = data;
+}
+
+/*
+ * Reset DP and prepare DP for init training
+ * param dp            pointer to main s5p-dp structure
+ * param lane_count    pointer to variable holding no of lanes
+ */
+static void s5p_dp_get_max_rx_lane_count(struct s5p_dp_device *dp,
+                                        u8 *lane_count)
+{
+       u8 data;
+
+       /*
+        * For DP rev.1.1, Maximum number of Main Link lanes
+        * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
+        */
+       s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
+       *lane_count = data & DPCD_MAX_LANE_COUNT_MASK;
+}
+
+/*
+ * DP H/w Link Training. Set DPCD link rate and bandwidth.
+ * param dp            pointer to main s5p-dp structure
+ * param max_lane      No of lanes
+ * param max_rate      bandwidth
+ * return status
+ */
+static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
+                                  unsigned int max_lane,
+                                  unsigned int max_rate)
+{
+       u32 data;
+       u32 start;
+       int lane;
+       struct exynos5_dp *base = dp->base;
+
+       /* Stop Video */
+       clrbits_le32(&base->video_ctl_1, VIDEO_EN);
+
+       start = get_timer(0);
+       while (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+               if (get_timer(start) > PLL_LOCK_TIMEOUT) {
+                       /* Ignore this error, and try to continue */
+                       printk(BIOS_ERR, "PLL is not locked yet.\n");
+                       break;
+               }
+       }
+
+       /* Reset Macro */
+       setbits_le32(&base->dp_phy_test, MACRO_RST);
+
+       /* 10 us is the minimum reset time. */
+       udelay(10);
+
+       clrbits_le32(&base->dp_phy_test, MACRO_RST);
+
+       /* Set TX pre-emphasis to minimum */
+       for (lane = 0; lane < max_lane; lane++)
+               if (s5p_dp_set_lane_lane_pre_emphasis(dp,
+                                                     PRE_EMPHASIS_LEVEL_0, 
lane)) {
+                       debug("Unable to set pre emphasis level\n");
+                       return -ERR_PRE_EMPHASIS_LEVELS;
+               }
+
+       /* All DP analog module power up */
+       writel(0x00, &base->dp_phy_pd);
+
+       /* Initialize by reading RX's DPCD */
+       s5p_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
+       s5p_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
+
+       if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
+           (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+               debug("Rx Max Link Rate is abnormal :%x !\n",
+                     dp->link_train.link_rate);
+               /* Not Retrying */
+               return -ERR_LINK_RATE_ABNORMAL;
+       }
+
+       if (dp->link_train.lane_count == 0) {
+               debug("Rx Max Lane count is abnormal :%x !\n",
+                     dp->link_train.lane_count);
+               /* Not retrying */
+               return -ERR_MAX_LANE_COUNT_ABNORMAL;
+       }
+
+       /* Setup TX lane count & rate */
+       if (dp->link_train.lane_count > max_lane)
+               dp->link_train.lane_count = max_lane;
+       if (dp->link_train.link_rate > max_rate)
+               dp->link_train.link_rate = max_rate;
+
+       /* Set link rate and count as you want to establish*/
+       writel(dp->link_train.lane_count, &base->lane_count_set);
+       writel(dp->link_train.link_rate, &base->link_bw_set);
+
+       /* Set sink to D0 (Sink Not Ready) mode. */
+       s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
+                                 DPCD_SET_POWER_STATE_D0);
+
+       /* Start HW link training */
+       writel(HW_TRAINING_EN, &base->dp_hw_link_training);
+
+       /* Wait unitl HW link training done */
+       s5p_dp_wait_hw_link_training_done(dp);
+
+       /* Get hardware link training status */
+       data = readl(&base->dp_hw_link_training);
+       if (data != 0) {
+               debug(" H/W link training failure: 0x%x\n", data);
+               return -ERR_LINK_TRAINING_FAILURE;
+       }
+
+       /* Get Link Bandwidth */
+       data = readl(&base->link_bw_set);
+
+       dp->link_train.link_rate = data;
+
+       data = readl(&base->lane_count_set);
+       dp->link_train.lane_count = data;
+
+       return 0;
+}
+
+/*
+ * Initialize DP display
+ */
+int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
+{
+       int ret;
+       struct s5p_dp_device *dp = dp_device;
+       struct exynos5_dp *base;
+
+       //dp->base = (struct exynos5_dp *)addr;
+       /* yes. we're a snow. Yet somehow our config is from a development kit?
+        * This Must Change */
+       //dp->video_info = &smdk5250_dp_config;
+
+       clock_init_dp_clock();
+
+       power_enable_dp_phy();
+       ret = s5p_dp_init_dp(dp);
+       if (ret) {
+               debug("%s: Could not initialize dp\n", __func__);
+               return ret;
+       }
+
+       ret = s5p_dp_hw_link_training(dp, dp->video_info->lane_count,
+                                     dp->video_info->link_rate);
+       if (ret) {
+               debug("unable to do link train\n");
+               return ret;
+       }
+       /* Minimum delay after H/w Link training */
+       udelay(1000);
+
+       ret = s5p_dp_enable_scramble(dp);
+       if (ret) {
+               debug("unable to set scramble mode\n");
+               return ret;
+       }
+
+       ret = s5p_dp_enable_rx_to_enhanced_mode(dp);
+       if (ret) {
+               debug("unable to set enhanced mode\n");
+               return ret;
+       }
+
+
+       base = dp->base;
+       /* Enable enhanced mode */
+       setbits_le32(&base->sys_ctl_4, ENHANCED);
+
+       writel(dp->link_train.lane_count, &base->lane_count_set);
+       writel(dp->link_train.link_rate, &base->link_bw_set);
+
+       s5p_dp_init_video(dp);
+       ret = s5p_dp_config_video(dp, dp->video_info);
+       if (ret) {
+               debug("unable to config video\n");
+               return ret;
+       }
+
+       /*
+        * This delay is T3 in the LCD timing spec (defined as >200ms). We set
+        * this down to 60ms since that's the approximate maximum amount of time
+        * it'll take a bridge to start outputting LVDS data. The delay of
+        * >200ms is just a conservative value to avoid turning on the backlight
+        * when there's random LCD data on the screen. Shaving 140ms off the
+        * boot is an acceptable trade-off.
+        */
+       *wait_ms = 60;
+       return 0;
+}
+
+/**
+ * Init the LCD controller
+ *
+ * @param lcdbase      Base address of LCD frame buffer
+ * @return 0 if ok, -ve error code on error
+ */
+int lcd_ctrl_init(vidinfo_t *panel_info, struct exynos5_fimd_panel 
*panel_data, void *lcdbase)
+{
+       int ret = 0;
+
+       //vi->res = panel_info->vl_col;
+       //vi->yres = panel_info->vl_row;
+
+       fimd_bypass();
+       fb_init(panel_info, lcdbase, panel_data);
+
+       /* Enable flushing after LCD writes if requested */
+       // forget it. lcd_set_flush_dcache(1);
+       return ret;
+}
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-core.h 
b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
new file mode 100644
index 0000000..67c1990
--- /dev/null
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
@@ -0,0 +1,256 @@
+/*
+ * Header file for Samsung DP (Display Port) interface driver.
+ *
+ * Copyright 2013 Google Inc.
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _S5P_DP_CORE_H
+#define _S5P_DP_CORE_H
+
+#define STREAM_ON_TIMEOUT 100
+#define PLL_LOCK_TIMEOUT 10
+#define DP_INIT_TRIES 10
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 4
+
+/* Link tare type */
+enum link_rate {
+       LINK_RATE_1_62GBPS = 0x06,
+       LINK_RATE_2_70GBPS = 0x0a
+};
+
+/* Number of lanes supported */
+enum link_lane_count {
+       LANE_COUNT1 = 1,
+       LANE_COUNT2 = 2,
+       LANE_COUNT4 = 4
+};
+
+/* Pre emphasis level */
+enum pre_emphasis_level {
+       PRE_EMPHASIS_LEVEL_0,
+       PRE_EMPHASIS_LEVEL_1,
+       PRE_EMPHASIS_LEVEL_2,
+       PRE_EMPHASIS_LEVEL_3,
+};
+
+/* Type of color space */
+enum color_space {
+       COLOR_RGB,
+       COLOR_YCBCR422,
+       COLOR_YCBCR444
+};
+
+/* Video input Bit Per Color */
+enum color_depth {
+       COLOR_6,
+       COLOR_8,
+       COLOR_10,
+       COLOR_12
+};
+
+/* Type of YCbCr coefficient */
+enum color_coefficient {
+       COLOR_YCBCR601,
+       COLOR_YCBCR709
+};
+
+/* Color range */
+enum dynamic_range {
+       VESA,
+       CEA
+};
+
+/* Status of PLL clock */
+enum pll_status {
+       PLL_UNLOCKED,
+       PLL_LOCKED
+};
+
+/* To choose type of m_value */
+enum clock_recovery_m_value_type {
+       CALCULATED_M,
+       REGISTER_M
+};
+
+struct video_info {
+       enum color_space color_space;
+       enum dynamic_range dynamic_range;
+       enum color_coefficient ycbcr_coeff;
+       enum color_depth color_depth;
+
+       enum link_rate link_rate;
+       enum link_lane_count lane_count;
+
+       char *name;
+
+       unsigned int h_sync_polarity:1;
+       unsigned int v_sync_polarity:1;
+       unsigned int interlaced:1;
+};
+
+struct link_train {
+       u8 link_rate;
+       u8 lane_count;
+};
+
+struct s5p_dp_device {
+       unsigned int            irq;
+       struct exynos5_dp       *base;
+       struct video_info       *video_info;
+       struct link_train       link_train;
+};
+
+/* this struct is used by mainboards to pass mode info to the driver */
+typedef struct vidinfo {
+       u16 vl_col;
+       u16 vl_row;
+       u8 vl_bpix;
+       u16 *cmap;
+} vidinfo_t;
+
+/* s5p_dp_reg.c */
+
+/*
+ * Reset DP module
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+void s5p_dp_reset(struct s5p_dp_device *dp);
+/*
+ * Initialize DP to recieve video stream
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+void s5p_dp_init_video(struct s5p_dp_device *dp);
+/*
+ * Check whether PLL is locked
+ *
+ * param dp    pointer to main s5p-dp structure
+ * return      Lock status
+ */
+unsigned int s5p_dp_get_pll_lock_status(struct s5p_dp_device *dp);
+/*
+ * Initialize analog functions of DP
+ *
+ * param dp    pointer to main s5p-dp structure
+ * return      0 on success
+ */
+int s5p_dp_init_analog_func(struct s5p_dp_device *dp);
+/*
+ * Initialize DP for AUX transaction
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+void s5p_dp_init_aux(struct s5p_dp_device *dp);
+
+/*
+ * Start an AUX transaction.
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+int s5p_dp_start_aux_transaction(struct s5p_dp_device *dp);
+
+/*
+ * Write a byte to DPCD register
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param reg_addr      DPCD register to be written
+ * param data          byte data to be written
+ * return              write status
+ */
+int s5p_dp_write_byte_to_dpcd(struct s5p_dp_device *dp,
+                               unsigned int reg_addr,
+                               unsigned char data);
+/*
+ * Read a byte from DPCD register
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param reg_addr      DPCD register to read
+ * param data          read byte data
+ * return              read status
+ */
+int s5p_dp_read_byte_from_dpcd(struct s5p_dp_device *dp,
+                               unsigned int reg_addr,
+                               unsigned char *data);
+/*
+ * Initialize DP video functions
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+//void s5p_dp_init_video(struct s5p_dp_device *dp);
+
+/*
+ * Set color parameters for display
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param color_depth   Video input Bit Per Color
+ * param color_space   Colorimetric format of input video
+ * param dynamic_range VESA range or CEA range
+ * param coeff         YCbCr Coefficients of input video
+ */
+void s5p_dp_set_video_color_format(struct s5p_dp_device *dp,
+                                  unsigned int color_depth,
+                                  unsigned int color_space,
+                                  unsigned int dynamic_range,
+                                  unsigned int coeff);
+/*
+ * Check whether video clock is on
+ *
+ * param dp    pointer to main s5p-dp structure
+ * return      clock status
+ */
+int s5p_dp_is_slave_video_stream_clock_on(struct s5p_dp_device *dp);
+/*
+ * Check whether video clock is on
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param type          clock_recovery_m_value_type
+ * param m_value       to caluculate m_vid value
+ * param n_value       to caluculate n_vid value
+ */
+void s5p_dp_set_video_cr_mn(struct s5p_dp_device *dp,
+                       enum clock_recovery_m_value_type type,
+                       unsigned int m_value,
+                       unsigned int n_value);
+/*
+ * Set DP to video slave mode thereby enabling video master
+ *
+ * param dp    pointer to main s5p-dp structure
+ */
+void s5p_dp_enable_video_master(struct s5p_dp_device *dp);
+/*
+ * Check whether video stream is on
+ *
+ * param dp    pointer to main s5p-dp structure
+ * return      video stream status
+ */
+int s5p_dp_is_video_stream_on(struct s5p_dp_device *dp);
+/*
+ * Configure DP in slave mode
+ *
+ * param dp            pointer to main s5p-dp structure
+ * param video_info    pointer to main video_info structure.
+ */
+void s5p_dp_config_video_slave_mode(struct s5p_dp_device *dp,
+                       struct video_info *video_info);
+
+/*
+ * Wait unitl HW link training done
+ *
+ * param dp            pointer to main s5p-dp structure
+ */
+void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp);
+
+/* startup and init */
+void fb_init(vidinfo_t *panel_info, void *lcdbase, struct exynos5_fimd_panel 
*pd);
+int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms);
+int lcd_ctrl_init(vidinfo_t *panel_info, struct exynos5_fimd_panel 
*panel_data, void *lcdbase);
+#endif /* _S5P_DP_CORE_H */
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-reg.c 
b/src/cpu/samsung/exynos5-common/s5p-dp-reg.c
new file mode 100644
index 0000000..adb64a8
--- /dev/null
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-reg.c
@@ -0,0 +1,481 @@
+/*
+ * Samsung DP (Display port) register interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+#include <arch/io.h>
+#include <cpu/samsung/exynos5-common/clk.h>
+#include <cpu/samsung/exynos5250/cpu.h>
+#include <cpu/samsung/exynos5250/periph.h>
+#include <cpu/samsung/exynos5250/s5p-dp.h>
+#include "cpu/samsung/exynos5250/fimd.h"
+#include "s5p-dp-core.h"
+
+void s5p_dp_reset(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       writel(RESET_DP_TX, &base->dp_tx_sw_reset);
+
+       /* Stop Video */
+       clrbits_le32(&base->video_ctl_1, VIDEO_EN);
+       clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);
+
+       reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+               AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+               HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+       writel(reg, &base->func_en_1);
+
+       reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
+               SERDES_FIFO_FUNC_EN_N |
+               LS_CLK_DOMAIN_FUNC_EN_N;
+       writel(reg, &base->func_en_2);
+
+       udelay(20);
+
+       reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
+               LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
+
+       writel(reg, &base->lane_map);
+
+       writel(0x0, &base->sys_ctl_1);
+       writel(0x40, &base->sys_ctl_2);
+       writel(0x0, &base->sys_ctl_3);
+       writel(0x0, &base->sys_ctl_4);
+
+       writel(0x0, &base->pkt_send_ctl);
+       writel(0x0, &base->dp_hdcp_ctl);
+
+       writel(0x5e, &base->dp_hpd_deglitch_l);
+       writel(0x1a, &base->dp_hpd_deglitch_h);
+
+       writel(0x10, &base->dp_debug_ctl);
+
+       writel(0x0, &base->dp_phy_test);
+
+       writel(0x0, &base->dp_video_fifo_thrd);
+       writel(0x20, &base->dp_audio_margin);
+
+       writel(0x4, &base->m_vid_gen_filter_th);
+       writel(0x2, &base->m_aud_gen_filter_th);
+
+       writel(0x00000101, &base->soc_general_ctl);
+
+       /* Set Analog Parameters */
+       writel(0x10, &base->analog_ctl_1);
+       writel(0x0C, &base->analog_ctl_2);
+       writel(0x85, &base->analog_ctl_3);
+       writel(0x66, &base->pll_filter_ctl_1);
+       writel(0x0, &base->tx_amp_tuning_ctl);
+
+       /* Set interrupt pin assertion polarity as high */
+       writel(INT_POL0 | INT_POL1, &base->int_ctl);
+
+       /* Clear pending regisers */
+       writel(0xff, &base->common_int_sta_1);
+       writel(0x4f, &base->common_int_sta_2);
+       writel(0xe0, &base->common_int_sta_3);
+       writel(0xe7, &base->common_int_sta_4);
+       writel(0x63, &base->dp_int_sta);
+
+       /* 0:mask,1: unmask */
+       writel(0x00, &base->common_int_mask_1);
+       writel(0x00, &base->common_int_mask_2);
+       writel(0x00, &base->common_int_mask_3);
+       writel(0x00, &base->common_int_mask_4);
+       writel(0x00, &base->int_sta_mask);
+}
+
+unsigned int s5p_dp_get_pll_lock_status(struct s5p_dp_device *dp)
+{
+       u32 reg;
+
+       reg = readl(&dp->base->dp_debug_ctl);
+       if (reg & PLL_LOCK)
+               return PLL_LOCKED;
+       else
+               return PLL_UNLOCKED;
+}
+
+int s5p_dp_init_analog_func(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       u32 start;
+       struct exynos5_dp *base = dp->base;
+
+       writel(0x00, &base->dp_phy_pd);
+
+       reg = PLL_LOCK_CHG;
+       writel(reg, &base->common_int_sta_1);
+
+       clrbits_le32(&base->dp_debug_ctl, (F_PLL_LOCK | PLL_LOCK_CTRL));
+
+       /* Power up PLL */
+       if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+
+               clrbits_le32(&base->dp_pll_ctl, DP_PLL_PD);
+
+               start = get_timer(0);
+               while (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+                       if (get_timer(start) > PLL_LOCK_TIMEOUT) {
+                               debug("%s: PLL is not locked yet\n", __func__);
+                               return -1;
+                       }
+               }
+       }
+
+       /* Enable Serdes FIFO function and Link symbol clock domain module */
+       clrbits_le32(&base->func_en_2, (SERDES_FIFO_FUNC_EN_N |
+                               LS_CLK_DOMAIN_FUNC_EN_N | AUX_FUNC_EN_N));
+       return 0;
+}
+
+void s5p_dp_init_aux(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       /* Clear inerrupts related to AUX channel */
+       reg = RPLY_RECEIV | AUX_ERR;
+       writel(reg, &base->dp_int_sta);
+
+       /* Disable AUX channel module */
+       setbits_le32(&base->func_en_2, AUX_FUNC_EN_N);
+
+       /* Disable AUX transaction H/W retry */
+       reg = (3 & AUX_BIT_PERIOD_MASK) << AUX_BIT_PERIOD_SHIFT;
+       reg |= (0 & AUX_HW_RETRY_COUNT_MASK) << AUX_HW_RETRY_COUNT_SHIFT;
+       reg |= (AUX_HW_RETRY_INTERVAL_600_US << AUX_HW_RETRY_INTERVAL_SHIFT);
+       writel(reg, &base->aux_hw_retry_ctl) ;
+
+       /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
+       reg = DEFER_CTRL_EN;
+       reg |= (1 & DEFER_COUNT_MASK) << DEFER_COUNT_SHIFT;
+       writel(reg, &base->aux_ch_defer_dtl);
+
+       /* Enable AUX channel module */
+       clrbits_le32(&base->func_en_2, AUX_FUNC_EN_N);
+}
+
+int s5p_dp_start_aux_transaction(struct s5p_dp_device *dp)
+{
+       int reg;
+       struct exynos5_dp *base = dp->base;
+
+       /* Enable AUX CH operation */
+       setbits_le32(&base->aux_ch_ctl_2, AUX_EN);
+
+       /* Is AUX CH command reply received? */
+       reg = readl(&base->dp_int_sta);
+       while (!(reg & RPLY_RECEIV))
+               reg = readl(&base->dp_int_sta);
+
+       /* Clear interrupt source for AUX CH command reply */
+       writel(RPLY_RECEIV, &base->dp_int_sta);
+
+       /* Clear interrupt source for AUX CH access error */
+       reg = readl(&base->dp_int_sta);
+       if (reg & AUX_ERR) {
+               writel(AUX_ERR, &base->dp_int_sta);
+               return -1;
+       }
+
+       /* Check AUX CH error access status */
+       reg = readl(&base->dp_int_sta);
+       if ((reg & AUX_STATUS_MASK) != 0) {
+               debug("AUX CH error happens: %d\n\n",
+                       reg & AUX_STATUS_MASK);
+               return -1;
+       }
+
+       return 0;
+}
+
+int s5p_dp_write_byte_to_dpcd(struct s5p_dp_device *dp,
+                               unsigned int reg_addr,
+                               unsigned char data)
+{
+       u32 reg;
+       int i;
+       int retval;
+       struct exynos5_dp *base = dp->base;
+
+       for (i = 0; i < MAX_AUX_RETRY_COUNT; i++) {
+               /* Clear AUX CH data buffer */
+               writel(BUF_CLR, &base->buf_data_ctl);
+
+               /* Select DPCD device address */
+               reg = reg_addr >> AUX_ADDR_7_0_SHIFT;
+               reg &= AUX_ADDR_7_0_MASK;
+               writel(reg, &base->aux_addr_7_0);
+               reg = reg_addr >> AUX_ADDR_15_8_SHIFT;
+               reg &= AUX_ADDR_15_8_MASK;
+               writel(reg, &base->aux_addr_15_8);
+               reg = reg_addr >> AUX_ADDR_19_16_SHIFT;
+               reg &= AUX_ADDR_19_16_MASK;
+               writel(reg, &base->aux_addr_19_16);
+
+               /* Write data buffer */
+               reg = (unsigned int)data;
+               writel(reg, &base->buf_data_0);
+
+               /*
+                * Set DisplayPort transaction and write 1 byte
+                * If bit 3 is 1, DisplayPort transaction.
+                * If Bit 3 is 0, I2C transaction.
+                */
+               reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+               writel(reg, &base->aux_ch_ctl_1);
+
+               /* Start AUX transaction */
+               retval = s5p_dp_start_aux_transaction(dp);
+               if (retval == 0)
+                       break;
+               else
+                       debug("Aux Transaction fail!\n");
+       }
+
+       return retval;
+}
+
+int s5p_dp_read_byte_from_dpcd(struct s5p_dp_device *dp,
+                               unsigned int reg_addr,
+                               unsigned char *data)
+{
+       u32 reg;
+       int i;
+       int retval;
+       struct exynos5_dp *base = dp->base;
+
+       for (i = 0; i < MAX_AUX_RETRY_COUNT; i++) {
+               /* Clear AUX CH data buffer */
+               writel(BUF_CLR, &base->buf_data_ctl);
+
+               /* Select DPCD device address */
+               reg = reg_addr >> AUX_ADDR_7_0_SHIFT;
+               reg &= AUX_ADDR_7_0_MASK;
+               writel(reg, &base->aux_addr_7_0);
+               reg = reg_addr >> AUX_ADDR_15_8_SHIFT;
+               reg &= AUX_ADDR_15_8_MASK;
+               writel(reg, &base->aux_addr_15_8);
+               reg = reg_addr >> AUX_ADDR_19_16_SHIFT;
+               reg &= AUX_ADDR_19_16_MASK;
+               writel(reg, &base->aux_addr_19_16);
+
+               /*
+                * Set DisplayPort transaction and read 1 byte
+                * If bit 3 is 1, DisplayPort transaction.
+                * If Bit 3 is 0, I2C transaction.
+                */
+               reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+               writel(reg, &base->aux_ch_ctl_1);
+
+               /* Start AUX transaction */
+               retval = s5p_dp_start_aux_transaction(dp);
+               if (retval == 0)
+                       break;
+               else
+                       debug("Aux Transaction fail!\n");
+       }
+
+       /* Read data buffer */
+       if (!retval) {
+               reg = readl(&base->buf_data_0);
+               *data = (unsigned char)(reg & 0xff);
+       }
+
+       return retval;
+}
+
+void s5p_dp_init_video(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
+       writel(reg, &base->common_int_sta_1);
+
+       reg = 0x0;
+       writel(reg, &base->sys_ctl_1);
+
+       reg = (4 & CHA_CRI_MASK) << CHA_CRI_SHIFT;
+       reg |= CHA_CTRL;
+       writel(reg, &base->sys_ctl_2);
+
+       reg = 0x0;
+       writel(reg, &base->sys_ctl_3);
+}
+
+void s5p_dp_set_video_color_format(struct s5p_dp_device *dp,
+                                       unsigned int color_depth,
+                                       unsigned int color_space,
+                                       unsigned int dynamic_range,
+                                       unsigned int coeff)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       /* Configure the input color depth, color space, dynamic range */
+       reg = (dynamic_range << IN_D_RANGE_SHIFT) |
+               (color_depth << IN_BPC_SHIFT) |
+               (color_space << IN_COLOR_F_SHIFT);
+       writel(reg, &base->video_ctl_2);
+
+       /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
+       reg = readl(&base->video_ctl_3);
+       reg &= ~IN_YC_COEFFI_MASK;
+       if (coeff)
+               reg |= IN_YC_COEFFI_ITU709;
+       else
+               reg |= IN_YC_COEFFI_ITU601;
+       writel(reg, &base->video_ctl_3);
+}
+
+int s5p_dp_is_slave_video_stream_clock_on(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = readl(&base->sys_ctl_1);
+       writel(reg, &base->sys_ctl_1);
+
+       reg = readl(&base->sys_ctl_1);
+
+       if (!(reg & DET_STA))
+               return -1;
+
+       reg = readl(&base->sys_ctl_2);
+       writel(reg, &base->sys_ctl_2);
+
+       reg = readl(&base->sys_ctl_2);
+
+       if (reg & CHA_STA) {
+               debug("Input stream clk is changing\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+void s5p_dp_set_video_cr_mn(struct s5p_dp_device *dp,
+               enum clock_recovery_m_value_type type,
+               unsigned int m_value,
+               unsigned int n_value)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       if (type == REGISTER_M) {
+               setbits_le32(&base->sys_ctl_4, FIX_M_VID);
+
+               reg = m_value >> M_VID_0_VALUE_SHIFT;
+               writel(reg, &base->m_vid_0);
+
+               reg = (m_value >> M_VID_1_VALUE_SHIFT);
+               writel(reg, &base->m_vid_1);
+
+               reg = (m_value >> M_VID_2_VALUE_SHIFT);
+               writel(reg, &base->m_vid_2);
+
+               reg = n_value >> N_VID_0_VALUE_SHIFT;
+               writel(reg, &base->n_vid_0);
+
+               reg = (n_value >> N_VID_1_VALUE_SHIFT);
+               writel(reg, &base->n_vid_1);
+
+               reg = (n_value >> N_VID_2_VALUE_SHIFT);
+               writel(reg, &base->n_vid_2);
+       } else  {
+               clrbits_le32(&base->sys_ctl_4, FIX_M_VID);
+
+               writel(0x00, &base->n_vid_0);
+               writel(0x80, &base->n_vid_1);
+               writel(0x00, &base->n_vid_2);
+       }
+}
+
+void s5p_dp_enable_video_master(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = readl(&base->soc_general_ctl);
+       reg &= ~VIDEO_MODE_MASK;
+       reg |= VIDEO_MODE_SLAVE_MODE;
+       writel(reg, &base->soc_general_ctl);
+}
+
+int s5p_dp_is_video_stream_on(struct s5p_dp_device *dp)
+{
+       u32 reg, i = 0;
+       u32 start;
+       struct exynos5_dp *base = dp->base;
+
+       /* Wait for 4 VSYNC_DET interrupts */
+       start = get_timer(0);
+       do {
+               reg = readl(&base->common_int_sta_1);
+               if (reg & VSYNC_DET) {
+                       i++;
+                       writel(reg | VSYNC_DET, &base->common_int_sta_1);
+               }
+               if (i == 4)
+                       break;
+       } while (get_timer(start) <= STREAM_ON_TIMEOUT);
+
+       if (i != 4) {
+               debug("s5p_dp_is_video_stream_on timeout\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+void s5p_dp_config_video_slave_mode(struct s5p_dp_device *dp,
+                       struct video_info *video_info)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = readl(&base->func_en_1);
+       reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+       reg |= MASTER_VID_FUNC_EN_N;
+       writel(reg, &base->func_en_1);
+
+       reg = readl(&base->video_ctl_10);
+       reg &= ~INTERACE_SCAN_CFG;
+       reg |= (video_info->interlaced << 2);
+       writel(reg, &base->video_ctl_10);
+
+       reg = readl(&base->video_ctl_10);
+       reg &= ~VSYNC_POLARITY_CFG;
+       reg |= (video_info->v_sync_polarity << 1);
+       writel(reg, &base->video_ctl_10);
+
+       reg = readl(&base->video_ctl_10);
+       reg &= ~HSYNC_POLARITY_CFG;
+       reg |= (video_info->h_sync_polarity << 0);
+       writel(reg, &base->video_ctl_10);
+
+       reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
+       writel(reg, &base->soc_general_ctl);
+}
+
+void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp)
+{
+       u32 reg;
+       struct exynos5_dp *base = dp->base;
+
+       reg = readl(&base->dp_hw_link_training);
+       while (reg & HW_TRAINING_EN)
+               reg = readl(&base->dp_hw_link_training);
+}
diff --git a/src/mainboard/google/snow/bootblock.c 
b/src/mainboard/google/snow/bootblock.c
index 17a3267..b564938 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -30,6 +30,10 @@
 void bootblock_mainboard_init(void);
 void bootblock_mainboard_init(void)
 {
+#if 0
+       /* bang the reset on graphics. Fix this when we have suspend/resume. */
+       exynos_pinmux_config(PERIPH_ID_DPHPD, 1);
+#endif
        exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
 #if CONFIG_EARLY_CONSOLE
        exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
diff --git a/src/mainboard/google/snow/romstage.c 
b/src/mainboard/google/snow/romstage.c
index 7e1cd57..d1365ad 100644
--- a/src/mainboard/google/snow/romstage.c
+++ b/src/mainboard/google/snow/romstage.c
@@ -31,7 +31,8 @@
 #include <cpu/samsung/exynos5250/setup.h>
 #include <cpu/samsung/exynos5250/periph.h>
 #include <cpu/samsung/exynos5250/clock_init.h>
-
+#include <cpu/samsung/exynos5250/fimd.h>
+#include <cpu/samsung/exynos5-common/s5p-dp-core.h>
 #include <console/console.h>
 #include <arch/stages.h>
 
@@ -39,6 +40,14 @@
 
 #define MMC0_GPIO_PIN  (58)
 
+static uint16_t cmap_buffer[1 << 16];
+static vidinfo_t panel_info = {
+       .vl_col         = 1366,
+       .vl_row         = 768,
+       .vl_bpix        = 16,
+       .cmap           = cmap_buffer,
+};
+
 #if 0
 static int board_wakeup_permitted(void)
 {
@@ -70,6 +79,13 @@ static void initialize_s5p_mshc(void) {
        exynos_pinmux_config(PERIPH_ID_SDMMC2, 0);
 }
 
+static void graphics(void)
+{
+
+       exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
+       printk(BIOS_SPEW, "Panel_info %p\n", &panel_info);
+       /* not done now: reset graphics. We're not sure we need to on snow */
+}
 void main(void)
 {
        struct mem_timings *mem;
@@ -108,6 +124,8 @@ void main(void)
 
        initialize_s5p_mshc();
 
+       graphics();
+
        entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
        printk(BIOS_INFO, "entry is 0x%p, leaving romstage.\n", entry);
 

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to