[coreboot] New patch to review for coreboot: 0ebb4e0 WIP: initial Snow board (ARM/Exynos 5250) support

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Sat Dec 8 02:34:04 CET 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2012

-gerrit

commit 0ebb4e0bc6edc42b257a1862b2e526621ccd7829
Author: Stefan Reinauer <stefan.reinauer at coreboot.org>
Date:   Fri Dec 7 17:32:24 2012 -0800

    WIP: initial Snow board (ARM/Exynos 5250) support
    
    NOTE: This patch series is based on
    http://review.coreboot.org/#/c/1679/31
    If 1679 is updated any further some of the patches in this series need
    updating, too.
    
    This pulls in lots of sources from U-Boot for the Snow board, which is
    used in Google's Chromebook based on the Exynos 5250 SoC from Samsung.
    This patch will likely be broken down significantly, I'm just
    uploading it as a draft for convenience.
    When compiling in the ChromeOS SDK chroot environment, use
    "CROSS_COMPILE=armv7a-cros-linux-gnueabi-". You may also use crossgcc
    with "-p armv7a-eabi".
    For now this patch also includes a config.snow file which sets the
    Kconfig options for Exynos5250 (cp config.snow .config &&
    make oldconfig && make).
    Overview of the code structure:
    - src/arch/armv7 - Common ARMv7 architecture files. This includes
      common headers and libraries.
    - src/cpu/samsung - Samsung SoC files, including Exynos5 (a Cortex-A15
      implementation). Since this is an SoC we'll forego the x86-style
      {north,south}bridge and cpu distinction. We may try to split some
      stuff out before the final version if prudent.
    - src/mainboard/google/snow - Mainboard directory (public name is
      "snow"). There are references to the Samsung SMDK5250 which is
      the development kit. Maybe we can add that as a separate board
      along with the Samsung Arndale (www.arndaleboard.org).
    TODO items:
    - The difference between romstage and ramstage is confusing (in
      context of this code). board_init_f() seems like it should be
      done in ramstage, since caches should be set up when start.S calls
      it.
    - Remove superfluous Linux code
    - Split out changes to console (e.g. src/console/Kconfig)
    - Incorporate dianders' DRAM fix from u-boot
    - Make sure CBFS works...
    - Do something about device tree / ACPI
    - (Re)move config.snow
    - Remove unneeded S5P stuff
    Get rid of linux include files. Merge asm/system.h into system.h,
    put in conditional __ASSEMBlY__ code.
    get rid of asm/. We're not linux and much of this junk is not needed.
    It builds without the asm/ directory.
    
    Change-Id: I6a6b94df095a15163c3392fcc1eaab3acbedd95b
    Signed-off-by: David Hendricks <dhendrix at chromium.org>
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 config.snow                              | 323 +++++++++++
 src/mainboard/Kconfig                    |  16 +
 src/mainboard/google/Kconfig             |  17 +
 src/mainboard/google/snow/Kconfig        | 162 ++++++
 src/mainboard/google/snow/Makefile.inc   |  36 ++
 src/mainboard/google/snow/board.h        |  33 ++
 src/mainboard/google/snow/devicetree.cb  |   7 +
 src/mainboard/google/snow/mainboard.c    | 943 +++++++++++++++++++++++++++++++
 src/mainboard/google/snow/romstage.c     | 291 ++++++++++
 src/mainboard/google/snow/smdk5250_spl.c | 123 ++++
 10 files changed, 1951 insertions(+)

