[coreboot-gerrit] Patch set updated for coreboot: 8247a4e GOOGLE/SNOW: get graphics working

David Hendricks (dhendrix@chromium.org) gerrit at coreboot.org
Fri Apr 19 21:44:17 CEST 2013


David Hendricks (dhendrix at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3116

-gerrit

commit 8247a4e950dd80328a95512be97d46728e7124a5
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Thu Apr 18 18:09:24 2013 -0700

    GOOGLE/SNOW: get graphics working
    
    draft patch, needs cleanup, but we've got pictures.
    
    Change-Id: I16e711c97e9d02c916824f621e2313297448732b
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 src/cpu/samsung/exynos5-common/exynos-fb.c  | 71 +++++++++++++++++++++++++----
 src/cpu/samsung/exynos5-common/s5p-dp-reg.c |  6 +++
 src/cpu/samsung/exynos5250/cpu.c            |  2 +-
 src/mainboard/google/snow/Kconfig           |  2 +
 src/mainboard/google/snow/chromeos.c        |  4 +-
 src/mainboard/google/snow/ramstage.c        | 46 ++++++++++++++++++-
 6 files changed, 118 insertions(+), 13 deletions(-)

diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c b/src/cpu/samsung/exynos5-common/exynos-fb.c
index 54a2d7a..1bb97a7 100644
--- a/src/cpu/samsung/exynos5-common/exynos-fb.c
+++ b/src/cpu/samsung/exynos5-common/exynos-fb.c
@@ -27,6 +27,7 @@
 #include <arch/io.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <console/console.h>
 #include <cpu/samsung/exynos5250/cpu.h>
 #include <cpu/samsung/exynos5250/power.h>
@@ -41,6 +42,24 @@
 #include "cpu/samsung/exynos5250/s5p-dp.h"
 #include "s5p-dp-core.h"
 
+/* useful information. Here is the rough outline of how we bring up the display.
+ *1. Upon power-on Sink generates a hot plug detection pulse thru HPD
+ *2. Source determines video mode by reading DPCD receiver capability field (DPCD 00000h to
+ *	0000Dh) including eDP CP capability register (DPCD 0000Dh)
+ *3. Sink replies DPCD receiver capability field.
+ *4. Source starts EDID read thru I2C-over-AUX
+ *5. Sink replies EDID thru I2C-over-AUX
+ *6. Source determines link configuration, such as MAX_LINK_RATE and
+ *	MAX_LANE_COUNT. Source also determines which type of eDP Authentication method
+ *	to use and writes DPCD link configuration field (DPCD 00100h to 0010Ah) including eDP
+ *	configuration set (DPCD 0010Ah).
+ *7. Source starts link training. Sink does clock recovery and equalization
+ *8. Source reads DPCD link status field (DPCD 00200h to 0020Bh)
+ *9. Sink replies DPCD link status field. If main link is not stable, Source repeats Step 7.
+ *10. Source sends MSA (Main Stream Attribute) data. Sink extracts video parameters and
+ *	recovers stream clock.
+ *11. Source sends video data
+ */
 /* To help debug any init errors here, define a list of possible errors */
 enum {
 	ERR_PLL_NOT_UNLOCKED = 2,
@@ -126,38 +145,51 @@ void fb_init(vidinfo_t *panel_info, void *lcdbase,
 {
 	unsigned int val;
 	u32 fbsize;
-	struct exynos5_fimd *fimd =
+	struct exynos5_fimd *fimd = //14400000
 		samsung_get_base_fimd();
-	struct exynos5_disp_ctrl *disp_ctrl =
+	struct exynos5_disp_ctrl *disp_ctrl = //14420000
 		samsung_get_base_disp_ctrl();
 
+	printk(BIOS_SPEW, "%s: fimd %p disp_ctrl %p\n", __func__, fimd, disp_ctrl);
+	printk(BIOS_SPEW, "pd %p\n", pd);
+	printk(BIOS_SPEW, "lcdbase %p\n", lcdbase);
+	printk(BIOS_SPEW, "pd->xres %d pd->yres %d\n", pd->xres, pd->yres);
+	printk(BIOS_SPEW, "Write %08x to %p\n", pd->ivclk | pd->fixvclk, &disp_ctrl->vidcon1);
 	writel(pd->ivclk | pd->fixvclk, &disp_ctrl->vidcon1);
 	val = ENVID_ON | ENVID_F_ON | (pd->clkval_f << CLKVAL_F_OFFSET);
+	printk(BIOS_SPEW, "Write %08x to fimd->vidcon0\n", val);
 	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);
+	printk(BIOS_SPEW, "Write %08x to %p\n", val, &disp_ctrl->vidtcon0);
 	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);
+	printk(BIOS_SPEW, "Write %08x to %p\n", val, &disp_ctrl->vidtcon1);
 	writel(val, &disp_ctrl->vidtcon1);
 
 	val = ((pd->xres - 1) << HOZVAL_OFFSET) |
 		((pd->yres - 1) << LINEVAL_OFFSET);
+	printk(BIOS_SPEW, "Write %08x to %p\n", val, &disp_ctrl->vidtcon2);
 	writel(val, &disp_ctrl->vidtcon2);
 
+	printk(BIOS_SPEW, "Write %08x to %p\n", (unsigned int)lcdbase, &fimd->vidw00add0b0);
 	writel((unsigned int)lcdbase, &fimd->vidw00add0b0);
 
 	fbsize = calc_fbsize(panel_info);
+	printk(BIOS_SPEW, "Write %08x to %p\n", (unsigned int)fbsize, &fimd->vidw00add1b0);
 	writel((unsigned int)lcdbase + fbsize, &fimd->vidw00add1b0);
 
+	printk(BIOS_SPEW, "Write %08x to %p\n", (unsigned int)pd->xres*2, &fimd->vidw00add0b0);
 	writel(pd->xres * 2, &fimd->vidw00add2);
 
 	val = ((pd->xres - 1) << OSD_RIGHTBOTX_F_OFFSET);
 	val |= ((pd->yres - 1) << OSD_RIGHTBOTY_F_OFFSET);
+	printk(BIOS_SPEW, "Write %08x to %p\n", val, &fimd->vidosd0b);
 	writel(val, &fimd->vidosd0b);
 	writel(pd->xres * pd->yres, &fimd->vidosd0c);
 
@@ -165,6 +197,7 @@ void fb_init(vidinfo_t *panel_info, void *lcdbase,
 
 	val = BPPMODE_F_RGB_16BIT_565 << BPPMODE_F_OFFSET;
 	val |= ENWIN_F_ENABLE | HALF_WORD_SWAP_EN;
+	printk(BIOS_SPEW, "Write %08x to %p\n", val, &fimd->wincon0);
 	writel(val, &fimd->wincon0);
 
 	/* DPCLKCON_ENABLE */
@@ -191,7 +224,7 @@ static int s5p_dp_config_video(struct s5p_dp_device *dp,
 			       struct video_info *video_info)
 {
 	int timeout = 0;
-	u32 start;
+	u32 start, end;
 	struct exynos5_dp *base = dp->base;
 
 	s5p_dp_config_video_slave_mode(dp, video_info);
@@ -206,16 +239,17 @@ static int s5p_dp_config_video(struct s5p_dp_device *dp,
 		return -ERR_PLL_NOT_UNLOCKED;
 	}
 
-	start = get_timer(0);
+	start = timer_us();
+	end = start + STREAM_ON_TIMEOUT*1000;
 	do {
 		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
 			timeout++;
 			break;
 		}
-	} while (get_timer(start) <= STREAM_ON_TIMEOUT);
+	} while (timer_us() < end);
 
 	if (!timeout) {
-		printk(BIOS_DEBUG, "Video Clock Not ok\n");
+		printk(BIOS_DEBUG, "Video Clock Not ok after %d microseconds waiting\n", timer_us() - start);
 		return -ERR_VIDEO_CLOCK_BAD;
 	}
 
@@ -255,7 +289,7 @@ static int s5p_dp_enable_rx_to_enhanced_mode(struct s5p_dp_device *dp)
 		printk(BIOS_DEBUG, "DPCD read error\n");
 		return -ERR_DPCD_READ_ERROR1;
 	}
-
+	/* let's not do this and see if it gets better */
 	if (s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
 				      DPCD_ENHANCED_FRAME_EN |
 				      (data & DPCD_LANE_COUNT_SET_MASK))) {
@@ -408,23 +442,25 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
 				   unsigned int max_lane,
 				   unsigned int max_rate)
 {
+	int pll_is_locked = 0;
 	u32 data;
 	u32 start;
 	int lane;
 	struct exynos5_dp *base = dp->base;
 
+	printk(BIOS_SPEW, "%s: start\n", __func__);
 	/* Stop Video */
 	clrbits_le32(&base->video_ctl_1, VIDEO_EN);
 
 	start = get_timer(0);
-	while (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+	while ((pll_is_locked = 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;
 		}
 	}
-
+	printk(BIOS_SPEW, "PLL is %slocked\n", pll_is_locked == PLL_LOCKED ? "": "un");
 	/* Reset Macro */
 	setbits_le32(&base->dp_phy_test, MACRO_RST);
 
@@ -448,6 +484,9 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
 	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);
 
+	printk(BIOS_SPEW, "%s: rate 0x%x, lane_count %d\n", __func__,
+		dp->link_train.link_rate, dp->link_train.lane_count);
+
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
 	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 		printk(BIOS_DEBUG, "Rx Max Link Rate is abnormal :%x !\n",
@@ -470,21 +509,27 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
 		dp->link_train.link_rate = max_rate;
 
 	/* Set link rate and count as you want to establish*/
+	printk(BIOS_SPEW, "Set link rate and count\n");
 	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. */
+	printk(BIOS_SPEW, "Set sink rate to D0\n");
 	s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
 				  DPCD_SET_POWER_STATE_D0);
 
 	/* Start HW link training */
+	printk(BIOS_SPEW, "Start Link hardware training\n");
 	writel(HW_TRAINING_EN, &base->dp_hw_link_training);
 
-	/* Wait unitl HW link training done */
+	/* Wait until HW link training done */
+	printk(BIOS_SPEW, "Wait until HW link training done\n");
 	s5p_dp_wait_hw_link_training_done(dp);
+	printk(BIOS_SPEW, "HW link training done\n");
 
 	/* Get hardware link training status */
 	data = readl(&base->dp_hw_link_training);
+	printk(BIOS_SPEW, "hardware link training status: 0x%08x\n", data);
 	if (data != 0) {
 		printk(BIOS_DEBUG, " H/W link training failure: 0x%x\n", data);
 		return -ERR_LINK_TRAINING_FAILURE;
@@ -497,6 +542,8 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
 
 	data = readl(&base->lane_count_set);
 	dp->link_train.lane_count = data;
+	printk(BIOS_SPEW, "Done training: Link bandwidth: 0x%x, lane_count: %d\n",
+		dp->link_train.link_rate, data);
 
 	return 0;
 }
@@ -533,12 +580,14 @@ int dp_controller_init(struct s5p_dp_device *dp_device)
 	/* Minimum delay after H/w Link training */
 	udelay(1000);
 
+	printk(BIOS_DEBUG, "call s5p_dp_enable_scramble\n");
 	ret = s5p_dp_enable_scramble(dp);
 	if (ret) {
 		printk(BIOS_DEBUG, "unable to set scramble mode\n");
 		return ret;
 	}
 
+	printk(BIOS_DEBUG, "call s5p_dp_enable_rx_to_enhanced_mode\n");
 	ret = s5p_dp_enable_rx_to_enhanced_mode(dp);
 	if (ret) {
 		printk(BIOS_DEBUG, "unable to set enhanced mode\n");
@@ -553,7 +602,9 @@ int dp_controller_init(struct s5p_dp_device *dp_device)
 	writel(dp->link_train.lane_count, &base->lane_count_set);
 	writel(dp->link_train.link_rate, &base->link_bw_set);
 
+	printk(BIOS_DEBUG, "call s5p_dp_init_video\n");
 	s5p_dp_init_video(dp);
+	printk(BIOS_DEBUG, "call s5p_dp_config_video\n");
 	ret = s5p_dp_config_video(dp, dp->video_info);
 	if (ret) {
 		printk(BIOS_DEBUG, "unable to config video\n");
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-reg.c b/src/cpu/samsung/exynos5-common/s5p-dp-reg.c
index 60e1398..49fe1cb 100644
--- a/src/cpu/samsung/exynos5-common/s5p-dp-reg.c
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-reg.c
@@ -102,6 +102,7 @@ unsigned int s5p_dp_get_pll_lock_status(struct s5p_dp_device *dp)
 	u32 reg;
 
 	reg = readl(&dp->base->dp_debug_ctl);
+	printk(BIOS_SPEW, "%s: reg is 0x%x, PLL_LOCK is 0x%x\n", __func__, reg, PLL_LOCK);
 	if (reg & PLL_LOCK)
 		return PLL_LOCKED;
 	else
@@ -351,11 +352,13 @@ int s5p_dp_is_slave_video_stream_clock_on(struct s5p_dp_device *dp)
 	u32 reg;
 	struct exynos5_dp *base = dp->base;
 
+	printk(BIOS_SPEW, "%s: sys_ctl_1 is %p\n", __func__, &base->sys_ctl_1);
 	reg = readl(&base->sys_ctl_1);
 	writel(reg, &base->sys_ctl_1);
 
 	reg = readl(&base->sys_ctl_1);
 
+	printk(BIOS_SPEW, "%s: sys_ctl_1 is %08x, DET_STA is 0x%x\n", __func__, reg, DET_STA);
 	if (!(reg & DET_STA))
 		return -1;
 
@@ -364,6 +367,7 @@ int s5p_dp_is_slave_video_stream_clock_on(struct s5p_dp_device *dp)
 
 	reg = readl(&base->sys_ctl_2);
 
+	printk(BIOS_SPEW, "%s: sys_ctl_2 is %08x, CHA_STA is 0x%x\n", __func__, reg, CHA_STA);
 	if (reg & CHA_STA) {
 		printk(BIOS_DEBUG, "Input stream clk is changing\n");
 		return -1;
@@ -452,6 +456,7 @@ void s5p_dp_config_video_slave_mode(struct s5p_dp_device *dp,
 	u32 reg;
 	struct exynos5_dp *base = dp->base;
 
+	printk(BIOS_SPEW, "%s: Start\n", __func__);
 	reg = readl(&base->func_en_1);
 	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
 	reg |= MASTER_VID_FUNC_EN_N;
@@ -474,6 +479,7 @@ void s5p_dp_config_video_slave_mode(struct s5p_dp_device *dp,
 
 	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
 	writel(reg, &base->soc_general_ctl);
+	printk(BIOS_SPEW, "%s: Done\n", __func__);
 }
 
 void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp)
diff --git a/src/cpu/samsung/exynos5250/cpu.c b/src/cpu/samsung/exynos5250/cpu.c
index 09b670e..b061433 100644
--- a/src/cpu/samsung/exynos5250/cpu.c
+++ b/src/cpu/samsung/exynos5250/cpu.c
@@ -32,7 +32,6 @@ static void exynos_displayport_init(device_t dev)
 	unsigned long int fb_size;
 	u32 lcdbase;
 
-	printk(BIOS_SPEW, "%s: dev 0x%p, conf 0x%p\n", __func__, dev, conf);
 	memset(&vi, 0, sizeof(vi));
 	memset(&panel, 0, sizeof(panel));
 
@@ -71,6 +70,7 @@ static void exynos_displayport_init(device_t dev)
 	mmio_resource(dev, 1, lcdbase/KiB, fb_size + (KiB-1)/KiB);
 	printk(BIOS_DEBUG,
 	       "Initializing exynos VGA, base %p\n",(void *)lcdbase);
+	memset((void *)lcdbase, 0x55, 0x100000);
 	ret = lcd_ctrl_init(&vi, &panel, (void *)lcdbase);
 }
 
diff --git a/src/mainboard/google/snow/Kconfig b/src/mainboard/google/snow/Kconfig
index 6d3d7c8..3df0b87 100644
--- a/src/mainboard/google/snow/Kconfig
+++ b/src/mainboard/google/snow/Kconfig
@@ -33,6 +33,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	select EXYNOS_DISPLAYPORT
 	select CHROMEOS
 	select DRIVER_TI_TPS65090
+        select MAINBOARD_HAS_NATIVE_VGA_INIT
+	select MAINBOARD_DO_NATIVE_VGA_INIT
 
 config MAINBOARD_DIR
 	string
diff --git a/src/mainboard/google/snow/chromeos.c b/src/mainboard/google/snow/chromeos.c
index 6e46d13..e3bab8b 100644
--- a/src/mainboard/google/snow/chromeos.c
+++ b/src/mainboard/google/snow/chromeos.c
@@ -98,7 +98,9 @@ void fill_lb_gpios(struct lb_gpios *gpios)
 
 int get_developer_mode_switch(void)
 {
-	return 0;
+	/* This should return 0, but we hardcode it to 1 to ensure coreboot
+	   draws the dev mode screen while we're working on this patch. */
+	return 1;
 }
 
 int get_recovery_mode_switch(void)
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index 1cd84e8..bd2a595 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -23,6 +23,7 @@
 #include <drivers/ti/tps65090/tps65090.h>
 #include <cbmem.h>
 #include <delay.h>
+#include <boot/coreboot_tables.h>
 #include <arch/cache.h>
 #include <arch/exception.h>
 #include <arch/gpio.h>
@@ -41,6 +42,46 @@
 #define DRAM_SIZE	CONFIG_DRAM_SIZE_MB
 #define DRAM_END	(DRAM_START + DRAM_SIZE)	/* plus one... */
 
+int vbe_mode_info_valid(void);
+int vbe_mode_info_valid(void)
+{
+	return 1;
+}
+
+void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
+void fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
+{
+	framebuffer->physical_address = (u32)cbmem_find(CBMEM_ID_CONSOLE);
+	printk(BIOS_SPEW, "%s: framebuffer->physical address is 0x%llx\n",
+			__func__, framebuffer->physical_address);
+/*
+        register "xres" = "1366"
+	register "yres" = "768"
+	register "bpp" = "16"
+	# complex magic timing!
+	register "clkval_f" = "2"
+	register "upper_margin" = "14"
+	register "lower_margin" = "3"
+        register "vsync" = "5"
+        register "left_margin" = "80"
+        register "right_margin" = "48"
+        register "hsync" = "32"
+*/
+	framebuffer->x_resolution = 1366;
+	framebuffer->y_resolution = 768;
+	framebuffer->bytes_per_line = 1366*2;
+	framebuffer->bits_per_pixel = 16;
+	framebuffer->red_mask_pos = 11;
+	framebuffer->red_mask_size = 5;
+	framebuffer->green_mask_pos = 6;
+	framebuffer->green_mask_size = 5;
+	framebuffer->blue_mask_pos = 0;
+	framebuffer->blue_mask_size = 5;
+	framebuffer->reserved_mask_pos = 0;
+	framebuffer->reserved_mask_size = 0;
+}
+
+
 void hardwaremain(int boot_complete);
 void main(void)
 {
@@ -221,6 +262,9 @@ static void mainboard_init(device_t dev)
 	} while (!exynos_dp_hotplug());
 
 	exynos_dp_bridge_setup();
+		snow_backlight_vdd();
+		snow_backlight_pwm();
+		snow_backlight_en();
 	for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
 		exynos_dp_bridge_init();
 		if (exynos_dp_hotplug()) {
@@ -229,7 +273,7 @@ static void mainboard_init(device_t dev)
 		}
 
 		if (dp_controller_init(&dp_device))
-			continue;
+			break; // continue;
 
 		udelay(LCD_T3_DELAY_MS * 1000);
 



More information about the coreboot-gerrit mailing list