[coreboot-gerrit] Patch set updated for coreboot: d302095 ARMv7: normalize ramstage code flow

Gabe Black (gabeblack@chromium.org) gerrit at coreboot.org
Tue Jul 9 22:43:52 CEST 2013


Gabe Black (gabeblack at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3638

-gerrit

commit d302095566e0ecd165017a7744517775e183f72c
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Thu May 9 16:16:13 2013 -0700

    ARMv7: normalize ramstage code flow
    
    In ram stage, all code flow should be tied to the resource allocator.
    Stuff that has to happen before everything else goes into the mainboard
    enable function in mainboard.c. This patch empties the main() wrapper
    around hardwaremain.c, allowing to get rid of this special case in the
    ARM port.
    
    Change-Id: Ide91a23f1043b64acf64471f180a2297f0f40d97
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
    Signed-off-by: Gabe Black <gabeblack at chromium.org>
---
 src/mainboard/emulation/qemu-armv7/ramstage.c |   2 -
 src/mainboard/google/snow/Makefile.inc        |   2 +-
 src/mainboard/google/snow/mainboard.c         | 279 ++++++++++++++++++++++----
 src/mainboard/google/snow/mainboard.h         |  16 --
 src/mainboard/google/snow/memory.c            |  64 +++++-
 src/mainboard/google/snow/ramstage.c          | 244 ----------------------
 6 files changed, 299 insertions(+), 308 deletions(-)

diff --git a/src/mainboard/emulation/qemu-armv7/ramstage.c b/src/mainboard/emulation/qemu-armv7/ramstage.c
index 5fce9fa..32e6cab 100644
--- a/src/mainboard/emulation/qemu-armv7/ramstage.c
+++ b/src/mainboard/emulation/qemu-armv7/ramstage.c
@@ -13,8 +13,6 @@
  * GNU General Public License for more details.
  */
 
-#include <console/console.h>
-
 void hardwaremain(void);
 void main(void)
 {
diff --git a/src/mainboard/google/snow/Makefile.inc b/src/mainboard/google/snow/Makefile.inc
index 84a8c05..190bb36 100644
--- a/src/mainboard/google/snow/Makefile.inc
+++ b/src/mainboard/google/snow/Makefile.inc
@@ -19,11 +19,11 @@
 
 bootblock-y += wakeup.c
 
-romstage-y += mainboard.c
 romstage-y += memory.c
 romstage-y += romstage.c
 romstage-y += wakeup.c
 
 # ramstage-y += ec.c
+ramstage-y += mainboard.c
 ramstage-y += ramstage.c
 ramstage-y += chromeos.c
diff --git a/src/mainboard/google/snow/mainboard.c b/src/mainboard/google/snow/mainboard.c
index 4a0d181..f4c8e6c 100644
--- a/src/mainboard/google/snow/mainboard.c
+++ b/src/mainboard/google/snow/mainboard.c
@@ -17,60 +17,255 @@
  * MA 02111-1307 USA
  */
 
-#include <stdlib.h>
-#include <gpio.h>
-#include <device/device.h>
 #include <console/console.h>
-
-#include <cpu/samsung/exynos5-common/gpio.h>
+#include <device/device.h>
+#include <device/i2c.h>
+#include <drivers/ti/tps65090/tps65090.h>
+#include <cbmem.h>
+#include <delay.h>
+#include <edid.h>
+#include <vbe.h>
+#include <boot/coreboot_tables.h>
+#include <arch/cache.h>
+#include <arch/exception.h>
+#include <arch/gpio.h>
+#include <cpu/samsung/exynos5-common/exynos-tmu.h>
+#include <cpu/samsung/exynos5250/clk.h>
+#include <cpu/samsung/exynos5250/cpu.h>
 #include <cpu/samsung/exynos5250/gpio.h>
+#include <cpu/samsung/exynos5250/power.h>
+
+#include <cpu/samsung/exynos5-common/i2c.h>
+#include <cpu/samsung/exynos5-common/s5p-dp-core.h>
+
+
+/* convenient shorthand (in MB) */
+#define DRAM_START	(CONFIG_SYS_SDRAM_BASE >> 20)
+#define DRAM_SIZE	CONFIG_DRAM_SIZE_MB
+#define DRAM_END	(DRAM_START + DRAM_SIZE)	/* plus one... */
+
+static struct edid snow_edid = {
+	.ha = 1366,
+	.va = 768,
+	.bpp = 16,
+};
+
+/* TODO: transplanted DP stuff, clean up once we have something that works */
+static enum exynos5_gpio_pin dp_pd_l = GPIO_Y25;	/* active low */
+static enum exynos5_gpio_pin dp_rst_l = GPIO_X15;	/* active low */
+static enum exynos5_gpio_pin dp_hpd = GPIO_X07;		/* active high */
+
+static void exynos_dp_bridge_setup(void)
+{
+	exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
+
+	gpio_set_value(dp_pd_l, 1);
+	gpio_cfg_pin(dp_pd_l, EXYNOS_GPIO_OUTPUT);
+	gpio_set_pull(dp_pd_l, EXYNOS_GPIO_PULL_NONE);
+
+	gpio_set_value(dp_rst_l, 0);
+	gpio_cfg_pin(dp_rst_l, EXYNOS_GPIO_OUTPUT);
+	gpio_set_pull(dp_rst_l, EXYNOS_GPIO_PULL_NONE);
+	udelay(10);
+	gpio_set_value(dp_rst_l, 1);
+}
+
+static void exynos_dp_bridge_init(void)
+{
+	/* De-assert PD (and possibly RST) to power up the bridge */
+	gpio_set_value(dp_pd_l, 1);
+	gpio_set_value(dp_rst_l, 1);
+
+	/*
+	 * We need to wait for 90ms after bringing up the bridge since
+	 * there is a phantom "high" on the HPD chip during its
+	 * bootup.  The phantom high comes within 7ms of de-asserting
+	 * PD and persists for at least 15ms.  The real high comes
+	 * roughly 50ms after PD is de-asserted. The phantom high
+	 * makes it hard for us to know when the NXP chip is up.
+	 */
+	udelay(90000);
+}
+
+static int exynos_dp_hotplug(void)
+{
+	/* Check HPD.  If it's high, we're all good. */
+	return gpio_get_value(dp_hpd) ? 0 : 1;
+}
+
+static void exynos_dp_reset(void)
+{
+	gpio_set_value(dp_pd_l, 0);
+	gpio_set_value(dp_rst_l, 0);
+	/* paranoid delay period (300ms) */
+	udelay(300 * 1000);
+}
+
+/*
+ * 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.
+ */
+#define LCD_T3_DELAY_MS	60
+
+#define LCD_T5_DELAY_MS	10
+#define LCD_T6_DELAY_MS	10
+
+static void snow_backlight_pwm(void)
+{
+	/*Configure backlight PWM as a simple output high (100% brightness) */
+	gpio_direction_output(GPIO_B20, 1);
+	udelay(LCD_T6_DELAY_MS * 1000);
+}
+
+static void snow_backlight_en(void)
+{
+	/* * Configure GPIO for LCD_BL_EN */
+	gpio_direction_output(GPIO_X30, 1);
+}
+
+#define TPS69050_BUS	4	/* Snow-specific */
 
-#include "mainboard.h"
-
-#define SNOW_BOARD_ID0_GPIO	88	/* GPD0, pin 0 */
-#define SNOW_BOARD_ID1_GPIO	89	/* GPD0, pin 1 */
-
-struct {
-	enum mvl3 id0, id1;
-	enum snow_board_config config;
-} snow_id_map[] = {
-	/*  ID0      ID1         config */
-	{ LOGIC_0, LOGIC_0, SNOW_CONFIG_SAMSUNG_MP },
-	{ LOGIC_0, LOGIC_1, SNOW_CONFIG_ELPIDA_MP },
-	{ LOGIC_1, LOGIC_0, SNOW_CONFIG_SAMSUNG_DVT },
-	{ LOGIC_1, LOGIC_1, SNOW_CONFIG_ELPIDA_DVT },
-	{ LOGIC_0, LOGIC_Z, SNOW_CONFIG_SAMSUNG_PVT },
-	{ LOGIC_1, LOGIC_Z, SNOW_CONFIG_ELPIDA_PVT },
-	{ LOGIC_Z, LOGIC_0, SNOW_CONFIG_SAMSUNG_MP },
-	{ LOGIC_Z, LOGIC_Z, SNOW_CONFIG_ELPIDA_MP },
-	{ LOGIC_Z, LOGIC_1, SNOW_CONFIG_RSVD },
+#define FET1_CTRL	0x0f
+#define FET6_CTRL	0x14
+
+static void snow_lcd_vdd(void)
+{
+	/* Enable FET6, lcd panel */
+	tps65090_fet_enable(TPS69050_BUS, FET6_CTRL);
+}
+
+static void snow_backlight_vdd(void)
+{
+	/* Enable FET1, backlight */
+	tps65090_fet_enable(TPS69050_BUS, FET1_CTRL);
+	udelay(LCD_T5_DELAY_MS * 1000);
+}
+
+//static struct video_info smdk5250_dp_config = {
+static struct video_info snow_dp_video_info = {
+	/* FIXME: fix video_info struct to use const for name */
+	.name			= (char *)"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,
 };
 
-int board_get_config(void)
+/* FIXME: move some place more appropriate */
+#define EXYNOS5250_DP1_BASE	0x145b0000
+#define SNOW_MAX_DP_TRIES	5
+
+/*
+ * This function disables the USB3.0 PLL to save power
+ */
+static void disable_usb30_pll(void)
 {
-	int i;
-	int id0, id1;
-	enum snow_board_config config = SNOW_CONFIG_UNKNOWN;
-
-	id0 = gpio_read_mvl3(SNOW_BOARD_ID0_GPIO);
-	id1 = gpio_read_mvl3(SNOW_BOARD_ID1_GPIO);
-	if (id0 < 0 || id1 < 0)
-		return -1;
-	printk(BIOS_DEBUG, "%s: id0: %u, id1: %u\n", __func__, id0, id1);
-
-	for (i = 0; i < ARRAY_SIZE(snow_id_map); i++) {
-		if (id0 == snow_id_map[i].id0 && id1 == snow_id_map[i].id1) {
-			config = snow_id_map[i].config;
-			break;
+	enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
+
+	gpio_direction_output(usb3_pll_l, 0);
+}
+
+/* this happens after cpu_init where exynos resources are set */
+static void mainboard_init(device_t dev)
+{
+	int dp_tries;
+	struct s5p_dp_device dp_device = {
+		.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
+		.video_info = &snow_dp_video_info,
+	};
+	void *fb_addr;
+
+	i2c_init(TPS69050_BUS, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+	i2c_init(7, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	tmu_init(&exynos5250_tmu_info);
+
+	/* Clock Gating all the unused IP's to save power */
+	clock_gate();
+
+	/* Disable USB3.0 PLL to save 250mW of power */
+	disable_usb30_pll();
+
+	fb_addr = cbmem_find(CBMEM_ID_CONSOLE);
+	set_vbe_mode_info_valid(&snow_edid, (uintptr_t)(fb_addr) + 64*KiB);
+
+	snow_lcd_vdd();
+	do {
+		udelay(50);
+	} while (!exynos_dp_hotplug());
+
+	exynos_dp_bridge_setup();
+	for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
+		exynos_dp_bridge_init();
+		if (exynos_dp_hotplug()) {
+			exynos_dp_reset();
+			continue;
 		}
+
+		if (dp_controller_init(&dp_device))
+			continue;
+
+		udelay(LCD_T3_DELAY_MS * 1000);
+
+		snow_backlight_vdd();
+		snow_backlight_pwm();
+		snow_backlight_en();
+		/* if we're here, we're successful */
+		break;
 	}
 
-	return config;
+	if (dp_tries > SNOW_MAX_DP_TRIES)
+		printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
+}
+
+static void mainboard_enable(device_t dev)
+{
+	dev->ops->init = &mainboard_init;
+
+	/* set up coreboot tables */
+	high_tables_size = CONFIG_COREBOOT_TABLES_SIZE;
+	high_tables_base = CONFIG_SYS_SDRAM_BASE +
+				((unsigned)CONFIG_DRAM_SIZE_MB << 20ULL) -
+				CONFIG_COREBOOT_TABLES_SIZE;
+	cbmem_init(high_tables_base, high_tables_size);
+
+	/* set up dcache and MMU */
+	/* FIXME: this should happen via resource allocator */
+	exynos5250_config_l2_cache();
+	mmu_init();
+	mmu_config_range(0, DRAM_START, DCACHE_OFF);
+	mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
+	mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
+	dcache_invalidate_all();
+	dcache_mmu_enable();
+
+	/* this is going to move, but we must have it now and we're
+	 * not sure where */
+	exception_init();
+
+	const unsigned epll_hz = 192000000;
+	const unsigned sample_rate = 48000;
+	const unsigned lr_frame_size = 256;
+	clock_epll_set_rate(epll_hz);
+	clock_select_i2s_clk_source();
+	clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
+
+	power_enable_xclkout();
 }
 
-#if 0
 struct chip_operations mainboard_ops = {
 	.name	= "Samsung/Google ARM Chromebook",
 	.enable_dev = mainboard_enable,
 };
-#endif
diff --git a/src/mainboard/google/snow/mainboard.h b/src/mainboard/google/snow/mainboard.h
index 5060b72..a91bed4 100644
--- a/src/mainboard/google/snow/mainboard.h
+++ b/src/mainboard/google/snow/mainboard.h
@@ -19,22 +19,6 @@
 
 #ifndef MAINBOARD_H
 #define MAINBOARD_H
-
-enum snow_board_config {
-	SNOW_CONFIG_UNKNOWN = -1,
-	SNOW_CONFIG_SAMSUNG_EVT,
-	SNOW_CONFIG_ELPIDA_EVT,
-	SNOW_CONFIG_SAMSUNG_DVT,
-	SNOW_CONFIG_ELPIDA_DVT,
-	SNOW_CONFIG_SAMSUNG_PVT,
-	SNOW_CONFIG_ELPIDA_PVT,
-	SNOW_CONFIG_SAMSUNG_MP,
-	SNOW_CONFIG_ELPIDA_MP,
-	SNOW_CONFIG_RSVD,
-};
-
-int board_get_config(void);
-
 enum {
 	SNOW_IS_NOT_WAKEUP,  // A normal boot (not suspend/resume).
 	SNOW_WAKEUP_DIRECT,  // A wake up event that can be resumed any time.
diff --git a/src/mainboard/google/snow/memory.c b/src/mainboard/google/snow/memory.c
index ba8c91f..0f72e69 100644
--- a/src/mainboard/google/snow/memory.c
+++ b/src/mainboard/google/snow/memory.c
@@ -23,13 +23,16 @@
 #include <stdlib.h>
 #include <console/console.h>
 
+#include <gpio.h>
+#include <cpu/samsung/exynos5-common/gpio.h>
+#include <cpu/samsung/exynos5250/gpio.h>
 #include <cpu/samsung/exynos5250/setup.h>
 #include <cpu/samsung/exynos5250/dmc.h>
 #include <cpu/samsung/exynos5250/clock_init.h>
 
 #include "mainboard.h"
 
-struct mem_timings mem_timings[] = {
+const struct mem_timings mem_timings[] = {
 	{
 		.mem_manuf = MEM_MANUF_ELPIDA,
 		.mem_type = DDR_MODE_DDR3,
@@ -450,6 +453,61 @@ struct mem_timings mem_timings[] = {
 	}
 };
 
+#define SNOW_BOARD_ID0_GPIO	88	/* GPD0, pin 0 */
+#define SNOW_BOARD_ID1_GPIO	89	/* GPD0, pin 1 */
+
+enum snow_board_config {
+	SNOW_CONFIG_UNKNOWN = -1,
+	SNOW_CONFIG_SAMSUNG_EVT,
+	SNOW_CONFIG_ELPIDA_EVT,
+	SNOW_CONFIG_SAMSUNG_DVT,
+	SNOW_CONFIG_ELPIDA_DVT,
+	SNOW_CONFIG_SAMSUNG_PVT,
+	SNOW_CONFIG_ELPIDA_PVT,
+	SNOW_CONFIG_SAMSUNG_MP,
+	SNOW_CONFIG_ELPIDA_MP,
+	SNOW_CONFIG_RSVD,
+};
+
+struct {
+	enum mvl3 id0, id1;
+	enum snow_board_config config;
+} snow_id_map[] = {
+	/*  ID0      ID1         config */
+	{ LOGIC_0, LOGIC_0, SNOW_CONFIG_SAMSUNG_MP },
+	{ LOGIC_0, LOGIC_1, SNOW_CONFIG_ELPIDA_MP },
+	{ LOGIC_1, LOGIC_0, SNOW_CONFIG_SAMSUNG_DVT },
+	{ LOGIC_1, LOGIC_1, SNOW_CONFIG_ELPIDA_DVT },
+	{ LOGIC_0, LOGIC_Z, SNOW_CONFIG_SAMSUNG_PVT },
+	{ LOGIC_1, LOGIC_Z, SNOW_CONFIG_ELPIDA_PVT },
+	{ LOGIC_Z, LOGIC_0, SNOW_CONFIG_SAMSUNG_MP },
+	{ LOGIC_Z, LOGIC_Z, SNOW_CONFIG_ELPIDA_MP },
+	{ LOGIC_Z, LOGIC_1, SNOW_CONFIG_RSVD },
+};
+
+static int board_get_config(void)
+{
+	int i;
+	int id0, id1;
+	enum snow_board_config config = SNOW_CONFIG_UNKNOWN;
+
+	id0 = gpio_read_mvl3(SNOW_BOARD_ID0_GPIO);
+	id1 = gpio_read_mvl3(SNOW_BOARD_ID1_GPIO);
+	if (id0 < 0 || id1 < 0)
+		return -1;
+	printk(BIOS_DEBUG, "%s: id0: %u, id1: %u\n", __func__, id0, id1);
+
+	for (i = 0; i < ARRAY_SIZE(snow_id_map); i++) {
+		if (id0 == snow_id_map[i].id0 && id1 == snow_id_map[i].id1) {
+			config = snow_id_map[i].config;
+			break;
+		}
+	}
+
+	return config;
+}
+
+
 struct mem_timings *get_mem_timings(void)
 {
 	int i;
@@ -457,7 +515,7 @@ struct mem_timings *get_mem_timings(void)
 	enum ddr_mode mem_type;
 	unsigned int frequency_mhz;
 	enum mem_manuf mem_manuf;
-	struct mem_timings *mem;
+	const struct mem_timings *mem;
 	
 	board_config = board_get_config();
 	switch (board_config) {
@@ -487,7 +545,7 @@ struct mem_timings *get_mem_timings(void)
 		if (mem->mem_type == mem_type &&
 			mem->frequency_mhz == frequency_mhz &&
 			mem->mem_manuf == mem_manuf)
-			return mem;
+			return (struct mem_timings *)mem;
 	}
 
 	return NULL;
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index 93979b2..6aa6082 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -17,252 +17,8 @@
  * MA 02111-1307 USA
  */
 
-#include <console/console.h>
-#include <device/device.h>
-#include <device/i2c.h>
-#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>
-#include <cpu/samsung/exynos5-common/exynos-tmu.h>
-#include <cpu/samsung/exynos5250/clk.h>
-#include <cpu/samsung/exynos5250/cpu.h>
-#include <cpu/samsung/exynos5250/gpio.h>
-#include <cpu/samsung/exynos5250/power.h>
-
-#include <cpu/samsung/exynos5-common/i2c.h>
-#include <cpu/samsung/exynos5-common/s5p-dp-core.h>
-
-
-/* convenient shorthand (in MB) */
-#define DRAM_START	(CONFIG_SYS_SDRAM_BASE >> 20)
-#define DRAM_SIZE	CONFIG_DRAM_SIZE_MB
-#define DRAM_END	(DRAM_START + DRAM_SIZE)	/* plus one... */
-
-
 void hardwaremain(void);
 void main(void)
 {
-	/* FIXME this should be moved elsewhere. We don't want ramstage.c */
-
-	/* set up coreboot tables */
-	high_tables_size = CONFIG_COREBOOT_TABLES_SIZE;
-	high_tables_base = CONFIG_SYS_SDRAM_BASE +
-				((unsigned)CONFIG_DRAM_SIZE_MB << 20ULL) -
-				CONFIG_COREBOOT_TABLES_SIZE;
-	cbmem_init(high_tables_base, high_tables_size);
-
-	/* set up dcache and MMU */
-	/* FIXME: this should happen via resource allocator */
-	exynos5250_config_l2_cache();
-	mmu_init();
-	mmu_config_range(0, DRAM_START, DCACHE_OFF);
-	mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
-	mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
-	dcache_invalidate_all();
-	dcache_mmu_enable();
-
-	/* this is going to move, but we must have it now and we're
-	 * not sure where */
-	exception_init();
-
-	const unsigned epll_hz = 192000000;
-	const unsigned sample_rate = 48000;
-	const unsigned lr_frame_size = 256;
-	clock_epll_set_rate(epll_hz);
-	clock_select_i2s_clk_source();
-	clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
-
-	power_enable_xclkout();
-
 	hardwaremain();
 }
-
-/* TODO: transplanted DP stuff, clean up once we have something that works */
-static enum exynos5_gpio_pin dp_pd_l = GPIO_Y25;	/* active low */
-static enum exynos5_gpio_pin dp_rst_l = GPIO_X15;	/* active low */
-static enum exynos5_gpio_pin dp_hpd = GPIO_X07;		/* active high */
-
-static void exynos_dp_bridge_setup(void)
-{
-	exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
-
-	gpio_set_value(dp_pd_l, 1);
-	gpio_cfg_pin(dp_pd_l, EXYNOS_GPIO_OUTPUT);
-	gpio_set_pull(dp_pd_l, EXYNOS_GPIO_PULL_NONE);
-
-	gpio_set_value(dp_rst_l, 0);
-	gpio_cfg_pin(dp_rst_l, EXYNOS_GPIO_OUTPUT);
-	gpio_set_pull(dp_rst_l, EXYNOS_GPIO_PULL_NONE);
-	udelay(10);
-	gpio_set_value(dp_rst_l, 1);
-}
-
-static void exynos_dp_bridge_init(void)
-{
-	/* De-assert PD (and possibly RST) to power up the bridge */
-	gpio_set_value(dp_pd_l, 1);
-	gpio_set_value(dp_rst_l, 1);
-
-	/*
-	 * We need to wait for 90ms after bringing up the bridge since
-	 * there is a phantom "high" on the HPD chip during its
-	 * bootup.  The phantom high comes within 7ms of de-asserting
-	 * PD and persists for at least 15ms.  The real high comes
-	 * roughly 50ms after PD is de-asserted. The phantom high
-	 * makes it hard for us to know when the NXP chip is up.
-	 */
-	udelay(90000);
-}
-
-static int exynos_dp_hotplug(void)
-{
-	/* Check HPD.  If it's high, we're all good. */
-	return gpio_get_value(dp_hpd) ? 0 : 1;
-}
-
-static void exynos_dp_reset(void)
-{
-	gpio_set_value(dp_pd_l, 0);
-	gpio_set_value(dp_rst_l, 0);
-	/* paranoid delay period (300ms) */
-	udelay(300 * 1000);
-}
-
-/*
- * 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.
- */
-#define LCD_T3_DELAY_MS	60
-
-#define LCD_T5_DELAY_MS	10
-#define LCD_T6_DELAY_MS	10
-
-static void snow_backlight_pwm(void)
-{
-	/*Configure backlight PWM as a simple output high (100% brightness) */
-	gpio_direction_output(GPIO_B20, 1);
-	udelay(LCD_T6_DELAY_MS * 1000);
-}
-
-static void snow_backlight_en(void)
-{
-	/* * Configure GPIO for LCD_BL_EN */
-	gpio_direction_output(GPIO_X30, 1);
-}
-
-#define TPS69050_BUS	4	/* Snow-specific */
-
-#define FET1_CTRL	0x0f
-#define FET6_CTRL	0x14
-
-static void snow_lcd_vdd(void)
-{
-	/* Enable FET6, lcd panel */
-	tps65090_fet_enable(TPS69050_BUS, FET6_CTRL);
-}
-
-static void snow_backlight_vdd(void)
-{
-	/* Enable FET1, backlight */
-	tps65090_fet_enable(TPS69050_BUS, FET1_CTRL);
-	udelay(LCD_T5_DELAY_MS * 1000);
-}
-
-//static struct video_info smdk5250_dp_config = {
-static struct video_info snow_dp_video_info = {
-	/* FIXME: fix video_info struct to use const for name */
-	.name			= (char *)"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,
-};
-
-/* FIXME: move some place more appropriate */
-#define EXYNOS5250_DP1_BASE	0x145b0000
-#define SNOW_MAX_DP_TRIES	5
-
-/*
- * This function disables the USB3.0 PLL to save power
- */
-static void disable_usb30_pll(void)
-{
-	enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
-
-	gpio_direction_output(usb3_pll_l, 0);
-}
-
-/* this happens after cpu_init where exynos resources are set */
-static void mainboard_init(device_t dev)
-{
-	int dp_tries;
-	struct s5p_dp_device dp_device = {
-		.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
-		.video_info = &snow_dp_video_info,
-	};
-
-	i2c_init(TPS69050_BUS, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-	i2c_init(7, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-
-	tmu_init(&exynos5250_tmu_info);
-
-	/* Clock Gating all the unused IP's to save power */
-	clock_gate();
-
-	/* Disable USB3.0 PLL to save 250mW of power */
-	disable_usb30_pll();
-
-	snow_lcd_vdd();
-	do {
-		udelay(50);
-	} while (!exynos_dp_hotplug());
-
-	exynos_dp_bridge_setup();
-	for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
-		exynos_dp_bridge_init();
-		if (exynos_dp_hotplug()) {
-			exynos_dp_reset();
-			continue;
-		}
-
-		if (dp_controller_init(&dp_device))
-			continue;
-
-		udelay(LCD_T3_DELAY_MS * 1000);
-
-		snow_backlight_vdd();
-		snow_backlight_pwm();
-		snow_backlight_en();
-		/* if we're here, we're successful */
-		break;
-	}
-
-	if (dp_tries > SNOW_MAX_DP_TRIES)
-		printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
-}
-
-static void mainboard_enable(device_t dev)
-{
-	dev->ops->init = &mainboard_init;
-}
-
-struct chip_operations mainboard_ops = {
-	.name	= "Samsung/Google ARM Chromebook",
-	.enable_dev = mainboard_enable,
-};



More information about the coreboot-gerrit mailing list