diff --git a/config.snow b/config.snow
new file mode 100644
index 0000000..2aaae18
--- /dev/null
+++ b/config.snow
@@ -0,0 +1,323 @@
+#
+# Automatically generated make config: don't edit
+# coreboot version: 4.0-3132-g0af95ea
+# Tue Dec  4 14:41:24 2012
+#
+
+#
+# General setup
+#
+# CONFIG_EXPERT is not set
+CONFIG_LOCALVERSION=""
+CONFIG_CBFS_PREFIX="fallback"
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_SCANBUILD_ENABLE is not set
+# CONFIG_CCACHE is not set
+# CONFIG_USE_OPTION_TABLE is not set
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+# CONFIG_EARLY_CBMEM_INIT is not set
+# CONFIG_USE_BLOBS is not set
+# CONFIG_REQUIRES_BLOB is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_ADVANTECH is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+# CONFIG_VENDOR_ARIMA is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASI is not set
+# CONFIG_VENDOR_ASROCK is not set
+# CONFIG_VENDOR_ASUS is not set
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AXUS is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_EAGLELION is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+CONFIG_VENDOR_GOOGLE=y
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IBM is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+# CONFIG_VENDOR_LENOVO is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NEWISYS is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_TECHNOLOGIC is not set
+# CONFIG_VENDOR_TELEVIDEO is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="google/snow"
+CONFIG_MAINBOARD_PART_NUMBER="SNOW"
+CONFIG_MAINBOARD_VENDOR="Samsung"
+CONFIG_MAX_CPUS=2
+CONFIG_RAMTOP=0x40100000
+CONFIG_HEAP_SIZE=0x4000
+CONFIG_RAMBASE=0x40000000
+CONFIG_WARNINGS_ARE_ERRORS=y
+# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set
+# CONFIG_VGA_BIOS is not set
+# CONFIG_CONSOLE_POST is not set
+# CONFIG_PCI_ROM_RUN is not set
+CONFIG_ACPI_SSDTX_NUM=0
+CONFIG_BOARD_GOOGLE_SNOW=y
+CONFIG_SPL_TEXT_BASE=0x02023400
+CONFIG_SPL_MAX_SIZE=0x3800
+CONFIG_DRAM_SIZE_MB=2048
+CONFIG_NR_DRAM_BANKS=1
+# CONFIG_CONSOLE_SERIAL_UART0 is not set
+# CONFIG_CONSOLE_SERIAL_UART1 is not set
+# CONFIG_CONSOLE_SERIAL_UART2 is not set
+CONFIG_CONSOLE_SERIAL_UART3=y
+CONFIG_CONSOLE_SERIAL_UART_ADDRESS=0x12c30000
+CONFIG_SYS_I2C_SPEED=100000
+CONFIG_SYS_I2C_SLAVE=0x0
+CONFIG_I2C_MULTI_BUS=y
+CONFIG_VDD_ARM_MV=1300
+CONFIG_VDD_INT_UV=1012500
+CONFIG_VDD_MIF_MV=1000
+CONFIG_VDD_G3D_MV=1200
+CONFIG_VDD_LDO2_MV=1500
+CONFIG_VDD_LDO3_MV=1800
+CONFIG_VDD_LDO5_MV=1800
+CONFIG_VDD_LDO10_MV=1800
+# CONFIG_MMCONF_SUPPORT_DEFAULT is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_IOAPIC is not set
+CONFIG_TTYS0_BAUD=115200
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+CONFIG_MAXIMUM_CONSOLE_LOGLEVEL=8
+# CONFIG_CONSOLE_SERIAL8250 is not set
+# CONFIG_USBDEBUG is not set
+CONFIG_BOARD_ROMSIZE_KB_4096=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_4096=y
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=4096
+CONFIG_ROM_SIZE=0x400000
+CONFIG_CACHE_ROM_SIZE=0x400000
+# CONFIG_ARCH_X86 is not set
+# CONFIG_ARCH_ARM is not set
+CONFIG_ARCH_ARMV7=y
+CONFIG_MAX_REBOOT_CNT=3
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+
+#
+# Architecture (armv7)
+#
+CONFIG_SPL_BUILD=y
+# CONFIG_EABI_COMPAT is not set
+CONFIG_ARM_BOOTBLOCK_SIMPLE=y
+# CONFIG_ARM_BOOTBLOCK_NORMAL is not set
+CONFIG_ARM_DCACHE_POLICY_WRITEBACK=y
+# CONFIG_ARM_DCACHE_POLICY_WRITETHROUGH is not set
+
+#
+# Chipset
+#
+
+#
+# CPU
+#
+CONFIG_CPU_SAMSUNG_EXYNOS=y
+CONFIG_CPU_SAMSUNG_EXYNOS5=y
+# CONFIG_SKIP_LOWLEVEL_INIT is not set
+CONFIG_IRAM_BOTTOM=0x02020000
+CONFIG_IRAM_TOP=0x02077fff
+CONFIG_SYS_INIT_SP_ADDR=0x0204F800
+CONFIG_IRAM_STACK=0x0204F800
+CONFIG_XIP_ROM_SIZE=0x20000
+# CONFIG_EXYNOS_ACE_SHA is not set
+# CONFIG_SATA_AHCI is not set
+CONFIG_SYS_TEXT_BASE=0x43e00000
+CONFIG_SYS_SDRAM_BASE=0x40000000
+CONFIG_HAVE_INIT_TIMER=y
+CONFIG_HIGH_SCRATCH_MEMORY_SIZE=0x0
+# CONFIG_CPU_MICROCODE_IN_CBFS is not set
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+
+#
+# Northbridge
+#
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_CBFS_SIZE=0x400000
+
+#
+# Southbridge
+#
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+# CONFIG_SPI_FLASH is not set
+
+#
+# Super I/O
+#
+
+#
+# Embedded Controllers
+#
+
+#
+# Devices
+#
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+# CONFIG_PCI is not set
+# CONFIG_PCIEXP_COMMON_CLOCK is not set
+# CONFIG_PCIEXP_ASPM is not set
+CONFIG_PCI_BUS_SEGN_BITS=0
+
+#
+# VGA BIOS
+#
+
+#
+# Generic Drivers
+#
+# CONFIG_IPMI_KCS is not set
+# CONFIG_DRIVERS_OXFORD_OXPCIE is not set
+# CONFIG_RTL8168_ROM_DISABLE is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+CONFIG_DRIVER_MAXIM_77686=y
+# CONFIG_MMCONF_SUPPORT is not set
+
+#
+# Console
+#
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_CONSOLE_SERIAL8250MEM is not set
+CONFIG_CONSOLE_SERIAL_NONSTANDARD_MEM=y
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+# CONFIG_HAVE_USBDEBUG is not set
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_8=y
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_MAXIMUM_CONSOLE_LOGLEVEL_0 is not set
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_CONSOLE_LOGBUF is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_IO_POST is not set
+CONFIG_HAVE_UART_IO_MAPPED=y
+CONFIG_HAVE_UART_MEMORY_MAPPED=y
+# CONFIG_HAVE_ACPI_RESUME is not set
+# CONFIG_HAVE_ACPI_SLIC is not set
+# CONFIG_HAVE_HARD_RESET is not set
+# CONFIG_HAVE_OPTION_TABLE is not set
+# CONFIG_PIRQ_ROUTE is not set
+# CONFIG_HAVE_SMI_HANDLER is not set
+# CONFIG_PCI_IO_CFG_EXT is not set
+# CONFIG_USE_WATCHDOG_ON_BOOT is not set
+# CONFIG_VGA is not set
+# CONFIG_GFXUMA is not set
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# System tables
+#
+CONFIG_WRITE_HIGH_TABLES=y
+CONFIG_MULTIBOOT=y
+# CONFIG_GENERATE_ACPI_TABLES is not set
+# CONFIG_GENERATE_MP_TABLE is not set
+# CONFIG_GENERATE_PIRQ_TABLE is not set
+
+#
+# Payload
+#
+CONFIG_PAYLOAD_NONE=y
+# CONFIG_PAYLOAD_ELF is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_COMPRESSED_PAYLOAD_NRV2B is not set
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_HAVE_DEBUG_RAM_SETUP is not set
+# CONFIG_HAVE_DEBUG_CAR is not set
+# CONFIG_HAVE_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_LLSHELL is not set
+# CONFIG_TRACE is not set
+# CONFIG_AP_CODE_IN_CAR is not set
+# CONFIG_RAMINIT_SYSINFO is not set
+# CONFIG_ENABLE_APIC_EXT_ID is not set
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+# CONFIG_CHROMEOS is not set
diff --git a/src/mainboard/Kconfig b/src/mainboard/Kconfig
index da76327..734aaf2 100644
--- a/src/mainboard/Kconfig
+++ b/src/mainboard/Kconfig
@@ -58,6 +58,8 @@ config VENDOR_GETAC
 	bool "Getac"
 config VENDOR_GIGABYTE
 	bool "GIGABYTE"
+config VENDOR_GOOGLE
+	bool "Google"
 config VENDOR_HP
 	bool "HP"
 config VENDOR_IBASE
@@ -158,6 +160,7 @@ source "src/mainboard/ecs/Kconfig"
 source "src/mainboard/emulation/Kconfig"
 source "src/mainboard/getac/Kconfig"
 source "src/mainboard/gigabyte/Kconfig"
+source "src/mainboard/google/Kconfig"
 source "src/mainboard/hp/Kconfig"
 source "src/mainboard/ibase/Kconfig"
 source "src/mainboard/ibm/Kconfig"
@@ -304,6 +307,19 @@ config ROM_SIZE
 	default 0x800000 if COREBOOT_ROMSIZE_KB_8192
 	default 0x1000000 if COREBOOT_ROMSIZE_KB_16384
 
+# FIXME: does this need to be here or in sandybridge/ ?
+#config CBFS_SIZE
+#	hex
+#	default ROM_SIZE
+
+config CACHE_ROM_SIZE
+	hex
+	default ROM_SIZE
+
+config CACHE_ROM_SIZE
+	hex
+	default CBFS_SIZE
+
 config ENABLE_POWER_BUTTON
 	bool "Enable the power button" if POWER_BUTTON_IS_OPTIONAL
 	default y if POWER_BUTTON_DEFAULT_ENABLE
diff --git a/src/mainboard/google/Kconfig b/src/mainboard/google/Kconfig
new file mode 100644
index 0000000..126a37d
--- /dev/null
+++ b/src/mainboard/google/Kconfig
@@ -0,0 +1,17 @@
+if VENDOR_GOOGLE
+
+choice
+	prompt "Mainboard model"
+
+config BOARD_GOOGLE_SNOW
+	bool "Snow"
+
+endchoice
+
+source "src/mainboard/google/snow/Kconfig"
+
+config MAINBOARD_VENDOR
+	string
+	default "Google"
+
+endif # VENDOR_GOOGLE
diff --git a/src/mainboard/google/snow/Kconfig b/src/mainboard/google/snow/Kconfig
new file mode 100644
index 0000000..eedccba
--- /dev/null
+++ b/src/mainboard/google/snow/Kconfig
@@ -0,0 +1,162 @@
+if BOARD_GOOGLE_SNOW
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select ARCH_ARMV7
+	select CPU_SAMSUNG_EXYNOS5
+	select HAVE_UART_MEMORY_MAPPED
+	select CONSOLE_SERIAL_NONSTANDARD_MEM	# enable serial debugging
+#	select NORTHBRIDGE_INTEL_IVYBRIDGE
+#	select EC_GOOGLE_CHROMEEC
+	select BOARD_ROMSIZE_KB_4096
+	select DRIVER_MAXIM_77686
+#	select HAVE_ACPI_TABLES
+#	select MMCONF_SUPPORT
+#	select CHROMEOS
+
+config MAINBOARD_DIR
+	string
+	default google/snow
+
+config MAINBOARD_PART_NUMBER
+	string
+	default "SNOW"
+
+#config MMCONF_BASE_ADDRESS
+#	hex
+#	default 0xf0000000
+
+#config IRQ_SLOT_COUNT
+#	int
+#	default 18
+
+config MAX_CPUS
+	int
+	default 2
+
+config MAINBOARD_VENDOR
+	string
+	default "Samsung"
+
+# SPL (second-phase loader) stuff
+config SPL_TEXT_BASE
+	hex "SPL executable base"
+	default 0x02023400
+	help
+	  Location of SPL. Default location is within iRAM region.
+
+#FIXME: increased "SPL" size to get around build issues 
+#config SPL_MAX_SIZE
+#	hex "SPL executable max size"
+#	default 0x3800
+#	help
+#	  Max size of SPL. Default is 14KB
+config SPL_MAX_SIZE
+	hex "SPL executable max size"
+	default 0x8000
+	help
+	  Max size of SPL. Let's say 32KB for now...
+
+config DRAM_SIZE_MB
+	int "DRAM size (MB)"
+	default 2048
+
+config NR_DRAM_BANKS
+	int "Number of DRAM banks"
+	default 1
+
+choice
+	prompt "Serial Console UART"
+	default CONSOLE_SERIAL_UART3
+	depends on CONSOLE_SERIAL_NONSTANDARD_MEM
+
+config CONSOLE_SERIAL_UART0
+	bool "UART0"
+	help
+	  Serial console on UART0
+
+config CONSOLE_SERIAL_UART1
+	bool "UART1"
+	help
+	  Serial console on UART1
+
+config CONSOLE_SERIAL_UART2
+	bool "UART2"
+	help
+	  Serial console on UART2
+
+config CONSOLE_SERIAL_UART3
+	bool "UART3"
+	help
+	  Serial console on UART3
+
+endchoice
+
+config CONSOLE_SERIAL_UART_ADDRESS
+	hex
+	depends on CONSOLE_SERIAL_NONSTANDARD_MEM
+	default 0x12c00000 if CONSOLE_SERIAL_UART0
+	default 0x12c10000 if CONSOLE_SERIAL_UART1
+	default 0x12c20000 if CONSOLE_SERIAL_UART2
+	default 0x12c30000 if CONSOLE_SERIAL_UART3
+	help
+	  Map the UART names to the respective MMIO address.
+
+#################################################################
+#   stuff from smdk5250.h                                       #
+#   FIXME: can we move some of these to exynos5250's Kconfig?   #
+#################################################################
+config SYS_I2C_SPEED
+	int
+	default 100000
+
+config SYS_I2C_SLAVE
+	hex
+	default 0x0
+	
+config I2C_MULTI_BUS
+	bool
+	default y
+
+#config HARD_I2C
+#	bool
+#	default y
+#CMD_I2C
+#I2C_EDID
+#DRIVER_S3C24X0_I2C
+
+config VDD_ARM_MV
+	int
+	default 1300	#1.3V
+
+config VDD_INT_UV
+	int
+	default 1012500	# 1.0125v
+
+config VDD_MIF_MV
+	int
+	default 1000	# 1.0v
+
+config VDD_G3D_MV
+	int
+	default 1200	# 1.2v
+
+config VDD_LDO2_MV
+	int
+	default 1500	# 1.5v
+
+config VDD_LDO3_MV
+	int
+	default 1800	# 1.8v
+
+config VDD_LDO5_MV
+	int
+	default 1800	# 1.8v
+
+config VDD_LDO10_MV
+	int
+	default 1800	# 1.8v
+
+######### smdk5250.h ########
+
+endif # BOARD_GOOGLE_SNOW
diff --git a/src/mainboard/google/snow/Makefile.inc b/src/mainboard/google/snow/Makefile.inc
new file mode 100644
index 0000000..01488d0
--- /dev/null
+++ b/src/mainboard/google/snow/Makefile.inc
@@ -0,0 +1,36 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 The ChromiumOS Authors.  All rights reserved.
+##
+## 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; version 2 of the License.
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+#romstage-y += romstage.c
+
+# ramstage-y += ec.c
+
+# FIXME: smdk5250_spl and mainboard.c are a mess. In the long
+# run we'll want to replace low-level code that calls mainboard code
+# with mainboard code that calls low-level code with appropriate
+# parameters. Grep around for spl_get_machine_params for examples.
+romstage-y += smdk5250_spl.c
+ramstage-y += smdk5250_spl.c
+#ramstage-y += mainboard.c
+
+# romstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+# FIXME: we should do something similar to x86 platforms for Snow SPDs
+
+SRC_ROOT = $(src)/mainboard/google/snow
diff --git a/src/mainboard/google/snow/board.h b/src/mainboard/google/snow/board.h
new file mode 100644
index 0000000..bedd740
--- /dev/null
+++ b/src/mainboard/google/snow/board.h
@@ -0,0 +1,33 @@
+/*
+ * Board header file for Exynos boards
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+#ifndef __SAMSUNG_BOARD_H
+#define __SAMSUNG_BOARD_H
+
+/* Init the SPI driver */
+void spi_init(void);
+
+/* Init the I2C driver */
+void board_i2c_init(const void *blob);
+
+#endif
diff --git a/src/mainboard/google/snow/devicetree.cb b/src/mainboard/google/snow/devicetree.cb
new file mode 100644
index 0000000..1d9d553
--- /dev/null
+++ b/src/mainboard/google/snow/devicetree.cb
@@ -0,0 +1,7 @@
+# FIXME: this is just a stub for now
+chip cpu/samsung/exynos5250
+	chip drivers/generic/generic # I2C0 controller
+		device i2c 6 on end # ?
+		device i2c 9 on end # ?
+	end
+end
diff --git a/src/mainboard/google/snow/mainboard.c b/src/mainboard/google/snow/mainboard.c
new file mode 100644
index 0000000..8afac3c
--- /dev/null
+++ b/src/mainboard/google/snow/mainboard.c
@@ -0,0 +1,943 @@
+/*
+ * 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
+ */
+
+/*
+ * FIXME: Note: Most of this is taken from U-Boot. Coreboot stuff is
+ * appended at the end. Also, much of this should be broken up into
+ * smaller files anyway.
+ */
+
+#include <device/device.h>
+#if 0	/* big #if */
+#include <common.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <max77686.h>
+#include <mkbp.h>
+#include <mmc.h>
+#include <netdev.h>
+#include <tps65090.h>
+#include <errno.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <cpu/samsung/exynos5250/cpu.h>
+#include <asm/arch/ehci-s5p.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/mshc.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/sromc.h>
+#include <asm/arch-exynos5/power.h>
+#include <asm/arch/sata.h>
+#include <asm/arch/exynos-tmu.h>
+#include <asm/arch/exynos-cpufreq.h>
+#include <asm/arch/s5p-dp.h>
+
+#include "board.h"
+
+#ifndef CONFIG_EXYNOS_DISPLAYPORT
+#error "CONFIG_EXYNOS_DISPLAYPORT must be defined for smdk5250"
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct local_info {
+	struct mkbp_dev *mkbp_dev;	/* Pointer to mkbp device */
+	int arbitrate_node;
+	struct fdt_gpio_state ap_claim;
+	struct fdt_gpio_state ec_claim;
+
+	/* DisplayPort gpios */
+	struct fdt_gpio_state dp_pd;
+	struct fdt_gpio_state dp_rst;
+	struct fdt_gpio_state dp_hpd;
+
+	/* Time between requesting bus and deciding that we have it */
+	unsigned slew_delay_us;
+
+	/* Time between retrying to see if the AP has released the bus */
+	unsigned wait_retry_ms;
+
+	/* Time to wait until the bus becomes free */
+	unsigned wait_free_ms;
+};
+
+static struct local_info local;
+static uint32_t cpufreq_loop_count;
+
+/*
+ * Called to do the needful when tstc has a character ready
+ * Meant to work in contrast to board_poll_devices
+ */
+void board_tstc_ready(void)
+{
+#ifdef CONFIG_EXYNOS_CPUFREQ
+	if (cpufreq_loop_count >= 10000000) {
+		/* Character received, increase ARM frequency */
+		exynos5250_set_frequency(CPU_FREQ_L1700);
+	}
+	cpufreq_loop_count = 0;
+#endif /* CONFIG_EXYNOS_CPUFREQ */
+}
+
+/*
+ * Polling various devices on board for details and status monitoring purposes
+ */
+void board_poll_devices(void)
+{
+#if defined CONFIG_EXYNOS_TMU
+	int temp;
+
+	switch (tmu_monitor(&temp)) {
+	case TMU_STATUS_TRIPPED:
+		puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
+		power_shutdown();
+		break;
+	case TMU_STATUS_WARNING:
+		puts("EXYNOS_TMU: WARNING! Temperature very high\n");
+		break;
+	case TMU_STATUS_INIT:
+	case TMU_STATUS_NORMAL:
+		break;
+	default:
+		debug("Unknown TMU state\n");
+	}
+#endif /* CONFIG_EXYNOS_TMU */
+#ifdef CONFIG_EXYNOS_CPUFREQ
+	cpufreq_loop_count++;
+	if (cpufreq_loop_count == 10000000) {
+		/* User is idle, decrease ARM frequency*/
+		exynos5250_set_frequency(CPU_FREQ_L200);
+	}
+#endif /* CONFIG_EXYNOS_CPUFREQ */
+}
+
+#ifdef CONFIG_OF_CONTROL
+static int decode_sromc(const void *blob, struct fdt_sromc *config)
+{
+	int err;
+	int node;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
+	if (node < 0) {
+		debug("Could not find SROMC node\n");
+		return node;
+	}
+
+	config->bank = fdtdec_get_int(blob, node, "bank", 0);
+	config->width = fdtdec_get_int(blob, node, "width", 2);
+
+	err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
+			FDT_SROM_TIMING_COUNT);
+	if (err < 0) {
+		debug("Could not decode SROMC configuration\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return 0;
+}
+#endif
+
+#if 0
+/**
+ * Read and clear the marker value; then return the read value.
+ *
+ * This marker is set to EXYNOS5_SPL_MARKER when SPL runs. Then in U-Boot
+ * we can check (and clear) this marker to see if we were run from SPL.
+ * If we were called from another U-Boot, the marker will be clear.
+ *
+ * @return marker value (EXYNOS5_SPL_MARKER if we were run from SPL, else 0)
+ */
+static uint32_t exynos5_read_and_clear_spl_marker(void)
+{
+	uint32_t value, *marker = (uint32_t *)CONFIG_SPL_MARKER;
+
+	value = *marker;
+	*marker = 0;
+
+	return value;
+}
+#endif
+
+int board_is_processor_reset(void)
+{
+	static uint8_t inited, is_reset;
+	uint32_t marker_value;
+
+	if (!inited) {
+		marker_value = exynos5_read_and_clear_spl_marker();
+		is_reset = marker_value == EXYNOS5_SPL_MARKER;
+		inited = 1;
+	}
+
+	return is_reset;
+}
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_SMC911X
+	u32 smc_bw_conf, smc_bc_conf;
+	struct fdt_sromc config;
+	fdt_addr_t base_addr;
+	int node;
+
+#ifdef CONFIG_OF_CONTROL
+	node = decode_sromc(gd->fdt_blob, &config);
+	if (node < 0) {
+		debug("%s: Could not find sromc configuration\n", __func__);
+		return 0;
+	}
+	node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
+	if (node < 0) {
+		debug("%s: Could not find lan9215 configuration\n", __func__);
+		return 0;
+	}
+
+	/* We now have a node, so any problems from now on are errors */
+	base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
+	if (base_addr == FDT_ADDR_T_NONE) {
+		debug("%s: Could not find lan9215 address\n", __func__);
+		return -1;
+	}
+#else
+	/* Non-FDT configuration - bank number and timing parameters*/
+	config.bank = CONFIG_ENV_SROM_BANK;
+	config.width = 2;
+
+	config.timing[FDT_SROM_TACS] = 0x01;
+	config.timing[FDT_SROM_TCOS] = 0x01;
+	config.timing[FDT_SROM_TACC] = 0x06;
+	config.timing[FDT_SROM_TCOH] = 0x01;
+	config.timing[FDT_SROM_TAH] = 0x0C;
+	config.timing[FDT_SROM_TACP] = 0x09;
+	config.timing[FDT_SROM_PMC] = 0x01;
+	base_addr = CONFIG_SMC911X_BASE;
+#endif
+
+	/* Ethernet needs data bus width of 16 bits */
+	if (config.width != 2) {
+		debug("%s: Unsupported bus width %d\n", __func__,
+			config.width);
+		return -1;
+	}
+	smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
+			| SROMC_BYTE_ENABLE(config.bank);
+
+	smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS])   |\
+			SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
+			SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
+			SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
+			SROMC_BC_TAH(config.timing[FDT_SROM_TAH])   |\
+			SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
+			SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
+
+	/* Select and configure the SROMC bank */
+	exynos_pinmux_config(PERIPH_ID_SROMC, config.bank | PINMUX_FLAG_16BIT);
+	s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
+	return smc911x_initialize(0, base_addr);
+#endif
+	return 0;
+}
+
+int fdtdec_decode_memory(const void *blob, struct fdt_memory *config)
+{
+	int node, len;
+	const fdt_addr_t *cell;
+
+	node = fdt_path_offset(blob, "/memory");
+	if (node < 0) {
+		debug("Could not find the path /memory\n");
+		return node;
+	}
+	cell = fdt_getprop(blob, node, "reg", &len);
+	if (cell && len == sizeof(fdt_addr_t) * 2) {
+		config->start = fdt_addr_to_cpu(cell[0]);
+		config->end = fdt_addr_to_cpu(cell[1]);
+	} else {
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	return 0;
+}
+
+int board_usb_vbus_init(void)
+{
+	/* Enable VBUS power switch */
+	gpio_direction_output(GPIO_X11, 1);
+	/* VBUS turn ON time */
+	mdelay(3);
+
+	return 0;
+}
+
+struct mkbp_dev *board_get_mkbp_dev(void)
+{
+	return local.mkbp_dev;
+}
+
+/*
+ * This functions disable the USB3.0 PLL to save power
+ */
+static void disable_usb30_pll(void)
+{
+	int node, ret;
+	struct fdt_gpio_state en_gpio;
+
+	node = fdtdec_next_compatible(gd->fdt_blob, 0,
+		COMPAT_SAMSUNG_EXYNOS_USB);
+	if (node < 0)
+		return;
+
+	ret = fdtdec_decode_gpio(gd->fdt_blob, node, "usb3-pll-gpio", &en_gpio);
+	if (ret)
+		return;
+
+	fdtdec_setup_gpio(&en_gpio);
+	gpio_direction_output(en_gpio.gpio, en_gpio.flags);
+}
+
+static int board_init_mkbp_devices(const void *blob)
+{
+	local.mkbp_dev = mkbp_init(blob);
+	if (!local.mkbp_dev) {
+		debug("%s: cannot init mkbp device\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int board_i2c_arb_init(const void *blob)
+{
+	int node;
+
+	local.arbitrate_node = -1;
+	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_ARBITRATOR);
+	if (node < 0) {
+		debug("Cannot find bus arbitrator node\n");
+		return 0;
+	}
+
+	if (fdtdec_decode_gpio(blob, node, "google,ap-claim-gpios",
+				&local.ap_claim) ||
+			fdtdec_decode_gpio(blob, node, "google,ec-claim-gpios",
+				&local.ec_claim)) {
+		debug("Cannot find bus arbitrator GPIOs\n");
+		return 0;
+	}
+
+	if (fdtdec_setup_gpio(&local.ap_claim) ||
+			fdtdec_setup_gpio(&local.ec_claim)) {
+		debug("Cannot claim arbitration GPIOs\n");
+		return -1;
+	}
+
+	/* We are currently not claiming the bus */
+	gpio_direction_output(local.ap_claim.gpio, 1);
+	gpio_direction_input(local.ec_claim.gpio);
+	gpio_set_pull(local.ec_claim.gpio, EXYNOS_GPIO_PULL_UP);
+
+	local.arbitrate_node = fdtdec_lookup_phandle(blob, node,
+						     "google,arbitrate-bus");
+	if (local.arbitrate_node < 0) {
+		debug("Cannot find bus to arbitrate\n");
+		return -1;
+	}
+
+	local.slew_delay_us = fdtdec_get_int(blob, node,
+					     "google,slew-delay-us", 10);
+	local.wait_retry_ms = fdtdec_get_int(blob, node,
+					     "google,wait-retry-us", 2000);
+	local.wait_retry_ms = DIV_ROUND_UP(local.wait_retry_ms, 1000);
+	local.wait_free_ms = fdtdec_get_int(blob, node,
+					    "google,wait-free-us", 50000);
+	local.wait_free_ms = DIV_ROUND_UP(local.wait_free_ms, 1000);
+	debug("Bus arbitration ready on fdt node %d\n", local.arbitrate_node);
+
+	return 0;
+}
+
+/**
+ * Fix-up the kernel device tree so the bridge pd_n and rst_n gpios accurately
+ * reflect the current board rev.
+ */
+static void ft_board_setup_gpios(void *blob, bd_t *bd)
+{
+	int ret, rev, np, len;
+	const struct fdt_property *prop;
+
+	/* Do nothing for newer boards */
+	rev = board_get_revision();
+	if (rev < 4 || rev == 6)
+		return;
+
+	/*
+	 * If this is an older board, replace powerdown-gpio contents with that
+	 * of reset-gpio and delete reset-gpio from the dt.
+	 */
+	np = fdtdec_next_compatible(blob, 0, COMPAT_NXP_PTN3460);
+	if (np < 0) {
+		debug("%s: Could not find COMPAT_NXP_PTN3460\n", __func__);
+		return;
+	}
+
+	prop = fdt_get_property(blob, np, "reset-gpio", &len);
+	if (!prop) {
+		debug("%s: Could not get property err=%d\n", __func__, len);
+		return;
+	}
+
+	ret = fdt_setprop_inplace(blob, np, "powerdown-gpio", prop->data,
+			len);
+	if (ret) {
+		debug("%s: Could not setprop inplace err=%d\n", __func__, ret);
+		return;
+	}
+
+	ret = fdt_delprop(blob, np, "reset-gpio");
+	if (ret) {
+		debug("%s: Could not delprop err=%d\n", __func__, ret);
+		return;
+	}
+}
+
+/**
+ * Fix-up the kernel device tree so the powered-while-resumed is added to MP
+ * device tree.
+ */
+static void ft_board_setup_tpm_resume(void *blob, bd_t *bd)
+{
+	const char kernel_tpm_compat[] = "infineon,slb9635tt";
+	const char prop_name[] = "powered-while-suspended";
+	int err, node, rev;
+
+	/* Only apply fixup to MP machine */
+	rev = board_get_revision();
+	if (!(rev == 0 || rev == 3))
+		return;
+
+	node = fdt_node_offset_by_compatible(blob, 0, kernel_tpm_compat);
+	if (node < 0) {
+		debug("%s: fail to find %s: %d\n", __func__,
+				kernel_tpm_compat, node);
+		return;
+	}
+
+	err = fdt_setprop(blob, node, prop_name, NULL, 0);
+	if (err) {
+		debug("%s: fail to setprop: %d\n", __func__, err);
+		return;
+	}
+}
+
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_board_setup_gpios(blob, bd);
+	ft_board_setup_tpm_resume(blob, bd);
+}
+
+#ifdef CONFIG_TPS65090_POWER
+int board_dp_lcd_vdd(const void *blob, unsigned *wait_ms)
+{
+	*wait_ms = 0;
+	return tps65090_fet_enable(6); /* Enable FET6, lcd panel */
+}
+#endif
+
+static int board_dp_fill_gpios(const void *blob)
+{
+	int np, ret, rev;
+
+	np = fdtdec_next_compatible(blob, 0, COMPAT_NXP_PTN3460);
+	if (np < 0) {
+		debug("%s: Could not find COMPAT_NXP_PTN3460 (%d)\n", __func__,
+			ret);
+		return np;
+	}
+	ret = fdtdec_decode_gpio(blob, np, "powerdown-gpio", &local.dp_pd);
+	if (ret) {
+		debug("%s: Could not decode powerdown-gpio (%d)\n", __func__,
+			ret);
+		return ret;
+	}
+	ret = fdtdec_decode_gpio(blob, np, "reset-gpio", &local.dp_rst);
+	if (ret) {
+		debug("%s: Could not decode reset-gpio (%d)\n", __func__, ret);
+		return ret;
+	}
+	ret = fdtdec_decode_gpio(blob, np, "hotplug-gpio", &local.dp_hpd);
+	if (ret) {
+		debug("%s: Could not decode hotplug (%d)\n", __func__, ret);
+		return ret;
+	}
+
+	/* If board is older, replace pd gpio with rst gpio */
+	rev = board_get_revision();
+	if (rev >= 4 && rev != 6) {
+		local.dp_pd = local.dp_rst;
+		local.dp_rst.gpio = FDT_GPIO_NONE;
+	}
+	return 0;
+}
+
+int board_dp_bridge_setup(const void *blob, unsigned *wait_ms)
+{
+	int ret;
+
+	ret = board_dp_fill_gpios(blob);
+	if (ret)
+		return ret;
+
+	/* Mux HPHPD to the special hotplug detect mode */
+	exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
+
+	/* Setup the GPIOs */
+	ret = fdtdec_setup_gpio(&local.dp_pd);
+	if (ret) {
+		debug("%s: Could not setup pd gpio (%d)\n", __func__, ret);
+		return ret;
+	}
+	ret = fdtdec_setup_gpio(&local.dp_rst);
+	if (ret) {
+		debug("%s: Could not setup rst gpio (%d)\n", __func__, ret);
+		return ret;
+	}
+	ret = fdtdec_setup_gpio(&local.dp_hpd);
+	if (ret) {
+		debug("%s: Could not setup hpd gpio (%d)\n", __func__, ret);
+		return ret;
+	}
+
+	fdtdec_set_gpio(&local.dp_pd, 0);
+	gpio_cfg_pin(local.dp_pd.gpio, EXYNOS_GPIO_OUTPUT);
+	gpio_set_pull(local.dp_pd.gpio, EXYNOS_GPIO_PULL_NONE);
+	if (fdt_gpio_isvalid(&local.dp_rst)) {
+		fdtdec_set_gpio(&local.dp_rst, 1);
+		gpio_cfg_pin(local.dp_rst.gpio, EXYNOS_GPIO_OUTPUT);
+		gpio_set_pull(local.dp_rst.gpio, EXYNOS_GPIO_PULL_NONE);
+		udelay(10);
+		fdtdec_set_gpio(&local.dp_rst, 0);
+	}
+
+	*wait_ms = 0;
+	return 0;
+}
+
+int board_dp_bridge_init(const void *blob, unsigned *wait_ms)
+{
+	/* De-assert PD (and possibly RST) to power up the bridge */
+	fdtdec_set_gpio(&local.dp_pd, 0);
+
+	/* Ignore the return value here, on some boards this is NC */
+	fdtdec_set_gpio(&local.dp_rst, 0);
+
+	/*
+	 * 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.
+	 */
+	*wait_ms = 90;
+	return 0;
+}
+
+int board_dp_bridge_reset(const void *blob, unsigned *wait_ms)
+{
+	debug("%s: eDP bridge failed to come up\n", __func__);
+
+	/*
+	 * If we're here, the bridge chip failed to initialize.
+	 * Drive DP_N low in an attempt to reset.
+	 */
+	fdtdec_set_gpio(&local.dp_pd, 1);
+
+	/* Ignore the return value here, on some boards this is NC */
+	fdtdec_set_gpio(&local.dp_rst, 1);
+
+	/*
+	 * Arbitrarily wait 300ms here with DP_N low.  Don't know for
+	 * sure how long we should wait, but we're being paranoid.
+	 */
+	*wait_ms = 300;
+	return 0;
+}
+
+int board_dp_hotplug(const void *blob, unsigned *wait_ms)
+{
+	const int MAX_TRIES = 10;
+	static int num_tries;
+
+	/* Check HPD.  If it's high, we're all good. */
+	if (fdtdec_get_gpio(&local.dp_hpd)) {
+		*wait_ms = 0;
+		return 0;
+	}
+
+	debug("%s: eDP bridge failed to come up; try %d of %d\n", __func__,
+		num_tries, MAX_TRIES);
+	/* Immediately go into bridge reset if the hp line is not high */
+	*wait_ms = 0;
+	++num_tries;
+	return num_tries <= MAX_TRIES ? -EAGAIN : -ENODEV;
+}
+
+#ifdef CONFIG_TPS65090_POWER
+int board_dp_backlight_vdd(const void *blob, unsigned *wait_ms)
+{
+	/* This delay is T5 in the LCD timing spec (defined as > 10ms) */
+	*wait_ms = 10;
+	return tps65090_fet_enable(1); /* Enable FET1, backlight */
+}
+#endif
+
+int board_dp_backlight_pwm(const void *blob, unsigned *wait_ms)
+{
+	/*
+	 * Configure backlight PWM as a simple output high (100% brightness)
+	 * TODO(hatim.rv at samsung.com): Move to FDT
+	 */
+	gpio_direction_output(GPIO_B20, 1);
+	/* This delay is T6 in the LCD timing spec (defined as > 10ms) */
+	*wait_ms = 10;
+	return 0;
+}
+
+int board_dp_backlight_en(const void *blob, unsigned *wait_ms)
+{
+	/*
+	 * Configure GPIO for LCD_BL_EN
+	 * TODO(hatim.rv at samsung.com): Move to FDT
+	 */
+	gpio_direction_output(GPIO_X30, 1);
+	/* We're done, no more delays! */
+	*wait_ms = 0;
+	return 0;
+}
+
+static void board_enable_audio_codec(void)
+{
+	int node, ret, value;
+	struct fdt_gpio_state en_gpio;
+
+	node = fdtdec_next_compatible(gd->fdt_blob, 0,
+		COMPAT_SAMSUNG_EXYNOS_SOUND);
+	if (node <= 0)
+		return;
+
+	ret = fdtdec_decode_gpio(gd->fdt_blob, node, "codec-enable-gpio",
+				&en_gpio);
+	if (ret == -FDT_ERR_NOTFOUND)
+		return;
+
+	/* Turn on the GPIO which connects to the codec's "enable" line. */
+	value = (en_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? 0 : 1;
+	gpio_direction_output(en_gpio.gpio, value);
+	gpio_set_pull(en_gpio.gpio, EXYNOS_GPIO_PULL_NONE);
+}
+
+int board_init(void)
+{
+	struct fdt_memory mem_config;
+
+	/* Record the time we spent before SPL */
+	bootstage_add_record(BOOTSTAGE_ID_START_SPL, "spl_start", 0,
+			     CONFIG_SPL_TIME_US);
+	bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT, "board_init");
+
+	if (fdtdec_decode_memory(gd->fdt_blob, &mem_config)) {
+		debug("%s: Failed to decode memory\n", __func__);
+		return -1;
+	}
+
+	gd->bd->bi_boot_params = mem_config.start + 0x100UL;
+
+#ifdef CONFIG_OF_CONTROL
+	gd->bd->bi_arch_number = fdtdec_get_config_int(gd->fdt_blob,
+				"machine-arch-id", -1);
+	if (gd->bd->bi_arch_number == -1U)
+		debug("Warning: No /config/machine-arch-id defined in fdt\n");
+#endif
+#ifdef CONFIG_EXYNOS_SPI
+	spi_init();
+#endif
+
+	if (board_i2c_arb_init(gd->fdt_blob))
+		return -1;
+
+	board_i2c_init(gd->fdt_blob);
+
+#ifdef CONFIG_TPS65090_POWER
+	tps65090_init();
+
+	/*
+	 * If we just reset, disable the backlight and lcd fets before
+	 * [re-]initializing the lcd. This ensures we are always in the same
+	 * state during lcd init. We've seen some oddities with these fets, so
+	 * this removes a bit of uncertainty.
+	 */
+	if (board_is_processor_reset()) {
+		tps65090_fet_disable(1);
+		tps65090_fet_disable(6);
+	}
+#endif
+	exynos_lcd_check_next_stage(gd->fdt_blob, 0);
+
+	if (max77686_enable_32khz_cp()) {
+		debug("%s: Failed to enable max77686 32khz coprocessor clock\n",
+				 __func__);
+		return -1;
+	}
+
+#if defined CONFIG_EXYNOS_CPUFREQ
+	if (exynos5250_cpufreq_init(gd->fdt_blob)) {
+		debug("%s: Failed to init CPU frequency scaling\n", __func__);
+		return -1;
+	}
+#endif
+
+#if defined CONFIG_EXYNOS_TMU
+	if (tmu_init(gd->fdt_blob)) {
+		debug("%s: Failed to init TMU\n", __func__);
+		return -1;
+	}
+#endif
+
+	/* Clock Gating all the unused IP's to save power */
+	clock_gate();
+
+	/* Disable USB3.0 PLL to save 250mW of power */
+	disable_usb30_pll();
+
+	if (board_init_mkbp_devices(gd->fdt_blob))
+		return -1;
+
+	board_enable_audio_codec();
+
+	exynos_lcd_check_next_stage(gd->fdt_blob, 0);
+
+	bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT_DONE, "board_init_done");
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct fdt_memory mem_config;
+
+	if (fdtdec_decode_memory(gd->fdt_blob, &mem_config)) {
+		debug("%s: Failed to decode memory\n", __func__);
+		return -1;
+	}
+
+	gd->ram_size = get_ram_size((long *)mem_config.start,
+				mem_config.end);
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	struct fdt_memory mem_config;
+
+	if (fdtdec_decode_memory(gd->fdt_blob, &mem_config)) {
+		debug("%s: Failed to decode memory\n", __func__);
+		return;
+	}
+
+	gd->bd->bi_dram[0].start = mem_config.start;
+	gd->bd->bi_dram[0].size = get_ram_size((long *)mem_config.start,
+				mem_config.end);
+}
+
+int board_get_revision(void)
+{
+	struct fdt_gpio_state gpios[CONFIG_BOARD_REV_GPIO_COUNT];
+	unsigned gpio_list[CONFIG_BOARD_REV_GPIO_COUNT];
+	int board_rev = -1;
+	int count = 0;
+	int node;
+
+	node = fdtdec_next_compatible(gd->fdt_blob, 0,
+				      COMPAT_GOOGLE_BOARD_REV);
+	if (node >= 0) {
+		count = fdtdec_decode_gpios(gd->fdt_blob, node,
+				"google,board-rev-gpios", gpios,
+				CONFIG_BOARD_REV_GPIO_COUNT);
+	}
+	if (count > 0) {
+		int i;
+
+		for (i = 0; i < count; i++)
+			gpio_list[i] = gpios[i].gpio;
+		board_rev = gpio_decode_number(gpio_list, count);
+	} else {
+		debug("%s: No board revision information in fdt\n", __func__);
+	}
+
+	return board_rev;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+#ifdef CONFIG_OF_CONTROL
+	const char *board_name;
+
+	board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+	printf("\nBoard: %s, rev %d\n", board_name ? board_name : "<unknown>",
+	       board_get_revision());
+#else
+	printf("\nBoard: SMDK5250\n");
+#endif
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_getcd(struct mmc *mmc)
+{
+	struct mshci_host *host = mmc->priv;
+	int present = 1; /* for ch0 (eMMC) card is always present */
+
+	if (host->peripheral == PERIPH_ID_SDMMC2)
+		present = !readl(&host->reg->cdetect);
+
+	return present;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+#ifdef CONFIG_S5P_MSHCI
+	s5p_mshci_init(gd->fdt_blob);
+#endif
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+	exynos_pinmux_config(EXYNOS_UART, PINMUX_FLAG_NONE);
+	return 0;
+}
+#endif
+
+void board_i2c_release_bus(int node)
+{
+	/* If this is us, release the bus */
+	if (node == local.arbitrate_node) {
+		gpio_set_value(local.ap_claim.gpio, 1);
+		udelay(local.slew_delay_us);
+	}
+}
+
+int board_i2c_claim_bus(int node)
+{
+	unsigned start;
+
+	if (node != local.arbitrate_node)
+		return 0;
+
+// 	putc('c');
+
+	/* Start a round of trying to claim the bus */
+	start = get_timer(0);
+	do {
+		unsigned start_retry;
+		int waiting = 0;
+
+		/* Indicate that we want to claim the bus */
+		gpio_set_value(local.ap_claim.gpio, 0);
+		udelay(local.slew_delay_us);
+
+		/* Wait for the EC to release it */
+		start_retry = get_timer(0);
+		while (get_timer(start_retry) < local.wait_retry_ms) {
+			if (gpio_get_value(local.ec_claim.gpio)) {
+				/* We got it, so return */
+				return 0;
+			}
+
+			if (!waiting) {
+				waiting = 1;
+			}
+		}
+
+		/* It didn't release, so give up, wait, and try again */
+		gpio_set_value(local.ap_claim.gpio, 1);
+
+		mdelay(local.wait_retry_ms);
+	} while (get_timer(start) < local.wait_free_ms);
+
+	/* Give up, release our claim */
+	printf("I2C: Could not claim bus, timeout %lu\n", get_timer(start));
+
+	return -1;
+}
+
+#ifdef CONFIG_SATA_AHCI
+int sata_initialize(void)
+{
+	return exynos5_sata_init(gd->fdt_blob);
+}
+#endif
+
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+	stdio_print_current_devices();
+
+	return 0;
+}
+#endif
+
+#endif	/* big #if */
+#if 0
+/* ACPI */
+void mainboard_suspend_resume(void)
+{
+	/* FIXME: stub */
+	return;
+}
+#endif
+
+static void mainboard_init(device_t dev)
+{
+	/* FIXME: stub */
+	return;
+}
+
+// mainboard_enable is executed as first thing after
+// enumerate_buses().
+
+static void mainboard_enable(device_t dev)
+{
+	dev->ops->init = mainboard_init;
+}
+
+struct chip_operations mainboard_ops = {
+	.name	= "Samsung/Google ChromeBook",
+	.enable_dev = mainboard_enable,
+};
+
diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c
new file mode 100644
index 0000000..c3a9b53
--- /dev/null
+++ b/src/mainboard/google/snow/romstage.c
@@ -0,0 +1,291 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2010 coresystems GmbH
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if 0
+#include <stdint.h>
+#include <string.h>
+#include <lib.h>
+#include <timestamp.h>
+#include <arch/io.h>
+//#include <arch/romcc_io.h>
+#if 0
+#include <device/pci_def.h>
+#include <device/pnp_def.h>
+#include <cpu/x86/lapic.h>
+#include <pc80/mc146818rtc.h>
+#endif
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
+#if 0
+#include "northbridge/intel/sandybridge/sandybridge.h"
+#include "northbridge/intel/sandybridge/raminit.h"
+#include "southbridge/intel/bd82x6x/pch.h"
+#include "southbridge/intel/bd82x6x/gpio.h"
+#endif
+#include <arch/cpu.h>
+#if 0
+#include <cpu/x86/bist.h>
+#include <cpu/x86/msr.h>
+#endif
+#include "option_table.h"
+#include "gpio.h"
+#if CONFIG_CONSOLE_SERIAL8250
+#if 0
+#include "superio/smsc/lpc47n207/lpc47n207.h"
+#include "superio/smsc/lpc47n207/early_serial.c"
+#endif
+#endif
+#if CONFIG_CHROMEOS
+#include <vendorcode/google/chromeos/chromeos.h>
+#endif
+#endif
+#include <types.h>
+#include <system.h>
+#include <cache.h>
+
+static void mmu_setup(void)
+{
+	dram_bank_mmu_setup(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB * 1024);
+}
+
+void main(unsigned long bist)
+{
+	mmu_setup();
+}
+
+#if 0
+/* FIXME: This is based off lumpy's romstage.c main() and is gutted to
+   resemble snow's eventually... */
+void main(unsigned long bist)
+{
+	int boot_mode = 0;
+	int cbmem_was_initted;
+//	u32 pm1_cnt;
+//	u16 pm1_sts;
+
+#if CONFIG_COLLECT_TIMESTAMPS
+#if 0
+	tsc_t start_romstage_time;
+	tsc_t before_dram_time;
+	tsc_t after_dram_time;
+	tsc_t base_time = {
+		.lo = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc),
+		.hi = pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0)
+	};
+#endif
+#endif
+
+#if 0
+	typedef const uint8_t spd_blob[256];
+	struct cbfs_file *spd_file;
+	spd_blob *spd_data;
+#endif
+
+
+#if CONFIG_COLLECT_TIMESTAMPS
+//	start_romstage_time = rdtsc();
+#endif
+
+#if 0
+	if (bist == 0)
+		enable_lapic();
+
+	pch_enable_lpc();
+
+	/* Enable GPIOs */
+	pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1);
+	pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
+	setup_pch_gpios(&lumpy_gpio_map);
+
+	console_init();
+#endif
+
+#if CONFIG_CHROMEOS
+	save_chromeos_gpios();
+#endif
+
+#if 0
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+#endif
+
+#if 0
+	/* Perform some early chipset initialization required
+	 * before RAM initialization can work
+	 */
+	sandybridge_early_initialization(SANDYBRIDGE_MOBILE);
+	printk(BIOS_DEBUG, "Back from sandybridge_early_initialization()\n");
+
+	/* Check PM1_STS[15] to see if we are waking from Sx */
+	pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
+
+	/* Read PM1_CNT[12:10] to determine which Sx state */
+	pm1_cnt = inl(DEFAULT_PMBASE + PM1_CNT);
+#endif
+#if 0
+
+	if ((pm1_sts & WAK_STS) && ((pm1_cnt >> 10) & 7) == 5) {
+#if CONFIG_HAVE_ACPI_RESUME
+		printk(BIOS_DEBUG, "Resume from S3 detected.\n");
+		boot_mode = 2;
+		/* Clear SLP_TYPE. This will break stage2 but
+		 * we care for that when we get there.
+		 */
+		outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + PM1_CNT);
+#else
+		printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
+#endif
+	}
+#endif
+
+//	post_code(0x38);
+	/* Enable SPD ROMs and DDR-III DRAM */
+//	enable_smbus();
+
+#if 0
+	/* Prepare USB controller early in S3 resume */
+	if (boot_mode == 2)
+		enable_usb_bar();
+
+	u32 gp_lvl2 = inl(DEFAULT_GPIOBASE + 0x38);
+	u8 gpio33, gpio41, gpio49;
+	gpio33 = (gp_lvl2 >> (33-32)) & 1;
+	gpio41 = (gp_lvl2 >> (41-32)) & 1;
+	gpio49 = (gp_lvl2 >> (49-32)) & 1;
+	printk(BIOS_DEBUG, "Memory Straps:\n");
+	printk(BIOS_DEBUG, " - memory capacity %dGB\n",
+		gpio33 ? 2 : 1);
+	printk(BIOS_DEBUG, " - die revision %d\n",
+		gpio41 ? 2 : 1);
+	printk(BIOS_DEBUG, " - vendor %s\n",
+		gpio49 ? "Samsung" : "Other");
+
+	int spd_index = 0;
+
+	switch ((gpio49 << 2) | (gpio41 << 1) | gpio33) {
+	case 0: // Other 1G Rev 1
+		spd_index = 0;
+		break;
+	case 2: // Other 1G Rev 2
+		spd_index = 1;
+		break;
+	case 1: // Other 2G Rev 1
+	case 3: // Other 2G Rev 2
+		spd_index = 2;
+		break;
+	case 4: // Samsung 1G Rev 1
+		spd_index = 3;
+		break;
+	case 6: // Samsung 1G Rev 2
+		spd_index = 4;
+		break;
+	case 5: // Samsung 2G Rev 1
+	case 7: // Samsung 2G Rev 2
+		spd_index = 5;
+		break;
+	}
+
+	spd_file = cbfs_find("spd.bin");
+	if (!spd_file)
+		die("SPD data not found.");
+	if (spd_file->len < (spd_index + 1) * 256)
+		die("Missing SPD data.");
+	spd_data = (spd_blob *)CBFS_SUBHEADER(spd_file);
+	// leave onboard dimm address at f0, and copy spd data there.
+	memcpy(pei_data.spd_data[0], spd_data[spd_index], 256);
+
+	post_code(0x39);
+	pei_data.boot_mode = boot_mode;
+#endif
+#if CONFIG_COLLECT_TIMESTAMPS
+	before_dram_time = rdtsc();
+#endif
+	sdram_initialize(&pei_data);
+
+#if CONFIG_COLLECT_TIMESTAMPS
+	after_dram_time = rdtsc();
+#endif
+#if 0
+	post_code(0x3a);
+	/* Perform some initialization that must run before stage2 */
+	early_pch_init();
+	post_code(0x3b);
+
+	rcba_config();
+	post_code(0x3c);
+
+	quick_ram_check();
+	post_code(0x3e);
+
+	MCHBAR16(SSKPD) = 0xCAFE;
+#endif
+#if CONFIG_EARLY_CBMEM_INIT
+	cbmem_was_initted = !cbmem_initialize();
+#else
+	cbmem_was_initted = cbmem_reinit((uint64_t) (get_top_of_ram()
+						     - HIGH_MEMORY_SIZE));
+#endif
+
+#if 0
+#if CONFIG_HAVE_ACPI_RESUME
+	/* If there is no high memory area, we didn't boot before, so
+	 * this is not a resume. In that case we just create the cbmem toc.
+	 */
+
+	*(u32 *)CBMEM_BOOT_MODE = 0;
+	*(u32 *)CBMEM_RESUME_BACKUP = 0;
+
+	if ((boot_mode == 2) && cbmem_was_initted) {
+		void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
+		if (resume_backup_memory) {
+			*(u32 *)CBMEM_BOOT_MODE = boot_mode;
+			*(u32 *)CBMEM_RESUME_BACKUP = (u32)resume_backup_memory;
+		}
+		/* Magic for S3 resume */
+		pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d);
+	} else if (boot_mode == 2) {
+		/* Failed S3 resume, reset to come up cleanly */
+		outb(0x6, 0xcf9);
+		hlt();
+	} else {
+		pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe);
+	}
+#endif
+#endif
+//	post_code(0x3f);
+#if CONFIG_CHROMEOS
+	init_chromeos(boot_mode);
+#endif
+#if 0
+#if CONFIG_COLLECT_TIMESTAMPS
+	timestamp_init(base_time);
+	timestamp_add(TS_START_ROMSTAGE, start_romstage_time );
+	timestamp_add(TS_BEFORE_INITRAM, before_dram_time );
+	timestamp_add(TS_AFTER_INITRAM, after_dram_time );
+	timestamp_add_now(TS_END_ROMSTAGE);
+#endif
+#endif
+#if CONFIG_CONSOLE_CBMEM
+	/* Keep this the last thing this function does. */
+	cbmemc_reinit();
+#endif
+}
+#endif
diff --git a/src/mainboard/google/snow/smdk5250_spl.c b/src/mainboard/google/snow/smdk5250_spl.c
new file mode 100644
index 0000000..a802338
--- /dev/null
+++ b/src/mainboard/google/snow/smdk5250_spl.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * 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
+ */
+
+#if 0
+#include <common.h>
+#include <asm/gpio.h>
+#include <asm/arch-exynos/cpu.h>
+#include <asm/arch/board.h>
+#include <asm/arch/dmc.h>
+#endif
+
+#include <arch/gpio.h>
+#include <cpu/samsung/exynos5-common/spl.h>
+#include <cpu/samsung/exynos5250/gpio.h>
+
+#define SIGNATURE	0xdeadbeef
+
+/* Parameters of early board initialization in SPL */
+static struct spl_machine_param machine_param
+		__attribute__((section(".machine_param"))) = {
+	.signature	= SIGNATURE,
+	.version	= 1,
+	.params		= "vmubfasirMw",
+	.size		= sizeof(machine_param),
+
+	.mem_iv_size	= 0x1f,
+	.mem_type	= DDR_MODE_DDR3,
+
+	/*
+	 * Set uboot_size to 0x100000 bytes.
+	 *
+	 * This is an overly conservative value chosen to accommodate all
+	 * possible U-Boot image.  You are advised to set this value to a
+	 * smaller realistic size via scripts that modifies the .machine_param
+	 * section of output U-Boot image.
+	 */
+	.uboot_size	= 0x100000,
+
+	.boot_source	= BOOT_MODE_OM,
+	.frequency_mhz	= 800,
+	.arm_freq_mhz	= 1700,
+	.serial_base	= 0x12c30000,
+	.i2c_base	= 0x12c60000,
+	.board_rev_gpios = GPIO_D00 | (GPIO_D01 << 16),
+	.mem_manuf	= MEM_MANUF_SAMSUNG,
+	.bad_wake_gpio	= GPIO_Y10,
+};
+
+struct spl_machine_param *spl_get_machine_params(void)
+{
+	if (machine_param.signature != SIGNATURE) {
+		/* TODO: Call panic() here */
+		while (1)
+			;
+	}
+
+	return &machine_param;
+}
+
+/* FIXME(dhendrix): Move all this board_* stuff into the actual mainboard
+ * directory. */
+#if 0
+/* FIXME(dhendrix): originally this #define was in exynos5-common.h which
+   seems wrong. */
+#define CONFIG_BOARD_REV_GPIO_COUNT	2
+int board_get_revision(void)
+{
+	struct spl_machine_param *params = spl_get_machine_params();
+	unsigned gpio[CONFIG_BOARD_REV_GPIO_COUNT];
+
+	gpio[0] = params->board_rev_gpios & 0xffff;
+	gpio[1] = params->board_rev_gpios >> 16;
+	return gpio_decode_number(gpio, CONFIG_BOARD_REV_GPIO_COUNT);
+}
+#endif
+
+int board_wakeup_permitted(void)
+{
+	struct spl_machine_param *param = spl_get_machine_params();
+	const int gpio = param->bad_wake_gpio;
+	int is_bad_wake;
+
+	/* We're a bad wakeup if the gpio was defined and was high */
+	is_bad_wake = ((gpio != -1) && gpio_get_value(gpio));
+
+	return !is_bad_wake;
+}
+
+#if 0
+/*
+ * TODO(sjg at chromium.org):
+ * Declared there here for SPL, since there is no core i2c subsystem and
+ * cmd_i2c.c is not included.
+ */
+void board_i2c_release_bus(int node)
+{
+}
+
+int board_i2c_claim_bus(int node)
+{
+	/* EC is not allowed to touch the bus until we enter U-Boot */
+	return 0;
+}
+#endif




More information about the coreboot mailing list