soc/amd/picasso: Create picasso as a copy of stoneyridge

So that everyone can see what's being updated from stoney, we're
starting with a direct copy of the stoney directory. There are
arguments both for and against doing it this way, but I believe
This the most transparent way.  We've moved much of the duplicated
stoney code into the soc/amd/common directory and will continue
that work as it becomes obvious that we have unchanged code between
the SOCs.

Makefile.inc has been renamed as makefile.inc so that it won't
build in jenkins until the directory is  updated.

Other than that change, this is an exact copy of the stoneyridge
SOC directory which will be updated in the follow-on commits in
the patch train.

TEST=None
BUG=b:130804851

Signed-off-by: Martin Roth <martinroth@chromium.org>
Change-Id: I6809bd1eea304f76dd9000c079b3ed09f94dbd3b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/32407
Reviewed-by: Richard Spiegel <richard.spiegel@silverbackltd.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/amd/picasso/BiosCallOuts.c b/src/soc/amd/picasso/BiosCallOuts.c
new file mode 100644
index 0000000..c55e734
--- /dev/null
+++ b/src/soc/amd/picasso/BiosCallOuts.c
@@ -0,0 +1,166 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011, 2017 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ * Copyright (C) 2017 Google Inc.
+ *
+ * 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.
+ */
+
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <amdblocks/BiosCallOuts.h>
+#include <console/console.h>
+#include <soc/southbridge.h>
+#include <soc/pci_devs.h>
+#include <stdlib.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/dimm_spd.h>
+#include <amdblocks/car.h>
+
+#include "chip.h"
+
+void __weak platform_FchParams_reset(FCH_RESET_DATA_BLOCK *FchParams_reset) {}
+
+AGESA_STATUS agesa_fch_initreset(uint32_t Func, uintptr_t FchData,
+							void *ConfigPtr)
+{
+	AMD_CONFIG_PARAMS *StdHeader = ConfigPtr;
+
+	if (StdHeader->Func == AMD_INIT_RESET) {
+		FCH_RESET_DATA_BLOCK *FchParams_reset;
+		FchParams_reset = (FCH_RESET_DATA_BLOCK *)FchData;
+		printk(BIOS_DEBUG, "Fch OEM config in INIT RESET ");
+
+		/* Get platform specific configuration changes */
+		platform_FchParams_reset(FchParams_reset);
+
+		printk(BIOS_DEBUG, "Done\n");
+	}
+
+	return AGESA_SUCCESS;
+}
+
+AGESA_STATUS agesa_fch_initenv(uint32_t Func, uintptr_t FchData,
+							void *ConfigPtr)
+{
+	AMD_CONFIG_PARAMS *StdHeader = ConfigPtr;
+	const struct device *dev = pcidev_path_on_root(SATA_DEVFN);
+
+	if (StdHeader->Func == AMD_INIT_ENV) {
+		FCH_DATA_BLOCK *FchParams_env = (FCH_DATA_BLOCK *)FchData;
+		printk(BIOS_DEBUG, "Fch OEM config in INIT ENV ");
+
+		/* XHCI configuration */
+		if (CONFIG(STONEYRIDGE_XHCI_ENABLE))
+			FchParams_env->Usb.Xhci0Enable = TRUE;
+		else
+			FchParams_env->Usb.Xhci0Enable = FALSE;
+		FchParams_env->Usb.Xhci1Enable = FALSE;
+
+		/* SATA configuration */
+		FchParams_env->Sata.SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
+		if (dev && dev->enabled) {
+			switch ((SATA_CLASS)CONFIG_STONEYRIDGE_SATA_MODE) {
+			case SataRaid:
+			case SataAhci:
+			case SataAhci7804:
+			case SataLegacyIde:
+				FchParams_env->Sata.SataIdeMode = FALSE;
+				break;
+			case SataIde2Ahci:
+			case SataIde2Ahci7804:
+			default: /* SataNativeIde */
+				FchParams_env->Sata.SataIdeMode = TRUE;
+				break;
+			}
+		} else
+			FchParams_env->Sata.SataIdeMode = FALSE;
+
+		/* Platform updates */
+		platform_FchParams_env(FchParams_env);
+
+		printk(BIOS_DEBUG, "Done\n");
+	}
+
+	return AGESA_SUCCESS;
+}
+
+AGESA_STATUS agesa_ReadSpd(uint32_t Func, uintptr_t Data, void *ConfigPtr)
+{
+	uint8_t spd_address;
+	int err;
+	DEVTREE_CONST struct device *dev;
+	DEVTREE_CONST struct soc_amd_stoneyridge_config *conf;
+	AGESA_READ_SPD_PARAMS *info = ConfigPtr;
+
+	if (!ENV_ROMSTAGE)
+		return AGESA_UNSUPPORTED;
+
+	dev = pcidev_path_on_root(DCT_DEVFN);
+	if (dev == NULL)
+		return AGESA_ERROR;
+
+	conf = dev->chip_info;
+	if (conf == NULL)
+		return AGESA_ERROR;
+
+	if (info->SocketId >= ARRAY_SIZE(conf->spd_addr_lookup))
+		return AGESA_ERROR;
+	if (info->MemChannelId >= ARRAY_SIZE(conf->spd_addr_lookup[0]))
+		return AGESA_ERROR;
+	if (info->DimmId >= ARRAY_SIZE(conf->spd_addr_lookup[0][0]))
+		return AGESA_ERROR;
+
+	spd_address = conf->spd_addr_lookup
+		[info->SocketId][info->MemChannelId][info->DimmId];
+	if (spd_address == 0)
+		return AGESA_ERROR;
+
+	err = mainboard_read_spd(spd_address, (void *)info->Buffer,
+				CONFIG_DIMM_SPD_SIZE);
+
+	/* Read the SPD if the mainboard didn't fill the buffer */
+	if (err || (*info->Buffer == 0))
+		err = sb_read_spd(spd_address, (void *)info->Buffer,
+				CONFIG_DIMM_SPD_SIZE);
+
+	if (err)
+		return AGESA_ERROR;
+
+	return AGESA_SUCCESS;
+}
+
+AGESA_STATUS agesa_HaltThisAp(uint32_t Func, uintptr_t Data, void *ConfigPtr)
+{
+	AGESA_HALT_THIS_AP_PARAMS *info = ConfigPtr;
+	uint32_t flags = 0;
+
+	if (info->PrimaryCore == TRUE)
+		return AGESA_UNSUPPORTED; /* force normal path */
+	if (info->ExecWbinvd == TRUE)
+		flags |= 1;
+	if (info->CacheEn == TRUE)
+		flags |= 2;
+
+	ap_teardown_car(flags); /* does not return */
+
+	/* Should never reach here */
+	return AGESA_UNSUPPORTED;
+}
+
+/* Allow mainboards to fill the SPD buffer */
+__weak int mainboard_read_spd(uint8_t spdAddress, char *buf,
+						size_t len)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return -1; /* SPD not read */
+}
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
new file mode 100644
index 0000000..ba82565
--- /dev/null
+++ b/src/soc/amd/picasso/Kconfig
@@ -0,0 +1,389 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2017 Advanced Micro Devices, Inc.
+##
+## 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.
+##
+
+config SOC_AMD_STONEYRIDGE_FP4
+	bool
+	help
+	  AMD Stoney Ridge FP4 support
+
+config SOC_AMD_STONEYRIDGE_FT4
+	bool
+	help
+	  AMD Stoney Ridge FT4 support
+
+if SOC_AMD_STONEYRIDGE_FP4 || SOC_AMD_STONEYRIDGE_FT4
+
+config CPU_SPECIFIC_OPTIONS
+	def_bool y
+	select ARCH_BOOTBLOCK_X86_32
+	select ARCH_VERSTAGE_X86_32
+	select ARCH_ROMSTAGE_X86_32
+	select ARCH_RAMSTAGE_X86_32
+	select X86_AMD_FIXED_MTRRS
+	select ACPI_AMD_HARDWARE_SLEEP_VALUES
+	select COLLECT_TIMESTAMPS_NO_TSC
+	select DRIVERS_I2C_DESIGNWARE
+	select GENERIC_GPIO_LIB
+	select GENERIC_UDELAY
+	select IOAPIC
+	select HAVE_USBDEBUG_OPTIONS
+	select HAVE_MONOTONIC_TIMER
+	select SPI_FLASH if HAVE_ACPI_RESUME
+	select TSC_SYNC_LFENCE
+	select COLLECT_TIMESTAMPS
+	select SOC_AMD_PI
+	select SOC_AMD_COMMON
+	select SOC_AMD_COMMON_BLOCK
+	select SOC_AMD_COMMON_BLOCK_IOMMU
+	select SOC_AMD_COMMON_BLOCK_ACPIMMIO
+	select SOC_AMD_COMMON_BLOCK_BANKED_GPIOS
+	select SOC_AMD_COMMON_BLOCK_ACPI
+	select SOC_AMD_COMMON_BLOCK_LPC
+	select SOC_AMD_COMMON_BLOCK_PCI
+	select SOC_AMD_COMMON_BLOCK_HDA
+	select SOC_AMD_COMMON_BLOCK_SATA
+	select SOC_AMD_COMMON_BLOCK_PI
+	select SOC_AMD_COMMON_BLOCK_PSP
+	select SOC_AMD_COMMON_BLOCK_CAR
+	select SOC_AMD_COMMON_BLOCK_S3
+	select C_ENVIRONMENT_BOOTBLOCK
+	select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH
+	select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH
+	select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
+	select PARALLEL_MP
+	select PARALLEL_MP_AP_WORK
+	select HAVE_SMI_HANDLER
+	select SMM_TSEG
+	select POSTCAR_STAGE
+	select POSTCAR_CONSOLE
+	select SSE2
+	select RTC
+	select SOC_AMD_PSP_SELECTABLE_SMU_FW
+
+config VBOOT
+	select VBOOT_SEPARATE_VERSTAGE
+	select VBOOT_STARTS_IN_BOOTBLOCK
+	select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT
+	select VBOOT_VBNV_CMOS
+	select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH
+
+config UDELAY_LAPIC_FIXED_FSB
+	int
+	default 200
+
+# TODO: Sync these with definitions in PI vendorcode.
+# DCACHE_RAM_BASE must equal BSP_STACK_BASE_ADDR.
+# DCACHE_RAM_SIZE must equal BSP_STACK_SIZE.
+
+config DCACHE_RAM_BASE
+	hex
+	default 0x30000
+
+config DCACHE_RAM_SIZE
+	hex
+	default 0x10000
+
+config DCACHE_BSP_STACK_SIZE
+	depends on C_ENVIRONMENT_BOOTBLOCK
+	hex
+	default 0x4000
+	help
+	  The amount of anticipated stack usage in CAR by bootblock and
+	  other stages.
+
+config PRERAM_CBMEM_CONSOLE_SIZE
+	hex
+	default 0x1600
+	help
+	  Increase this value if preram cbmem console is getting truncated
+
+config CPU_ADDR_BITS
+	int
+	default 48
+
+config BOTTOMIO_POSITION
+	hex "Bottom of 32-bit IO space"
+	default 0xD0000000
+	help
+	  If PCI peripherals with big BARs are connected to the system
+	  the bottom of the IO must be decreased to allocate such
+	  devices.
+
+	  Declare the beginning of the 128MB-aligned MMIO region.  This
+	  option is useful when PCI peripherals requesting large address
+	  ranges are present.
+
+config MMCONF_BASE_ADDRESS
+	hex
+	default 0xF8000000
+
+config MMCONF_BUS_NUMBER
+	int
+	default 64
+
+config VGA_BIOS_ID
+	string
+	default "1002,98e4"
+	help
+	  The default VGA BIOS PCI vendor/device ID should be set to the
+	  result of the map_oprom_vendev() function in northbridge.c.
+
+config VGA_BIOS_FILE
+	string
+	default "3rdparty/blobs/soc/amd/stoneyridge/VBIOS.bin"
+
+config S3_VGA_ROM_RUN
+	bool
+	default n
+
+config HEAP_SIZE
+	hex
+	default 0xc0000
+
+config EHCI_BAR
+	hex
+	default 0xfef00000
+
+config STONEYRIDGE_XHCI_ENABLE
+	bool "Enable Stoney Ridge XHCI Controller"
+	default y
+	help
+	  The XHCI controller must be enabled and the XHCI firmware
+	  must be added in order to have USB 3.0 support configured
+	  by coreboot. The OS will be responsible for enabling the XHCI
+	  controller if the XHCI firmware is available but the
+	  XHCI controller is not enabled by coreboot.
+
+config STONEYRIDGE_XHCI_FWM
+	bool "Add xhci firmware"
+	default y
+	help
+	  Add Stoney Ridge XHCI Firmware to support the onboard USB 3.0
+
+config STONEYRIDGE_GEC_FWM
+	bool
+	default n
+	help
+	  Add Stoney Ridge GEC Firmware to support the onboard gigabit Ethernet MAC.
+	  Must be connected to a Broadcom B50610 or B50610M PHY on the motherboard.
+
+config STONEYRIDGE_XHCI_FWM_FILE
+	string "XHCI firmware path and filename"
+	default "3rdparty/blobs/soc/amd/stoneyridge/xhci.bin"
+	depends on STONEYRIDGE_XHCI_FWM
+
+config STONEYRIDGE_GEC_FWM_FILE
+	string "GEC firmware path and filename"
+	depends on STONEYRIDGE_GEC_FWM
+
+config AMD_PUBKEY_FILE
+	string "AMD public Key"
+	default "3rdparty/blobs/soc/amd/stoneyridge/PSP/AmdPubKeyST.bin"
+
+config STONEYRIDGE_SATA_MODE
+	int "SATA Mode"
+	default 0
+	range 0 6
+	help
+	  Select the mode in which SATA should be driven.
+	  The default is NATIVE.
+	  0: NATIVE mode does not require a ROM.
+	  2: AHCI may work with or without AHCI ROM. It depends on the payload support.
+	     For example, seabios does not require the AHCI ROM.
+	  3: LEGACY IDE
+	  4: IDE to AHCI
+	  5: AHCI7804: ROM Required, and AMD driver required in the OS.
+	  6: IDE to AHCI7804: ROM Required, and AMD driver required in the OS.
+
+comment "NATIVE"
+	depends on STONEYRIDGE_SATA_MODE = 0
+
+comment "AHCI"
+	depends on STONEYRIDGE_SATA_MODE = 2
+
+comment "LEGACY IDE"
+	depends on STONEYRIDGE_SATA_MODE = 3
+
+comment "IDE to AHCI"
+	depends on STONEYRIDGE_SATA_MODE = 4
+
+comment "AHCI7804"
+	depends on STONEYRIDGE_SATA_MODE = 5
+
+comment "IDE to AHCI7804"
+	depends on STONEYRIDGE_SATA_MODE = 6
+
+if STONEYRIDGE_SATA_MODE = 2 || STONEYRIDGE_SATA_MODE = 5
+
+config AHCI_ROM_ID
+	string  "AHCI device PCI IDs"
+	default "1022,7801" if STONEYRIDGE_SATA_MODE = 2
+	default "1022,7804" if STONEYRIDGE_SATA_MODE = 5
+
+endif # STONEYRIDGE_SATA_MODE = 2 || STONEYRIDGE_SATA_MODE = 5
+
+config STONEYRIDGE_LEGACY_FREE
+	bool "System is legacy free"
+	help
+	  Select y if there is no keyboard controller in the system.
+	  This sets variables in AGESA and ACPI.
+
+config SERIRQ_CONTINUOUS_MODE
+	bool
+	default n
+	help
+	  Set this option to y for serial IRQ in continuous mode.
+	  Otherwise it is in quiet mode.
+
+config STONEYRIDGE_ACPI_IO_BASE
+	hex
+	default 0x400
+	help
+	  Base address for the ACPI registers.
+	  This value must match the hardcoded value of AGESA.
+
+config STONEYRIDGE_UART
+	bool "UART controller on Stoney Ridge"
+	default n
+	select DRIVERS_UART_8250MEM
+	select DRIVERS_UART_8250MEM_32
+	select NO_UART_ON_SUPERIO
+	select UART_OVERRIDE_REFCLK
+	help
+	  There are two UART controllers in Stoney Ridge.
+	  The UART registers are memory-mapped. UART
+	  controller 0 registers range from FEDC_6000h
+	  to FEDC_6FFFh. UART controller 1 registers
+	  range from FEDC_8000h to FEDC_8FFFh.
+
+config CONSOLE_UART_BASE_ADDRESS
+	depends on CONSOLE_SERIAL
+	hex
+	default 0xfedc6000
+
+config SMM_TSEG_SIZE
+	hex
+	default 0x800000 if SMM_TSEG && HAVE_SMI_HANDLER
+	default 0x0
+
+config SMM_RESERVED_SIZE
+	hex
+	default 0x150000
+
+config SMM_MODULE_STACK_SIZE
+	hex
+	default 0x800
+
+config ACPI_CPU_STRING
+	string
+	default "\\_PR.P%03d"
+
+config ACPI_BERT
+	bool "Build ACPI BERT Table"
+	default y
+	depends on HAVE_ACPI_TABLES
+	help
+	  Report Machine Check errors identified in POST to the OS in an
+	  ACPI Boot Error Record Table.  This option reserves an 8MB region
+	  for building the error structures.
+
+config USE_PSPSECUREOS
+	bool "Include PSP SecureOS blobs in AMD firmware"
+	default y
+	help
+	  Include the PspSecureOs, PspTrustlet and TrustletKey binaries
+	  in the amdfw section.
+
+	  If unsure, answer 'y'
+
+config SOC_AMD_SMU_FANLESS
+	bool
+	depends on SOC_AMD_PSP_SELECTABLE_SMU_FW
+	default n if SOC_AMD_SMU_NOTFANLESS
+	default y
+
+config SOC_AMD_SMU_FANNED
+	bool
+	depends on SOC_AMD_PSP_SELECTABLE_SMU_FW
+	default n
+	select SOC_AMD_SMU_NOTFANLESS
+
+config SOC_AMD_SMU_NOTFANLESS	# helper symbol - do not use
+	bool
+	depends on SOC_AMD_PSP_SELECTABLE_SMU_FW
+
+config AMDFW_OUTSIDE_CBFS
+	bool "The AMD firmware is outside CBFS"
+	default n
+	help
+	  The AMDFW (PSP) is typically locatable in cbfs.  Select this
+	  option to manually attach the generated amdfw.rom outside of
+	  cbfs.  The location is selected by the FWM position.
+
+config AMD_FWM_POSITION_INDEX
+	int "Firmware Directory Table location (0 to 5)"
+	range 0 5
+	default 0 if BOARD_ROMSIZE_KB_512
+	default 1 if BOARD_ROMSIZE_KB_1024
+	default 2 if BOARD_ROMSIZE_KB_2048
+	default 3 if BOARD_ROMSIZE_KB_4096
+	default 4 if BOARD_ROMSIZE_KB_8192
+	default 5 if BOARD_ROMSIZE_KB_16384
+	help
+	  Typically this is calculated by the ROM size, but there may
+	  be situations where you want to put the firmware directory
+	  table in a different location.
+	    0: 512 KB - 0xFFFA0000
+	    1: 1 MB   - 0xFFF20000
+	    2: 2 MB   - 0xFFE20000
+	    3: 4 MB   - 0xFFC20000
+	    4: 8 MB   - 0xFF820000
+	    5: 16 MB  - 0xFF020000
+
+comment "AMD Firmware Directory Table set to location for 512KB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 0
+comment "AMD Firmware Directory Table set to location for 1MB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 1
+comment "AMD Firmware Directory Table set to location for 2MB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 2
+comment "AMD Firmware Directory Table set to location for 4MB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 3
+comment "AMD Firmware Directory Table set to location for 8MB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 4
+comment "AMD Firmware Directory Table set to location for 16MB ROM"
+	depends on AMD_FWM_POSITION_INDEX = 5
+
+config DIMM_SPD_SIZE
+	int
+	default 512	# DDR4
+
+config RO_REGION_ONLY
+	string
+	depends on CHROMEOS
+	default "apu/amdfw"
+
+config DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ
+	int
+	default 133
+
+config MAINBOARD_POWER_RESTORE
+	def_bool n
+	help
+	  This option determines what state to go to once power is restored
+	  after having been lost in S0.  Select this option to automatically
+	  return to S0.  Otherwise the system will remain in S5 once power
+	  is restored.
+
+endif # SOC_AMD_STONEYRIDGE_FP4 || SOC_AMD_STONEYRIDGE_FT4
diff --git a/src/soc/amd/picasso/acpi.c b/src/soc/amd/picasso/acpi.c
new file mode 100644
index 0000000..d1ea24f
--- /dev/null
+++ b/src/soc/amd/picasso/acpi.c
@@ -0,0 +1,406 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012, 2017 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.
+ */
+
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <device/pci_ops.h>
+#include <arch/ioapic.h>
+#include <cpu/x86/smm.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <amdblocks/acpimmio.h>
+#include <amdblocks/acpi.h>
+#include <soc/acpi.h>
+#include <soc/pci_devs.h>
+#include <soc/southbridge.h>
+#include <soc/northbridge.h>
+#include <soc/nvs.h>
+#include <soc/gpio.h>
+#include <version.h>
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+	/* create all subtables for processors */
+	current = acpi_create_madt_lapics(current);
+
+	/* Write Kern IOAPIC, only one */
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current,
+			CONFIG_MAX_CPUS, IO_APIC_ADDR, 0);
+
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current,
+			CONFIG_MAX_CPUS+1, IO_APIC2_ADDR, 24);
+
+	/* 0: mean bus 0--->ISA */
+	/* 0: PIC 0 */
+	/* 2: APIC 2 */
+	/* 5 mean: 0101 --> Edge-triggered, Active high */
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+						current, 0, 0, 2, 0);
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+						current, 0, 9, 9, 0xf);
+
+	/* create all subtables for processors */
+	current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current,
+			0xff, 5, 1);
+	/* 1: LINT1 connect to NMI */
+
+	return current;
+}
+
+/*
+ * Reference section 5.2.9 Fixed ACPI Description Table (FADT)
+ * in the ACPI 3.0b specification.
+ */
+void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
+{
+	acpi_header_t *header = &(fadt->header);
+
+	printk(BIOS_DEBUG, "pm_base: 0x%04x\n", STONEYRIDGE_ACPI_IO_BASE);
+
+	/* Prepare the header */
+	memset((void *)fadt, 0, sizeof(acpi_fadt_t));
+	memcpy(header->signature, "FACP", 4);
+	header->length = sizeof(acpi_fadt_t);
+	header->revision = get_acpi_table_revision(FADT);
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+	header->asl_compiler_revision = asl_revision;
+
+	fadt->firmware_ctrl = (u32) facs;
+	fadt->dsdt = (u32) dsdt;
+	fadt->reserved = 0;		/* reserved, should be 0 ACPI 3.0 */
+	fadt->preferred_pm_profile = FADT_PM_PROFILE;
+	fadt->sci_int = 9;		/* IRQ 09 - ACPI SCI */
+
+	if (CONFIG(HAVE_SMI_HANDLER)) {
+		fadt->smi_cmd = APM_CNT;
+		fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+		fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+		fadt->s4bios_req = 0;	/* Not supported */
+		fadt->pstate_cnt = 0;	/* Not supported */
+		fadt->cst_cnt = 0;	/* Not supported */
+		acpi_disable_sci();
+	} else {
+		fadt->smi_cmd = 0;	/* disable system management mode */
+		fadt->acpi_enable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->acpi_disable = 0;	/* unused if SMI_CMD = 0 */
+		fadt->s4bios_req = 0;	/* unused if SMI_CMD = 0 */
+		fadt->pstate_cnt = 0;	/* unused if SMI_CMD = 0 */
+		fadt->cst_cnt = 0x00;	/* unused if SMI_CMD = 0 */
+		acpi_enable_sci();
+	}
+
+	fadt->pm1a_evt_blk = ACPI_PM_EVT_BLK;
+	fadt->pm1b_evt_blk = 0x0000;
+	fadt->pm1a_cnt_blk = ACPI_PM1_CNT_BLK;
+	fadt->pm1b_cnt_blk = 0x0000;
+	fadt->pm2_cnt_blk = 0x0000;
+	fadt->pm_tmr_blk = ACPI_PM_TMR_BLK;
+	fadt->gpe0_blk = ACPI_GPE0_BLK;
+	fadt->gpe1_blk = 0x0000;		/* No gpe1 block  */
+
+	fadt->pm1_evt_len = 4;	/* 32 bits */
+	fadt->pm1_cnt_len = 2;	/* 16 bits */
+	fadt->pm2_cnt_len = 0;
+	fadt->pm_tmr_len = 4;	/* 32 bits */
+	fadt->gpe0_blk_len = 8;	/* 64 bits */
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+
+	fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
+	fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
+	fadt->flush_size = 0;	/* set to 0 if WBINVD is 1 in flags */
+	fadt->flush_stride = 0;	/* set to 0 if WBINVD is 1 in flags */
+	fadt->duty_offset = 1;	/* CLK_VAL bits 3:1 */
+	fadt->duty_width = 3;	/* CLK_VAL bits 3:1 */
+	fadt->day_alrm = 0;	/* 0x7d these have to be */
+	fadt->mon_alrm = 0;	/* 0x7e added to cmos.layout */
+	fadt->century = 0;	/* 0x7f to make rtc alarm work */
+	fadt->iapc_boot_arch = FADT_BOOT_ARCH;	/* See table 5-10 */
+	fadt->res2 = 0;		/* reserved, MUST be 0 ACPI 3.0 */
+	fadt->flags = ACPI_FADT_WBINVD | /* See table 5-10 ACPI 3.0a spec */
+				ACPI_FADT_C1_SUPPORTED |
+				ACPI_FADT_SLEEP_BUTTON |
+				ACPI_FADT_S4_RTC_WAKE |
+				ACPI_FADT_32BIT_TIMER |
+				ACPI_FADT_RESET_REGISTER |
+				ACPI_FADT_PCI_EXPRESS_WAKE |
+				ACPI_FADT_PLATFORM_CLOCK |
+				ACPI_FADT_S4_RTC_VALID |
+				ACPI_FADT_REMOTE_POWER_ON;
+
+	/* Format is from 5.2.3.1: Generic Address Structure */
+	/* reset_reg: see section 4.7.3.6 ACPI 3.0a spec */
+	/* 8 bit write of value 0x06 to 0xCF9 in IO space */
+	fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->reset_reg.addrl = SYS_RESET;
+	fadt->reset_reg.addrh = 0x0;
+
+	fadt->reset_value = 6;
+
+	fadt->ARM_boot_arch = 0;	/* MUST be 0 ACPI 3.0 */
+	fadt->FADT_MinorVersion = 0;	/* MUST be 0 ACPI 3.0 */
+
+	fadt->x_firmware_ctl_l = 0;	/* set to 0 if firmware_ctrl is used */
+	fadt->x_firmware_ctl_h = 0;
+	fadt->x_dsdt_l = (u32) dsdt;
+	fadt->x_dsdt_h = 0;
+
+	fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_evt_blk.bit_width = 32;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
+	fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_evt_blk.bit_width = 0;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.access_size = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+
+	fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1a_cnt_blk.bit_width = 16;
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.access_size = 0;
+	fadt->x_pm1a_cnt_blk.addrl = ACPI_PM1_CNT_BLK;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm1b_cnt_blk.bit_width = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.access_size = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+	/*
+	 * Note: Under this current AMD C state implementation, this is no
+	 *       longer used and should not be reported to OS.
+	 */
+	fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm2_cnt_blk.bit_width = 0;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
+	fadt->x_pm2_cnt_blk.addrl = 0;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+
+	fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_pm_tmr_blk.bit_width = 32;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK;
+	fadt->x_pm_tmr_blk.addrh = 0x0;
+
+
+	fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + Event Enable */
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
+	fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK;
+	fadt->x_gpe0_blk.addrh = 0x0;
+
+
+	fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.access_size = 0;
+	fadt->x_gpe1_blk.addrl = 0;
+	fadt->x_gpe1_blk.addrh = 0x0;
+
+	header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
+}
+
+void generate_cpu_entries(struct device *device)
+{
+	int cores, cpu;
+
+	/* Stoney Ridge is single node, just report # of cores */
+	cores = pci_read_config32(SOC_NB_DEV, NB_CAPABILITIES2) & CMP_CAP_MASK;
+	cores++; /* number of cores is CmpCap+1 */
+
+	printk(BIOS_DEBUG, "ACPI \\_PR report %d core(s)\n", cores);
+
+	/* Generate BSP \_PR.P000 */
+	acpigen_write_processor(0, ACPI_GPE0_BLK, 6);
+	acpigen_pop_len();
+
+	/* Generate AP \_PR.Pxxx */
+	for (cpu = 1; cpu < cores; cpu++) {
+		acpigen_write_processor(cpu, 0, 0);
+		acpigen_pop_len();
+	}
+}
+
+unsigned long southbridge_write_acpi_tables(struct device *device,
+		unsigned long current,
+		struct acpi_rsdp *rsdp)
+{
+	return acpi_write_hpet(device, current, rsdp);
+}
+
+static void acpi_create_gnvs(struct global_nvs_t *gnvs)
+{
+	/* Clear out GNVS. */
+	memset(gnvs, 0, sizeof(*gnvs));
+
+	if (CONFIG(CONSOLE_CBMEM))
+		gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE);
+
+	if (CONFIG(CHROMEOS)) {
+		/* Initialize Verified Boot data */
+		chromeos_init_chromeos_acpi(&gnvs->chromeos);
+		gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO;
+	}
+
+	/* Set unknown wake source */
+	gnvs->pm1i = ~0ULL;
+	gnvs->gpei = ~0ULL;
+
+	/* CPU core count */
+	gnvs->pcnt = dev_count_cpu();
+}
+
+void southbridge_inject_dsdt(struct device *device)
+{
+	struct global_nvs_t *gnvs;
+
+	gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+
+	if (gnvs) {
+		acpi_create_gnvs(gnvs);
+
+		/* Add it to DSDT */
+		acpigen_write_scope("\\");
+		acpigen_write_name_dword("NVSA", (uintptr_t)gnvs);
+		acpigen_pop_len();
+	}
+}
+
+static void acpigen_soc_get_gpio_in_local5(uintptr_t addr)
+{
+	/*
+	 *   Store (\_SB.GPR2 (addr), Local5)
+	 * \_SB.GPR2 is used to read control byte 2 from control register.
+	 * / It is defined in gpio_lib.asl.
+	 */
+	acpigen_write_store();
+	acpigen_emit_namestring("\\_SB.GPR2");
+	acpigen_write_integer(addr);
+	acpigen_emit_byte(LOCAL5_OP);
+}
+
+static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask)
+{
+	if (gpio_num >= SOC_GPIO_TOTAL_PINS) {
+		printk(BIOS_WARNING, "Warning: Pin %d should be smaller than"
+					" %d\n", gpio_num, SOC_GPIO_TOTAL_PINS);
+		return -1;
+	}
+	uintptr_t addr = (uintptr_t) gpio_get_address(gpio_num);
+
+	acpigen_soc_get_gpio_in_local5(addr);
+
+	/* If (And (Local5, mask)) */
+	acpigen_write_if_and(LOCAL5_OP, mask);
+
+	/* Store (One, Local0) */
+	acpigen_write_store_ops(ONE_OP, LOCAL0_OP);
+
+	acpigen_pop_len();	/* If */
+
+	/* Else */
+	acpigen_write_else();
+
+	/* Store (Zero, Local0) */
+	acpigen_write_store_ops(ZERO_OP, LOCAL0_OP);
+
+	acpigen_pop_len();	/* Else */
+
+	return 0;
+}
+
+static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val)
+{
+	if (gpio_num >= SOC_GPIO_TOTAL_PINS) {
+		printk(BIOS_WARNING, "Warning: Pin %d should be smaller than"
+					" %d\n", gpio_num, SOC_GPIO_TOTAL_PINS);
+		return -1;
+	}
+	uintptr_t addr = (uintptr_t) gpio_get_address(gpio_num);
+
+	/* Store (0x40, Local0) */
+	acpigen_write_store();
+	acpigen_write_integer(GPIO_PIN_OUT);
+	acpigen_emit_byte(LOCAL0_OP);
+
+	acpigen_soc_get_gpio_in_local5(addr);
+
+	if (val) {
+		/* Or (Local5, GPIO_PIN_OUT, Local5) */
+		acpigen_write_or(LOCAL5_OP, LOCAL0_OP, LOCAL5_OP);
+	} else {
+		/* Not (GPIO_PIN_OUT, Local6) */
+		acpigen_write_not(LOCAL0_OP, LOCAL6_OP);
+
+		/* And (Local5, Local6, Local5) */
+		acpigen_write_and(LOCAL5_OP, LOCAL6_OP, LOCAL5_OP);
+	}
+
+	/*
+	 *   SB.GPW2 (addr, Local5)
+	 * \_SB.GPW2 is used to write control byte in control register
+	 * / byte 2. It is defined in gpio_lib.asl.
+	 */
+	acpigen_emit_namestring("\\_SB.GPW2");
+	acpigen_write_integer(addr);
+	acpigen_emit_byte(LOCAL5_OP);
+
+	return 0;
+}
+
+int acpigen_soc_read_rx_gpio(unsigned int gpio_num)
+{
+	return acpigen_soc_get_gpio_val(gpio_num, GPIO_PIN_IN);
+}
+
+int acpigen_soc_get_tx_gpio(unsigned int gpio_num)
+{
+	return acpigen_soc_get_gpio_val(gpio_num, GPIO_PIN_OUT);
+}
+
+int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
+{
+	return acpigen_soc_set_gpio_val(gpio_num, 1);
+}
+
+int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
+{
+	return acpigen_soc_set_gpio_val(gpio_num, 0);
+}
diff --git a/src/soc/amd/picasso/acpi/acpi_wake_source.asl b/src/soc/amd/picasso/acpi/acpi_wake_source.asl
new file mode 100644
index 0000000..fa01802
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/acpi_wake_source.asl
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.
+ */
+
+Scope (\_SB)
+{
+	Method (_SWS)
+	{
+		/* Index into PM1 for device that caused wake */
+		Return (\PM1I)
+	}
+}
+
+Scope (\_GPE)
+{
+	Method (_SWS)
+	{
+		/* Index into GPE for device that caused wake */
+		Return (\GPEI)
+	}
+}
diff --git a/src/soc/amd/picasso/acpi/cpu.asl b/src/soc/amd/picasso/acpi/cpu.asl
new file mode 100644
index 0000000..414326e
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/cpu.asl
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ */
+
+/* Required function by EC, Notify OS to re-read CPU tables */
+Method (PNOT)
+{
+}
+
+/*
+ * Processor Object
+ */
+/* These devices are created at runtime */
+External (\_PR.P000, DeviceObj)
+External (\_PR.P001, DeviceObj)
+External (\_PR.P002, DeviceObj)
+External (\_PR.P003, DeviceObj)
+External (\_PR.P004, DeviceObj)
+External (\_PR.P005, DeviceObj)
+External (\_PR.P006, DeviceObj)
+External (\_PR.P007, DeviceObj)
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+	If (LGreaterEqual (\PCNT, 2)) {
+		Return (Package ()
+		{
+			\_PR.P000,
+			\_PR.P001
+		})
+	} Else {
+		Return (Package ()
+		{
+			\_PR.P000
+		})
+	}
+}
diff --git a/src/soc/amd/picasso/acpi/globalnvs.asl b/src/soc/amd/picasso/acpi/globalnvs.asl
new file mode 100644
index 0000000..03d205f
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/globalnvs.asl
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.)
+ *
+ * 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.
+ */
+
+/*
+ * NOTE: The layout of the GNVS structure below must match the layout in
+ * soc/amd/stoneyridge/include/soc/nvs.h !!!
+ *
+ */
+
+External (NVSA)
+
+OperationRegion (GNVS, SystemMemory, NVSA, 0x1000)
+Field (GNVS, ByteAcc, NoLock, Preserve)
+{
+	/* Miscellaneous */
+	Offset (0x00),
+	PCNT,	8,	// 0x00 - Processor Count
+	PPCM,	8,	// 0x01 - Max PPC State
+	LIDS,	8,	// 0x02 - LID State
+	PWRS,	8,	// 0x03 - AC Power State
+	DPTE,	8,	// 0x04 - Enable DPTF
+	CBMC,	32,	// 0x05 - 0x08 - coreboot Memory Console
+	PM1I,	64,	// 0x09 - 0x10 - System Wake Source - PM1 Index
+	GPEI,	64,	// 0x11 - 0x18 - GPE Wake Source
+	NHLA,	64,	// 0x19 - 0x20 - NHLT Address
+	NHLL,	32,	// 0x21 - 0x24 - NHLT Length
+	PRT0,	32,	// 0x25 - 0x28 - PERST_0 Address
+	SCDP,	8,	// 0x29 - SD_CD GPIO portid
+	SCDO,	8,	// 0x2A - GPIO pad offset relative to the community
+	TMPS,	8,	// 0x2B - Temperature Sensor ID
+	TLVL,	8,	// 0x2C - Throttle Level Limit
+	FLVL,	8,	// 0x2D - Current FAN Level
+	TCRT,	8,	// 0x2E - Critical Threshold
+	TPSV,	8,	// 0x2F - Passive Threshold
+	TMAX,	8,	// 0x30 - CPU Tj_max
+	Offset (0x34),  // 0x34 - AOAC Device Enables
+	, 5,
+	IC0E,	1,	//        I2C0, 5
+	IC1E,	1,	//        I2C1, 6
+	IC2E,	1,	//        I2C2, 7
+	IC3E,	1,	//        I2C3, 8
+	, 2,
+	UT0E,	1,	//        UART0, 11
+	UT1E,	1,	//        UART1, 12
+	, 2,
+	ST_E,	1,	//        SATA, 15
+	, 2,
+	EHCE,	1,	//        EHCI, 18
+	, 4,
+	XHCE,	1,	//        XCHI, 23
+	SD_E,	1,	//        SD, 24
+	, 2,
+	ESPI,	1,	//        ESPI, 27
+	, 4,
+	FW00,	16,	// 0x38 - xHCI FW ROM addr, boot RAM
+	FW02,	16,	// 0x3A - xHCI FW ROM addr, Instruction RAM
+	FW01,	32,	// 0x3C - xHCI FW RAM addr, boot RAM
+	FW03,	32,	// 0x40 - xHCI FW RAM addr, Instruction RAM
+	EH10,	32,	// 0x44 - EHCI BAR
+	/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
+	Offset (0x100),
+	#include <vendorcode/google/chromeos/acpi/gnvs.asl>
+}
diff --git a/src/soc/amd/picasso/acpi/northbridge.asl b/src/soc/amd/picasso/acpi/northbridge.asl
new file mode 100644
index 0000000..fe78534
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/northbridge.asl
@@ -0,0 +1,134 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ * Copyright (C) 2016 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+/* Note: Only need HID on Primary Bus */
+External (TOM1)
+External (TOM2)
+Name(_HID, EISAID("PNP0A08"))	/* PCI Express Root Bridge */
+Name(_CID, EISAID("PNP0A03"))	/* PCI Root Bridge */
+Name(_ADR, 0x00180000)	/* Dev# = BSP Dev#, Func# = 0 */
+
+/* Describe the Northbridge devices */
+
+Method(_BBN, 0, NotSerialized)	/* Bus number = 0 */
+{
+	Return(Zero)
+}
+
+Method(_STA, 0, NotSerialized)
+{
+	Return(0x0B)	/* Status is visible */
+}
+
+Method(_PRT,0, NotSerialized)
+{
+	If(PMOD)
+	{
+		Return(APR0)	/* APIC mode */
+	}
+	Return (PR0)		/* PIC Mode */
+}
+
+Device(AMRT) {
+	Name(_ADR, 0x00000000)
+} /* end AMRT */
+
+/* Internal Graphics */
+Device(IGFX) {
+	Name(_ADR, 0x00010000)
+}
+
+/* Gpp 0 */
+Device(PBR4) {
+	Name(_ADR, 0x00020001)
+	Method(_PRT,0) {
+		If(PMOD){ Return(APS4) }	/* APIC mode */
+		Return (PS4)			/* PIC Mode */
+	} /* end _PRT */
+} /* end PBR4 */
+
+/* Gpp 1 */
+Device(PBR5) {
+	Name(_ADR, 0x00020002)
+	Method(_PRT,0) {
+		If(PMOD){ Return(APS5) }	/* APIC mode */
+		Return (PS5)			/* PIC Mode */
+	} /* end _PRT */
+} /* end PBR5 */
+
+/* Gpp 2 */
+Device(PBR6) {
+	Name(_ADR, 0x00020003)
+	Method(_PRT,0) {
+		If(PMOD){ Return(APS6) }	/* APIC mode */
+		Return (PS6)			/* PIC Mode */
+	} /* end _PRT */
+} /* end PBR6 */
+
+/* Gpp 3 */
+Device(PBR7) {
+	Name(_ADR, 0x00020004)
+	Method(_PRT,0) {
+		If(PMOD){ Return(APS7) }	/* APIC mode */
+		Return (PS7)			/* PIC Mode */
+	} /* end _PRT */
+} /* end PBR7 */
+
+/* Gpp 4 */
+Device(PBR8) {
+	Name(_ADR, 0x00020005)
+	Method(_PRT,0) {
+		If(PMOD){ Return(APS8) }	/* APIC mode */
+		Return (PS8)			/* PIC Mode */
+	} /* end _PRT */
+} /* end PBR8 */
+
+Device(AZHD) {	/* 0:9.2 - HD Audio */
+	Name(_ADR, 0x00090002)
+	OperationRegion(AZPD, PCI_Config, 0x00, 0x100)
+		Field(AZPD, AnyAcc, NoLock, Preserve) {
+		offset (0x42),
+		NSDI, 1,
+		NSDO, 1,
+		NSEN, 1,
+		offset (0x44),
+		IPCR, 4,
+		offset (0x54),
+		PWST, 2,
+		, 6,
+		PMEB, 1,
+		, 6,
+		PMST, 1,
+		offset (0x62),
+		MMCR, 1,
+		offset (0x64),
+		MMLA, 32,
+		offset (0x68),
+		MMHA, 32,
+		offset (0x6c),
+		MMDT, 16,
+	}
+
+	Method (_INI, 0, NotSerialized)
+	{
+		If (LEqual (OSVR, 0x03))
+		{
+			Store (Zero, NSEN)
+			Store (One, NSDO)
+			Store (One, NSDI)
+		}
+	}
+} /* end AZHD */
diff --git a/src/soc/amd/picasso/acpi/pci_int.asl b/src/soc/amd/picasso/acpi/pci_int.asl
new file mode 100644
index 0000000..617b9eb
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/pci_int.asl
@@ -0,0 +1,469 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ */
+
+	/* PCIe Configuration Space for CONFIG_MMCONF_BUS_NUMBER busses */
+	OperationRegion(PCFG, SystemMemory, PCBA, PCLN) /* Each bus consumes 1MB */
+		Field(PCFG, ByteAcc, NoLock, Preserve) {
+		/* Byte offsets are computed using the following technique:
+		 * ((bus number + 1) * ((device number * 8) * 4096)) + register offset
+		 * The 8 comes from 8 functions per device, and 4096 bytes per function config space
+		*/
+		Offset(0x00088024),	/* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */
+		STB5, 32,
+		Offset(0x00098042),	/* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */
+		PT0D, 1,
+		PT1D, 1,
+		PT2D, 1,
+		PT3D, 1,
+		PT4D, 1,
+		PT5D, 1,
+		PT6D, 1,
+		PT7D, 1,
+		PT8D, 1,
+		PT9D, 1,
+		Offset(0x000a0004),	/* Byte offset to SMBUS register 4h - Bus 0, Device 20, Function 0 */
+		SBIE, 1,
+		SBME, 1,
+		Offset(0x000a0008),	/* Byte offset to SMBUS register 8h - Bus 0, Device 20, Function 0 */
+		SBRI, 8,
+		Offset(0x000a0014),	/* Byte offset to SMBUS register 14h - Bus 0, Device 20, Function 0 */
+		SBB1, 32,
+		Offset(0x000a0078),	/* Byte offset to SMBUS register 78h - Bus 0, Device 20, Function 0 */
+		,14,
+		P92E, 1,		/* Port92 decode enable */
+	}
+
+	OperationRegion(SB5, SystemMemory, STB5, 0x1000)
+		Field(SB5, AnyAcc, NoLock, Preserve){
+		/* Port 0 */
+		Offset(0x120),		/* Port 0 Task file status */
+		P0ER, 1,
+		, 2,
+		P0DQ, 1,
+		, 3,
+		P0BY, 1,
+		Offset(0x128),		/* Port 0 Serial ATA status */
+		P0DD, 4,
+		, 4,
+		P0IS, 4,
+		Offset(0x12c),		/* Port 0 Serial ATA control */
+		P0DI, 4,
+		Offset(0x130),		/* Port 0 Serial ATA error */
+		, 16,
+		P0PR, 1,
+
+		/* Port 1 */
+		offset(0x1a0),		/* Port 1 Task file status */
+		P1ER, 1,
+		, 2,
+		P1DQ, 1,
+		, 3,
+		P1BY, 1,
+		Offset(0x1a8),		/* Port 1 Serial ATA status */
+		P1DD, 4,
+		, 4,
+		P1IS, 4,
+		Offset(0x1ac),		/* Port 1 Serial ATA control */
+		P1DI, 4,
+		Offset(0x1b0),		/* Port 1 Serial ATA error */
+		, 16,
+		P1PR, 1,
+
+		/* Port 2 */
+		Offset(0x220),		/* Port 2 Task file status */
+		P2ER, 1,
+		, 2,
+		P2DQ, 1,
+		, 3,
+		P2BY, 1,
+		Offset(0x228),		/* Port 2 Serial ATA status */
+		P2DD, 4,
+		, 4,
+		P2IS, 4,
+		Offset(0x22c),		/* Port 2 Serial ATA control */
+		P2DI, 4,
+		Offset(0x230),		/* Port 2 Serial ATA error */
+		, 16,
+		P2PR, 1,
+
+		/* Port 3 */
+		Offset(0x2a0),		/* Port 3 Task file status */
+		P3ER, 1,
+		, 2,
+		P3DQ, 1,
+		, 3,
+		P3BY, 1,
+		Offset(0x2a8),		/* Port 3 Serial ATA status */
+		P3DD, 4,
+		, 4,
+		P3IS, 4,
+		Offset(0x2aC),		/* Port 3 Serial ATA control */
+		P3DI, 4,
+		Offset(0x2b0),		/* Port 3 Serial ATA error */
+		, 16,
+		P3PR, 1,
+	}
+
+	Method(_PIC, 0x01, NotSerialized)
+	{
+		If (Arg0)
+		{
+			\_SB.CIRQ()
+		}
+		Store(Arg0, PMOD)
+	}
+
+	Method(CIRQ, 0x00, NotSerialized){
+	}
+
+	Name(IRQB, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Shared){15}
+	})
+
+	Name(IRQP, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Exclusive){3, 4, 5, 7, 10, 11, 12, 15}
+	})
+
+	Name(PITF, ResourceTemplate(){
+		IRQ(Level,ActiveLow,Exclusive){9}
+	})
+
+	Device(INTA) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 1)
+
+		Method(_STA, 0) {
+			if (PIRA) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTA._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_DIS\n") */
+		} /* End Method(_SB.INTA._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTA._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKA\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRA, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTA._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKA\\_SRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRA)
+		} /* End Method(_SB.INTA._SRS) */
+	} /* End Device(INTA) */
+
+	Device(INTB) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 2)
+
+		Method(_STA, 0) {
+			if (PIRB) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTB._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_DIS\n") */
+		} /* End Method(_SB.INTB._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTB._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKB\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRB, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTB._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKB\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRB)
+		} /* End Method(_SB.INTB._SRS) */
+	} /* End Device(INTB)  */
+
+	Device(INTC) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 3)
+
+		Method(_STA, 0) {
+			if (PIRC) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTC._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_DIS\n") */
+		} /* End Method(_SB.INTC._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTC._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKC\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRC, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTC._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKC\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRC)
+		} /* End Method(_SB.INTC._SRS) */
+	} /* End Device(INTC)  */
+
+	Device(INTD) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 4)
+
+		Method(_STA, 0) {
+			if (PIRD) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTD._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_DIS\n") */
+		} /* End Method(_SB.INTD._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTD._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKD\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRD, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTD._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKD\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRD)
+		} /* End Method(_SB.INTD._SRS) */
+	} /* End Device(INTD)  */
+
+	Device(INTE) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 5)
+
+		Method(_STA, 0) {
+			if (PIRE) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTE._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_DIS\n") */
+		} /* End Method(_SB.INTE._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTE._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKE\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRE, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTE._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKE\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRE)
+		} /* End Method(_SB.INTE._SRS) */
+	} /* End Device(INTE)  */
+
+	Device(INTF) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 6)
+
+		Method(_STA, 0) {
+			if (PIRF) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTF._STA) */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_DIS\n") */
+		} /* End Method(_SB.INTF._DIS) */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_PRS\n") */
+			Return(PITF)
+		} /* Method(_SB.INTF._PRS) */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKF\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRF, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTF._CRS) */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKF\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRF)
+		} /*  End Method(_SB.INTF._SRS) */
+	} /* End Device(INTF)  */
+
+	Device(INTG) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 7)
+
+		Method(_STA, 0) {
+			if (PIRG) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTG._STA)  */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_DIS\n") */
+		} /* End Method(_SB.INTG._DIS)  */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTG._CRS)  */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKG\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRG, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTG._CRS)  */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKG\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRG)
+		} /* End Method(_SB.INTG._SRS)  */
+	} /* End Device(INTG)  */
+
+	Device(INTH) {
+		Name(_HID, EISAID("PNP0C0F"))
+		Name(_UID, 8)
+
+		Method(_STA, 0) {
+			if (PIRH) {
+				Return(0x0b) /* sata is invisible */
+			} else {
+				Return(0x09) /* sata is disabled */
+			}
+		} /* End Method(_SB.INTH._STA)  */
+
+		Method(_DIS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_DIS\n") */
+		} /* End Method(_SB.INTH._DIS)  */
+
+		Method(_PRS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_PRS\n") */
+			Return(IRQP)
+		} /* Method(_SB.INTH._CRS)  */
+
+		Method(_CRS ,0) {
+			/* DBGO("\\_SB\\LNKH\\_CRS\n") */
+			CreateWordField(IRQB, 0x1, IRQN)
+			ShiftLeft(1, PIRH, IRQN)
+			Return(IRQB)
+		} /* Method(_SB.INTH._CRS)  */
+
+		Method(_SRS, 1) {
+			/* DBGO("\\_SB\\LNKH\\_CRS\n") */
+			CreateWordField(ARG0, 1, IRQM)
+
+			/* Use lowest available IRQ */
+			FindSetRightBit(IRQM, Local0)
+			if (Local0) {
+				Decrement(Local0)
+			}
+			Store(Local0, PIRH)
+		} /* End Method(_SB.INTH._SRS)  */
+	} /* End Device(INTH)   */
diff --git a/src/soc/amd/picasso/acpi/pcie.asl b/src/soc/amd/picasso/acpi/pcie.asl
new file mode 100644
index 0000000..9251872
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/pcie.asl
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ */
+
+	/* PCI IRQ mapping registers, C00h-C01h. */
+	OperationRegion(PRQM, SystemIO, 0x00000c00, 0x00000002)
+		Field(PRQM, ByteAcc, NoLock, Preserve) {
+		PRQI, 0x00000008,
+		PRQD, 0x00000008,  /* Offset: 1h */
+	}
+	IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) {
+		PIRA, 0x00000008,	/* Index 0 */
+		PIRB, 0x00000008,	/* Index 1 */
+		PIRC, 0x00000008,	/* Index 2 */
+		PIRD, 0x00000008,	/* Index 3 */
+		PIRE, 0x00000008,	/* Index 4 */
+		PIRF, 0x00000008,	/* Index 5 */
+		PIRG, 0x00000008,	/* Index 6 */
+		PIRH, 0x00000008,	/* Index 7 */
+	}
+
+	/* PCI Error control register */
+	OperationRegion(PERC, SystemIO, 0x00000c14, 0x00000001)
+		Field(PERC, ByteAcc, NoLock, Preserve) {
+		SENS, 0x00000001,
+		PENS, 0x00000001,
+		SENE, 0x00000001,
+		PENE, 0x00000001,
+	}
+
+	/* Client Management index/data registers */
+	OperationRegion(CMT, SystemIO, 0x00000c50, 0x00000002)
+		Field(CMT, ByteAcc, NoLock, Preserve) {
+		CMTI,	8,
+		/* Client Management Data register */
+		G64E,	1,
+		G64O,	1,
+		G32O,	2,
+		,		2,
+		GPSL,	2,
+	}
+
+	/* GPM Port register */
+	OperationRegion(GPT, SystemIO, 0x00000c52, 0x00000001)
+		Field(GPT, ByteAcc, NoLock, Preserve) {
+		GPB0,1,
+		GPB1,1,
+		GPB2,1,
+		GPB3,1,
+		GPB4,1,
+		GPB5,1,
+		GPB6,1,
+		GPB7,1,
+	}
+
+	/* Flash ROM program enable register */
+	OperationRegion(FRE, SystemIO, 0x00000c6F, 0x00000001)
+		Field(FRE, ByteAcc, NoLock, Preserve) {
+		,     0x00000006,
+		FLRE, 0x00000001,
+	}
+
+	/* PM2 index/data registers */
+	OperationRegion(PM2R, SystemIO, 0x00000Cd0, 0x00000002)
+		Field(PM2R, ByteAcc, NoLock, Preserve) {
+		PM2I, 0x00000008,
+		PM2D, 0x00000008,
+	}
+
+	/* Power Management I/O registers, TODO:PMIO is quite different in SB800. */
+	OperationRegion(PIOR, SystemIO, 0x00000Cd6, 0x00000002)
+		Field(PIOR, ByteAcc, NoLock, Preserve) {
+		PIOI, 0x00000008,
+		PIOD, 0x00000008,
+	}
+
+	IndexField (PIOI, PIOD, ByteAcc, NoLock, Preserve) {
+		Offset(0x60),		/* AcpiPm1EvgBlk */
+		P1EB, 16,
+		Offset(0xee),
+		UPWS, 3,
+	}
+	OperationRegion (P1E0, SystemIO, P1EB, 0x04)
+		Field (P1E0, ByteAcc, Nolock, Preserve) {
+		Offset(0x02),
+		, 14,
+		PEWD, 1,
+	}
diff --git a/src/soc/amd/picasso/acpi/sb_fch.asl b/src/soc/amd/picasso/acpi/sb_fch.asl
new file mode 100644
index 0000000..e7975f8
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/sb_fch.asl
@@ -0,0 +1,153 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <soc/gpio.h>
+#include <soc/iomap.h>
+
+Device (AAHB)
+{
+	Name (_HID, "AAHB0000")
+	Name (_UID, 0x0)
+	Name (_CRS, ResourceTemplate()
+	{
+		Memory32Fixed (ReadWrite, ALINK_AHB_ADDRESS, 0x2000)
+	})
+
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (GPIO)
+{
+	Name (_HID, GPIO_DEVICE_NAME)
+	Name (_CID, GPIO_DEVICE_NAME)
+	Name (_UID, 0)
+	Name (_DDN, GPIO_DEVICE_DESC)
+
+	Name (_CRS, ResourceTemplate()
+	{
+		Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , )
+			{ 7 }
+		Memory32Fixed (ReadWrite, 0xFED81500, 0x300)
+	})
+
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (FUR0)
+{
+	Name (_HID, "AMD0020")
+	Name (_UID, 0x0)
+	Name (_CRS, ResourceTemplate()
+	{
+		IRQ (Edge, ActiveHigh, Exclusive) { 10 }
+		Memory32Fixed (ReadWrite, 0xFEDC6000, 0x2000)
+	})
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (FUR1) {
+	Name (_HID, "AMD0020")
+	Name (_UID, 0x1)
+	Name (_CRS, ResourceTemplate()
+	{
+			IRQ (Edge, ActiveHigh, Exclusive) { 11 }
+			Memory32Fixed (ReadWrite, 0xFEDC8000, 0x2000)
+	})
+	Method (_STA, 0x0, NotSerialized)
+	{
+			Return (0x0F)
+	}
+}
+
+Device (I2CA) {
+	Name (_HID, "AMD0010")
+	Name (_UID, 0x0)
+	Name (_CRS, ResourceTemplate()
+	{
+		IRQ (Edge, ActiveHigh, Exclusive) { 3 }
+		Memory32Fixed (ReadWrite, 0xFEDC2000, 0x1000)
+	})
+
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (I2CB)
+{
+	Name (_HID, "AMD0010")
+	Name (_UID, 0x1)
+	Name (_CRS, ResourceTemplate()
+	{
+		IRQ (Edge, ActiveHigh, Exclusive) { 15 }
+		Memory32Fixed (ReadWrite, 0xFEDC3000, 0x1000)
+	})
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (I2CC) {
+	Name (_HID, "AMD0010")
+	Name (_UID, 0x2)
+	Name (_CRS, ResourceTemplate()
+	{
+		IRQ (Edge, ActiveHigh, Exclusive) { 6 }
+		Memory32Fixed (ReadWrite, 0xFEDC4000, 0x1000)
+	})
+
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (I2CD)
+{
+	Name (_HID, "AMD0010")
+	Name (_UID, 0x3)
+	Name (_CRS, ResourceTemplate() {
+		IRQ (Edge, ActiveHigh, Exclusive) { 14 }
+		Memory32Fixed(ReadWrite, 0xFEDC5000, 0x1000)
+	})
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
+
+Device (MISC)
+{
+	Name (_HID, "AMD0040")
+	Name (_UID, 0x3)
+	Name (_CRS, ResourceTemplate() {
+		Memory32Fixed(ReadWrite, ACPIMMIO_MISC_BASE, 0x100)
+	})
+	Method (_STA, 0x0, NotSerialized)
+	{
+		Return (0x0F)
+	}
+}
diff --git a/src/soc/amd/picasso/acpi/sb_pci0_fch.asl b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
new file mode 100644
index 0000000..3623814
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
@@ -0,0 +1,619 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ */
+
+External(\_SB.ALIB, MethodObj)
+
+/* System Bus */
+/*  _SB.PCI0 */
+
+/* Operating System Capabilities Method */
+Method(_OSC,4)
+{
+	/* Check for proper PCI/PCIe UUID */
+	If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+	{
+		/* Let OS control everything */
+		Return (Arg3)
+	} Else {
+		CreateDWordField(Arg3,0,CDW1)
+		Or(CDW1,4,CDW1)	// Unrecognized UUID
+		Return(Arg3)
+	}
+}
+
+/* Describe the Southbridge devices */
+
+/* 0:11.0 - SATA */
+Device(STCR) {
+	Name(_ADR, 0x00110000)
+} /* end STCR */
+
+/* 0:14.0 - SMBUS */
+Device(SBUS) {
+	Name(_ADR, 0x00140000)
+} /* end SBUS */
+
+#include "usb.asl"
+
+/* 0:14.2 - I2S Audio */
+
+/* 0:14.3 - LPC */
+#include <soc/amd/common/acpi/lpc.asl>
+
+/* 0:14.7 - SD Controller */
+Device(SDCN) {
+	Name(_ADR, 0x00140007)
+
+	Method(_PS0) {
+		FDDC(24, 0)
+	}
+	Method(_PS3) {
+		FDDC(24, 3)
+	}
+	Method(_PSC) {
+		Return(SDTD)
+	}
+} /* end SDCN */
+
+Name(CRES, ResourceTemplate() {
+	/* Set the Bus number and Secondary Bus number for the PCI0 device
+	 * The Secondary bus range for PCI0 lets the system
+	 * know what bus values are allowed on the downstream
+	 * side of this PCI bus if there is a PCI-PCI bridge.
+	 * PCI busses can have 256 secondary busses which
+	 * range from [0-0xFF] but they do not need to be
+	 * sequential.
+	 */
+	WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
+		0x0000,		/* address granularity */
+		0x0000,		/* range minimum */
+		0x00ff,		/* range maximum */
+		0x0000,		/* translation */
+		0x0100,		/* length */
+		,, PSB0)		/* ResourceSourceIndex, ResourceSource, DescriptorName */
+
+	IO(Decode16, 0x0cf8, 0x0cf8, 1,	8)
+
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x0000,		/* range minimum */
+		0x0cf7,		/* range maximum */
+		0x0000,		/* translation */
+		0x0cf8		/* length */
+	)
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x03b0,		/* range minimum */
+		0x03df,		/* range maximum */
+		0x0000,		/* translation */
+		0x0030		/* length */
+	)
+
+	WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+		0x0000,		/* address granularity */
+		0x0d00,		/* range minimum */
+		0xffff,		/* range maximum */
+		0x0000,		/* translation */
+		0xf300		/* length */
+	)
+
+	Memory32Fixed(READONLY, 0x000a0000, 0x00020000, VGAM)	/* VGA memory space */
+	Memory32Fixed(READONLY, 0x000c0000, 0x00020000, EMM1)	/* Assume C0000-E0000 empty */
+
+	/* memory space for PCI BARs below 4GB */
+	Memory32Fixed(ReadOnly, 0x00000000, 0x00000000, MMIO)
+}) /* End Name(_SB.PCI0.CRES) */
+
+Method(_CRS, 0) {
+	/* DBGO("\\_SB\\PCI0\\_CRS\n") */
+	CreateDWordField(CRES, ^MMIO._BAS, MM1B)
+	CreateDWordField(CRES, ^MMIO._LEN, MM1L)
+
+	/*
+	 * Declare memory between TOM1 and 4GB as available
+	 * for PCI MMIO.
+	 * Use ShiftLeft to avoid 64bit constant (for XP).
+	 * This will work even if the OS does 32bit arithmetic, as
+	 * 32bit (0x00000000 - TOM1) will wrap and give the same
+	 * result as 64bit (0x100000000 - TOM1).
+	 */
+	Store(TOM1, MM1B)
+	ShiftLeft(0x10000000, 4, Local0)
+	Subtract(Local0, TOM1, Local0)
+	Store(Local0, MM1L)
+
+	Return(CRES) /* note to change the Name buffer */
+} /* end of Method(_SB.PCI0._CRS) */
+
+/*
+ *
+ *               FIRST METHOD CALLED UPON BOOT
+ *
+ *  1. If debugging, print current OS and ACPI interpreter.
+ *  2. Get PCI Interrupt routing from ACPI VSM, this
+ *     value is based on user choice in BIOS setup.
+ */
+Method(_INI, 0, Serialized) {
+	/* DBGO("\\_SB\\_INI\n") */
+	/* DBGO("   DSDT.ASL code from ") */
+	/* DBGO(__DATE__) */
+	/* DBGO(" ") */
+	/* DBGO(__TIME__) */
+	/* DBGO("\n   Sleep states supported: ") */
+	/* DBGO("\n") */
+	/* DBGO("   \\_OS=") */
+	/* DBGO(\_OS) */
+	/* DBGO("\n   \\_REV=") */
+	/* DBGO(\_REV) */
+	/* DBGO("\n") */
+
+	/* Determine the OS we're running on */
+	OSFL()
+
+	/* Send ALIB Function 1 the AC/DC state */
+	Name(F1BF, Buffer(0x03){})
+	CreateWordField(F1BF, 0, F1SZ)
+	CreateByteField(F1BF, 2, F1DA)
+
+	Store(3, F1SZ)
+	Store(\PWRS, F1DA)
+
+	\_SB.ALIB(1, F1BF)
+
+} /* End Method(_SB._INI) */
+
+Method(OSFL, 0){
+
+	if (LNotEqual(OSVR, Ones)) {Return(OSVR)}	/* OS version was already detected */
+
+	if (CondRefOf(\_OSI))
+	{
+		Store(1, OSVR)					/* Assume some form of XP */
+		if (\_OSI("Windows 2006"))		/* Vista */
+		{
+			Store(2, OSVR)
+		}
+	} else {
+		If(WCMP(\_OS,"Linux")) {
+			Store(3, OSVR)				/* Linux */
+		} Else {
+			Store(4, OSVR)				/* Gotta be WinCE */
+		}
+	}
+	Return(OSVR)
+}
+
+OperationRegion(SMIC, SystemMemory, 0xfed80000, 0x80000)
+Field( SMIC, ByteAcc, NoLock, Preserve) {
+	/* MISC registers */
+	offset (0x03ee),
+	U3PS, 2,  /* Usb3PowerSel */
+
+	offset (0x0e28),
+	,29 ,
+	SARP, 1,  /* Sata Ref Clock Powerdown */
+	U2RP, 1,  /* Usb2 Ref Clock Powerdown */
+	U3RP, 1,  /* Usb3 Ref Clock Powerdown */
+
+	/* XHCI_PM registers */
+	offset (0x1c00),
+	, 1,
+	,6,
+	U3PY, 1,
+	, 7,
+	UD3P, 1,  /* bit 15 */
+	U3PR, 1,  /* bit 16 */
+	, 11,
+	FWLM, 1,  /* FirmWare Load Mode  */
+	FPLS, 1,  /* Fw PreLoad Start    */
+	FPLC, 1,  /* Fw PreLoad Complete */
+
+	offset (0x1c04),
+	UA04, 16,
+	, 15,
+	ROAM, 1,  /* 1= ROM 0=RAM */
+
+	offset (0x1c08),
+	UA08, 32,
+
+	/* AOAC Registers */
+	offset (0x1e4a), /* I2C0 D3 Control */
+	I0TD, 2,
+	, 1,
+	I0PD, 1,
+	offset (0x1e4b), /* I2C0 D3 State */
+	I0DS, 3,
+
+	offset (0x1e4c), /* I2C1 D3 Control */
+	I1TD, 2,
+	, 1,
+	I1PD, 1,
+	offset (0x1e4d), /* I2C1 D3 State */
+	I1DS, 3,
+
+	offset (0x1e4e), /* I2C2 D3 Control */
+	I2TD, 2,
+	, 1,
+	I2PD, 1,
+	offset (0x1e4f), /* I2C2 D3 State */
+	I2DS, 3,
+
+	offset (0x1e50), /* I2C3 D3 Control */
+	I3TD, 2,
+	, 1,
+	I3PD, 1,
+	offset (0x1e51), /* I2C3 D3 State */
+	I3DS, 3,
+
+	offset (0x1e56), /* UART0 D3 Control */
+	U0TD, 2,
+	, 1,
+	U0PD, 1,
+	offset (0x1e57), /* UART0 D3 State */
+	U0DS, 3,
+
+	offset (0x1e58), /* UART1 D3 Control */
+	U1TD, 2,
+	, 1,
+	U1PD, 1,
+	offset (0x1e59), /* UART1 D3 State */
+	U1DS, 3,
+
+	offset (0x1e5e), /* SATA D3 Control */
+	SATD, 2,
+	, 1,
+	SAPD, 1,
+	offset (0x1e5f), /* SATA D3 State */
+	SADS, 3,
+
+	offset (0x1e64), /* USB2 D3 Control */
+	U2TD, 2,
+	, 1,
+	U2PD, 1,
+	offset (0x1e65), /* USB2 D3 State */
+	U2DS, 3,
+
+	offset (0x1e6e), /* USB3 D3 Control */
+	U3TD, 2,
+	, 1,
+	U3PD, 1,
+	offset (0x1e6f), /* USB3 D3 State */
+	U3DS, 3,
+
+	offset (0x1e70), /* SD D3 Control */
+	SDTD, 2,
+	, 1,
+	SDPD, 1,
+	, 1,
+	, 1,
+	SDRT, 1,
+	SDSC, 1,
+
+	offset (0x1e71), /* SD D3 State */
+	SDDS, 3,
+
+	offset (0x1e80), /* Shadow Register Request */
+	, 15,
+	RQ15, 1,
+	, 2,
+	RQ18, 1,
+	, 4,
+	RQ23, 1,
+	RQ24, 1,
+	, 5,
+	RQTY, 1,
+	offset (0x1e84), /* Shadow Register Status */
+	, 15,
+	SASR, 1,  /* SATA 15 Shadow Reg Request Status Register */
+	, 2,
+	U2SR, 1,  /* USB2 18 Shadow Reg Request Status Register */
+	, 4,
+	U3SR, 1,  /* USB3 23 Shadow Reg Request Status Register */
+	SDSR, 1,  /* SD 24 Shadow Reg Request Status Register */
+
+	offset (0x1ea0), /* PwrGood Control */
+	PG1A, 1,
+	PG2_, 1,
+	,1,
+	U3PG, 1,  /* Usb3 Power Good BIT3 */
+
+	offset (0x1ea3), /* PwrGood Control b[31:24] */
+	PGA3, 8 ,
+}
+
+OperationRegion(FCFG, SystemMemory, PCBA, 0x01000000)
+Field(FCFG, DwordAcc, NoLock, Preserve)
+{
+	/* XHCI */
+	Offset(0x00080010), /* Base address */
+	XHBA, 32,
+	Offset(0x0008002c), /* Subsystem ID / Vendor ID */
+	XH2C, 32,
+
+	Offset(0x00080048), /* Indirect PCI Index Register */
+	IDEX, 32,
+	DATA, 32,
+	Offset(0x00080054), /* PME Control / Status */
+	U_PS, 2,
+
+	/* EHCI */
+	Offset(0x00090004), /* Control */
+	, 1,
+	EHME, 1,
+	Offset(0x00090010), /* Base address */
+	EHBA, 32,
+	Offset(0x0009002c), /* Subsystem ID / Vendor ID */
+	EH2C, 32,
+	Offset(0x00090054), /* EHCI Spare 1 */
+	EH54, 8,
+	Offset(0x00090064), /* Misc Control 2 */
+	EH64, 8,
+
+	Offset(0x000900c4), /* PME Control / Status */
+	E_PS, 2,
+
+	/* LPC Bridge */
+	Offset(0x000a30cb), /* ClientRomProtect[31:24] */
+	,  7,
+	AUSS,  1, /* AutoSizeStart */
+}
+
+/*
+ * Arg0:device:
+ *  5=I2C0, 6=I2C1, 7=I2C2, 8=I2C3, 11=UART0, 12=UART1,
+ *  15=SATA, 18=EHCI, 23=xHCI, 24=SD
+ * Arg1:D-state
+ */
+Mutex (FDAS, 0) /* FCH Device AOAC Semophore */
+Method(FDDC, 2, Serialized)
+{
+	Acquire(FDAS, 0xffff)
+
+	if(LEqual(Arg1, 0)) {
+		Switch(ToInteger(Arg0)) {
+			Case(Package() {5, 15, 24}) {
+				Store(One, PG1A)
+			}
+			Case(Package() {6, 7, 8, 11, 12, 18}) {
+				Store(One, PG2_)
+			}
+		}
+		/* put device into D0 */
+		Switch(ToInteger(Arg0))
+		{
+			Case(5) {
+				Store(0x00, I0TD)
+				Store(One, I0PD)
+				Store(I0DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(I0DS, Local0)
+				}
+			}
+			Case(6) {
+				Store(0x00, I1TD)
+				Store(One, I1PD)
+				Store(I1DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(I1DS, Local0)
+				}
+			}
+			Case(7) {
+				Store(0x00, I2TD)
+				Store(One, I2PD)
+				Store(I2DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(I2DS, Local0)
+				}
+			}
+			Case(8) {Store(0x00, I3TD)
+				Store(One, I3PD)
+				Store(I3DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(I3DS, Local0)
+				}
+			}
+			Case(11) {
+				Store(0x00, U0TD)
+				Store(One, U0PD)
+				Store(U0DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(U0DS, Local0)
+				}
+			}
+			Case(12) {
+				Store(0x00, U1TD)
+				Store(One, U1PD)
+				Store(U1DS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(U1DS, Local0)
+				}
+			}
+/* todo			Case(15) { STD0()} */ /* SATA */
+			Case(18) { U2D0()} /* EHCI */
+			Case(23) { U3D0()} /* XHCI */
+			Case(24) { /* SD */
+				Store(0x00, SDTD)
+				Store(One, SDPD)
+				Store(SDDS, Local0)
+				while(LNotEqual(Local0,0x7)) {
+					Store(SDDS, Local0)
+				}
+			}
+		}
+	} else {
+		/* put device into D3cold */
+		Switch(ToInteger(Arg0))
+		{
+			Case(5) {
+				Store(Zero, I0PD)
+				Store(I0DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(I0DS, Local0)
+				}
+				Store(0x03, I0TD)
+			}
+			Case(6) {
+				Store(Zero, I1PD)
+				Store(I1DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(I1DS, Local0)
+				}
+				Store(0x03, I1TD)
+			}
+			Case(7)  {
+				Store(Zero, I2PD)
+				Store(I2DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(I2DS, Local0)
+				}
+				Store(0x03, I2TD)}
+			Case(8) {
+				Store(Zero, I3PD)
+				Store(I3DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(I3DS, Local0)
+				}
+				Store(0x03, I3TD)
+			}
+			Case(11) {
+				Store(Zero, U0PD)
+				Store(U0DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(U0DS, Local0)
+				}
+				Store(0x03, U0TD)
+			}
+			Case(12) {
+				Store(Zero, U1PD)
+				Store(U1DS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(U1DS, Local0)
+				}
+				Store(0x03, U1TD)
+			}
+/* todo			Case(15) { STD3()} */ /* SATA */
+			Case(18) { U2D3()} /* EHCI */
+			Case(23) { U3D3()} /* XHCI */
+			Case(24) { /* SD */
+				Store(Zero, SDPD)
+				Store(SDDS, Local0)
+				while(LNotEqual(Local0,0x0)) {
+					Store(SDDS, Local0)
+				}
+				Store(0x03, SDTD)
+			}
+		}
+		/* Turn off Power */
+		if(LEqual(I0TD, 3)) {
+			if(LEqual(SATD, 3)) {
+				if(LEqual(SDTD, 3)) { Store(Zero, PG1A) }
+			}
+		}
+		if(LEqual(I1TD, 3)) {
+			if(LEqual(I2TD, 3)) {
+				if(LEqual(I3TD, 3)) {
+					if(LEqual(U0TD, 3)) {
+						if(LEqual(U1TD, 3)) {
+							if(LEqual(U2TD, 3)) {
+								Store(Zero, PG2_)
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	Release(FDAS)
+}
+
+Method(FPTS,0, Serialized)  /* FCH _PTS */
+{
+	if(LEqual(\XHCE, one)) {
+		if(LNotEqual(U3TD, 0x03)) {
+			FDDC(23, 3)
+		}
+	}
+	if(LNotEqual(U2TD, 0x03)) {
+		FDDC(18, 3)
+	}
+}
+
+Method(FWAK,0, Serialized)  /* FCH _WAK */
+{
+	if(LEqual(\XHCE, one)) {
+		if(LEqual(U3TD, 0x03)) {
+			FDDC(23, 0)
+		}
+	}
+	if(LEqual(U2TD, 0x03)) {
+		FDDC(18, 0)
+	}
+	if(LEqual(\UT0E, zero)) {
+		if(LNotEqual(U0TD, 0x03)) {
+			FDDC(11, 3)
+		}
+	}
+	if(LEqual(\UT1E, zero)) {
+		if(LNotEqual(U1TD, 0x03)) {
+			FDDC(12, 3)
+		}
+	}
+	if(LEqual(\IC0E, zero)) {
+		if(LNotEqual(I0TD, 0x03)) {
+			FDDC(5, 3)
+		}
+	}
+	if(LEqual(\IC1E, zero)) {
+		if(LNotEqual(I1TD, 0x03)) {
+			FDDC(6, 3)
+		}
+	}
+	if(LEqual(\IC2E, zero)) {
+		if(LNotEqual(I2TD, 0x03)) {
+			FDDC(7, 3)
+		}
+	}
+	if(LEqual(\IC3E, zero)) {
+		if(LNotEqual(I3TD, 0x03)) {
+			FDDC(8, 3)
+		}
+	}
+}
+
+/*
+ * Helper for setting a bit in AOACxA0 PwrGood Control
+ * Arg0: bit to set or clear
+ * Arg1: 0 = clear bit[Arg0], non-zero = set bit[Arg0]
+ */
+Method(PWGC,2, Serialized)
+{
+	And (PGA3, 0xdf, Local0)  /* do SwUsb3SlpShutdown below */
+	if(Arg1) {
+		Or(Arg0, Local0, Local0)
+	} else {
+		Not(Arg0, Local1)
+		And(Local1, Local0, Local0)
+	}
+	Store(Local0, PGA3)
+	if(LEqual(Arg0, 0x20)) { /* if SwUsb3SlpShutdown */
+		Store(PGA3, Local0)
+		And(Arg0, Local0, Local0)
+		while(LNot(Local0)) { /* wait SwUsb3SlpShutdown to complete */
+			Store(PGA3, Local0)
+			And(Arg0, Local0, Local0)
+		}
+	}
+}
diff --git a/src/soc/amd/picasso/acpi/sleepstates.asl b/src/soc/amd/picasso/acpi/sleepstates.asl
new file mode 100644
index 0000000..d4aabdb
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/sleepstates.asl
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 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.
+ */
+
+/* S1 support: bit 0, S2 Support: bit 1, etc. S0 & S5 assumed */
+Name(SSFG, 0x09)
+If (CONFIG(HAVE_ACPI_RESUME)) {
+	Store(0x0D, SSFG)
+}
+
+/* Supported sleep states: */
+Name(\_S0, Package () {0x00, 0x00, 0x00, 0x00} )	/* (S0) - working state */
+
+If (And(SSFG, 0x01)) {
+	Name(\_S1, Package () {0x01, 0x01, 0x00, 0x00} )	/* (S1) - sleeping w/CPU context */
+}
+If (And(SSFG, 0x02)) {
+	Name(\_S2, Package () {0x02, 0x02, 0x00, 0x00} )	/* (S2) - "light" Suspend to RAM */
+}
+If (And(SSFG, 0x04)) {
+	Name(\_S3, Package () {0x03, 0x03, 0x00, 0x00} )	/* (S3) - Suspend to RAM */
+}
+If (And(SSFG, 0x08)) {
+	Name(\_S4, Package () {0x04, 0x04, 0x00, 0x00} )	/* (S4) - Suspend to Disk */
+}
+
+Name(\_S5, Package () {0x05, 0x05, 0x00, 0x00} )	/* (S5) - Soft Off */
diff --git a/src/soc/amd/picasso/acpi/soc.asl b/src/soc/amd/picasso/acpi/soc.asl
new file mode 100644
index 0000000..52c7ee6
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/soc.asl
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+Device(PCI0) {
+	/* Describe the AMD Northbridge */
+	#include "northbridge.asl"
+
+	/* Describe the AMD Fusion Controller Hub */
+	#include "sb_pci0_fch.asl"
+}
+
+/* Describe PCI INT[A-H] for the Southbridge */
+#include "pci_int.asl"
+
+/* Describe the devices in the Southbridge */
+#include "sb_fch.asl"
+
+/* Add GPIO library */
+#include <soc/amd/common/acpi/gpio_bank_lib.asl>
diff --git a/src/soc/amd/picasso/acpi/usb.asl b/src/soc/amd/picasso/acpi/usb.asl
new file mode 100644
index 0000000..f2ee8f6
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/usb.asl
@@ -0,0 +1,392 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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.
+ */
+
+/* 0:12.0 - EHCI */
+Device(EHC0) {
+	Name(_ADR, 0x00120000)
+	Name(_PRW, Package() { 0xb, 3 })
+	Device (RHUB) {
+		Name (_ADR, Zero)
+		Device (HS01) { Name (_ADR, 1) }
+		Device (HS02) { Name (_ADR, 2) }
+		Device (HS03) { Name (_ADR, 3) }
+		Device (HS04) { Name (_ADR, 4) }
+		Device (HS05) { Name (_ADR, 5) }
+		Device (HS06) { Name (_ADR, 6) }
+		Device (HS07) { Name (_ADR, 7) }
+		Device (HS08) { Name (_ADR, 8) }
+	}
+
+	Name(_PR0, Package() { P0U2 }) /* Indicate support for D0 */
+	Name(_PR3, Package() { P3U2 }) /* Indicate support for D3cold */
+
+	Method(_S0W,0) {
+		Return(0)
+	}
+
+	Method(_S3W,0) {
+		Return(4)
+	}
+
+	Method(_S4W,0) {
+		Return(4)
+	}
+} /* end EHC0 */
+
+
+/* 0:10.0 - XHCI 0*/
+Device(XHC0) {
+	Name(_ADR, 0x00100000)
+	Name(_PRW, Package() { 0xb, 3 })
+	Device (SS01) { Name (_ADR, 1) }
+	Device (SS02) { Name (_ADR, 2) }
+	Device (SS03) { Name (_ADR, 3) }
+
+	Name(_PR0, Package() { P0U3 }) /* Indicate support for D0 */
+	Name(_PR3, Package() { P3U3 }) /* Indicate support for D3cold */
+
+	Method(_S0W,0) {
+		Return(0)
+	}
+
+	Method(_S3W,0) {
+		Return(4)
+	}
+
+	Method(_S4W,0) {
+		Return(4)
+	}
+
+} /* end XHC0 */
+
+Scope(\_SB)
+{
+	Name(XHD0, 0)
+	Name(XHD3, 0)
+	PowerResource(P0U3, 0, 0) {
+		Method(_STA) {
+			Return(XHD0)
+		}
+		Method(_ON) {
+			Store(0x01, XHD0)
+		}
+		Method(_OFF) {
+			Store(0x00, XHD0)
+		}
+	}
+	PowerResource(P3U3, 0, 0) {
+		Method(_STA) {
+			Return(XHD3)
+		}
+		Method(_ON) {
+			Store(0x01, XHD3)
+		}
+		Method(_OFF) {
+			Store(0x00, XHD3)
+		}
+	}
+
+	Name(EHD0, 0)
+	Name(EHD3, 0)
+	PowerResource(P0U2, 0, 0) {
+		Method(_STA) {
+			Return(EHD0)
+		}
+		Method(_ON) {
+			Store(0x01, EHD0)
+		}
+		Method(_OFF) {
+			Store(0x00, EHD0)
+		}
+	}
+	PowerResource(P3U2, 0, 0) {
+		Method(_STA) {
+			Return(EHD3)
+		}
+		Method(_ON) {
+			Store(0x01, EHD3)
+		}
+		Method(_OFF) {
+			Store(0x00, EHD3)
+		}
+	}
+}
+
+OperationRegion(EHMC, SystemMemory, EH10, 0x100)
+Field(EHMC, DwordAcc, NoLock, Preserve)
+{
+	Offset(0xb0),
+	, 5,
+	ESIM, 1,
+}
+
+Method(U2D3,0, Serialized)
+{
+	if (LNotEqual(EH10, Zero)) {
+		Store (EH10, EHBA)
+		Store (One, EHME)
+		Store (ESIM, SSIM)
+	}
+
+	if (LEqual(E_PS, 3)) {
+		Store (Zero, RQTY)
+		Store (One, RQ18)
+
+		Store (U2SR, Local0)
+		while (Local0) {
+			Store (U2SR, Local0)
+		}
+
+		Store (Zero, U2PD)
+
+		Store (U2DS, Local0)
+		while (LNotEqual(Local0, Zero)) {
+			Store (U2DS, Local0)
+		}
+
+		Store (0x03,U2TD)
+
+		if (LEqual(U3TD, 0x03)) { /* Shutdown USB2 PLL */
+		    PWGC (0x40, 0)
+		    Store (One, U2RP)
+		}
+	}
+}
+
+Method(U2D0,0, Serialized)
+{
+	PWGC (0x40, 1)
+	Store (Zero, U2RP)
+	Store (0x00,U2TD)
+
+	Store (Zero, U2TD)
+	Store (One, U2PD)
+
+	Store (U2DS, Local0)
+	while (LNotEqual(Local0,0x7)) {
+		Store (U2DS, Local0)
+	}
+
+	Store (One, RQTY)
+	Store (One, RQ18)
+	Store (U2SR, Local0)
+	while (LNot(Local0)) {
+		Store (U2SR, Local0)
+	}
+	Store (EHID, EH2C)
+
+
+	if (LNotEqual(EH10, Zero)) {
+		Store (EH10, EHBA)
+		Store (One, EHME)
+		Store (SSIM, ESIM)
+	}
+
+	Store (ES54, EH54)
+	Store (ES64, EH64)
+}
+
+Method(LXFW,3, Serialized)  //Load Xhci FirmWare
+{
+	Store (One, FWLM)  /* Firmware Load Mode */
+	Store (Arg0, ROAM) /* ROM/RAM */
+	Store (Arg1, UA04)
+	Store (Arg2, UA08)
+	Store (One, FPLS)    /* Firmware Preload Start */
+	Store (FPLC, Local0) /* Firmware Preload Complete */
+	while (LNot(Local0)) {
+		Store (FPLC, Local0)
+	}
+	Store (Zero, FPLS)
+}
+
+Method(U3D3,0, Serialized)
+{
+	if (LEqual(U_PS, 3)) {
+		X0_S ()
+
+		Or (PGA3, 0x20, PGA3) /* SwUsb3SlpShutdown */
+		And (PGA3, 0x20, Local0)
+		while (LNot(Local0)) { /* wait for it to complete */
+			And (PGA3, 0x20, Local0)
+		}
+		Store (One, UD3P) /* U3P_D3Cold_PWRDN */
+
+		Store (Zero, U3PD) /* PwrOnDev */
+		Store (U3DS, Local0)
+		while (Local0) { /* RstBState, RefClkOkState, PwrRstBState */
+			Store (U3DS, Local0)
+		}
+
+		Store (0x3, U3TD) /* TargetedDeviceState */
+
+		Store (One, U3RP) /* USB3_RefClk_Pwdn */
+
+		if (Lequal(U2TD, 0x3)) { /* If EHCI targeted in D3cold */
+			And (PGA3, 0x9f, PGA3) /* SwUsb2S5RstB */
+			Store (One, U2RP)      /* USB2_RefClk_Pwdn */
+		}
+		Store (Zero, U3PG) /* XhcPwrGood  */
+		Store (One, U3PS)  /* Usb3PowerSel */
+	}
+}
+
+Method(U3D0,0, Serialized)
+{
+	Store (Zero, U3PS) /* Usb3PowerSel */
+	Store (One, U3PG)  /* XhcPwrGood  */
+
+	Store (Zero, U2RP)
+	Store (Zero, U3RP)
+
+	And (PGA3, 0xdf, Local0)
+	Or (Local0, 0x40, Local0)
+	Store (Local0, PGA3) /* SwUsb2S5RstB */
+
+	Store (Zero, U3TD) /* TargetedDeviceState */
+	Store (One, U3PD)  /* PwrOnDev */
+
+	Store (U3DS, Local0) /* wait for RstBState, RefClkOkState, PwrRstBState */
+	while (LNot(Lequal(Local0, 0x7))) {
+		Store (U3DS, Local0)
+	}
+
+	Store (U3PY, Local0) /* USB3 PHY Lock */
+	while (LNot(Local0)) {
+		Store (U3PY, Local0)
+	}
+
+	Store (Zero, U3PR) /* U3P_RESTORE_RESET */
+
+	Store (AUSS, Local0) /* AutoSizeStart */
+	if (LNotEqual(Local0,1)) {
+		Store(One, AUSS)
+	}
+	Store (AUSS, Local0)
+	while (LNotEqual(Local0,1)) {
+		Store (AUSS, Local0)
+	}
+
+	LXFW (1, FW00, FW01)
+	LXFW (0, FW02, FW03)
+
+	X0_R ()
+
+	Store (One, U3PR)  /* U3P_RESTORE_RESET */
+	Store (Zero, UD3P) /* U3P_D3Cold_PWRDN */
+	Store (One, U3TD)  /* TargetedDeviceState */
+}
+
+Name (SVBF, Buffer (0x1000) {0})    /* length from FchCarrizo.asl, new fields */
+CreateDWordField(SVBF, 0x000, S000) /* will be easier to add from there */
+CreateDWordField(SVBF, 0x004, S004)
+CreateDWordField(SVBF, 0x008, S008)
+CreateDWordField(SVBF, 0x00C, S00C)
+CreateDWordField(SVBF, 0x018, S018)
+CreateDWordField(SVBF, 0x01C, S01C)
+CreateDWordField(SVBF, 0x020, S020)
+CreateDWordField(SVBF, 0x030, S030)
+CreateDWordField(SVBF, 0x118, S118)
+CreateDWordField(SVBF, 0x158, S158)
+CreateDWordField(SVBF, 0x198, S198)
+CreateDWordField(SVBF, 0x1D8, S1D8)
+CreateDWordField(SVBF, 0x300, S300)
+CreateDWordField(SVBF, 0x304, S304)
+CreateDWordField(SVBF, 0x308, S308)
+CreateDWordField(SVBF, 0x30C, S30C)
+CreateDWordField(SVBF, 0x310, S310)
+CreateDWordField(SVBF, 0x428, S428)
+CreateDWordField(SVBF, 0x438, S438)
+CreateDWordField(SVBF, 0x43C, S43C)
+CreateDWordField(SVBF, 0x458, S458)
+CreateDWordField(SVBF, 0x468, S468)
+CreateDWordField(SVBF, 0x46C, S46C)
+CreateDWordField(SVBF, 0x470, S470)
+CreateDWordField(SVBF, 0x480, S480)
+CreateDWordField(SVBF, 0x484, S484)
+CreateDWordField(SVBF, 0x488, S488)
+CreateDWordField(SVBF, 0x48C, S48C)
+CreateDWordField(SVBF, 0x730, EHID) /* EHCI SSID    */
+CreateDWordField(SVBF, 0x734, XHID) /* XHCI SSID    */
+CreateByteField(SVBF, 0x740, ES54)  /* EHCI PCIx54  */
+CreateByteField(SVBF, 0x741, ES64)  /* EHCI PCIx64  */
+CreateDWordField(SVBF, 0x7B0, SSIM) /* EHCI SIM BIT */
+
+Method(X0_S,0)
+{
+	Store (XH2C, XHID)
+	Store (0x00000000, IDEX) Store (DATA, S000)
+	Store (0x00000004, IDEX) Store (DATA, S004)
+	Store (0x00000008, IDEX) Store (DATA, S008)
+	Store (0x0000000c, IDEX) Store (DATA, S00C)
+	Store (0x00000018, IDEX) Store (DATA, S018)
+	Store (0x0000001c, IDEX) Store (DATA, S01C)
+	Store (0x00000020, IDEX) Store (DATA, S020)
+	Store (0x00000030, IDEX) Store (DATA, S030)
+	Store (0x00000118, IDEX) Store (DATA, S118)
+	Store (0x00000158, IDEX) Store (DATA, S158)
+	Store (0x00000198, IDEX) Store (DATA, S198)
+	Store (0x000001d8, IDEX) Store (DATA, S1D8)
+	Store (0x00000300, IDEX) Store (DATA, S300)
+	Store (0x00000304, IDEX) Store (DATA, S304)
+	Store (0x00000308, IDEX) Store (DATA, S308)
+	Store (0x0000030c, IDEX) Store (DATA, S30C)
+	Store (0x00000310, IDEX) Store (DATA, S310)
+	Store (0x40000028, IDEX) Store (DATA, S428)
+	Store (0x40000038, IDEX) Store (DATA, S438)
+	Store (0x4000003c, IDEX) Store (DATA, S43C)
+	Store (0x40000058, IDEX) Store (DATA, S458)
+	Store (0x40000068, IDEX) Store (DATA, S468)
+	Store (0x4000006c, IDEX) Store (DATA, S46C)
+	Store (0x40000070, IDEX) Store (DATA, S470)
+	Store (0x40000080, IDEX) Store (DATA, S480)
+	Store (0x40000084, IDEX) Store (DATA, S484)
+	Store (0x40000088, IDEX) Store (DATA, S488)
+	Store (0x4000008c, IDEX) Store (DATA, S48C)
+}
+
+Method(X0_R,0)
+{
+	Store (XHID, XH2C)
+	Store (0x00000000, IDEX) Store (S000, DATA)
+	Store (0x00000004, IDEX) Store (S004, DATA)
+	Store (0x00000008, IDEX) Store (S008, DATA)
+	Store (0x0000000c, IDEX) Store (S00C, DATA)
+	Store (0x00000018, IDEX) Store (S018, DATA)
+	Store (0x0000001c, IDEX) Store (S01C, DATA)
+	Store (0x00000020, IDEX) Store (S020, DATA)
+	Store (0x00000030, IDEX) Store (S030, DATA)
+	Store (0x00000118, IDEX) Store (S118, DATA)
+	Store (0x00000158, IDEX) Store (S158, DATA)
+	Store (0x00000198, IDEX) Store (S198, DATA)
+	Store (0x000001d8, IDEX) Store (S1D8, DATA)
+	Store (0x00000300, IDEX) Store (S300, DATA)
+	Store (0x00000304, IDEX) Store (S304, DATA)
+	Store (0x00000308, IDEX) Store (S308, DATA)
+	Store (0x0000030c, IDEX) Store (S30C, DATA)
+	Store (0x00000310, IDEX) Store (S310, DATA)
+	Store (0x40000028, IDEX) Store (S428, DATA)
+	Store (0x40000038, IDEX) Store (S438, DATA)
+	Store (0x4000003c, IDEX) Store (S43C, DATA)
+	Store (0x40000058, IDEX) Store (S458, DATA)
+	Store (0x40000068, IDEX) Store (S468, DATA)
+	Store (0x4000006c, IDEX) Store (S46C, DATA)
+	Store (0x40000070, IDEX) Store (S470, DATA)
+	Store (0x40000080, IDEX) Store (S480, DATA)
+	Store (0x40000084, IDEX) Store (S484, DATA)
+	Store (0x40000088, IDEX) Store (S488, DATA)
+	Store (0x4000008c, IDEX) Store (S48C, DATA)
+}
diff --git a/src/soc/amd/picasso/bootblock/bootblock.c b/src/soc/amd/picasso/bootblock/bootblock.c
new file mode 100644
index 0000000..9239030
--- /dev/null
+++ b/src/soc/amd/picasso/bootblock/bootblock.c
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corporation..
+ * Copyright (C) 2017 Advanced Micro Devices
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <assert.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <smp/node.h>
+#include <bootblock_common.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/agesawrapper_call.h>
+#include <soc/pci_devs.h>
+#include <soc/cpu.h>
+#include <soc/northbridge.h>
+#include <soc/southbridge.h>
+#include <amdblocks/psp.h>
+#include <timestamp.h>
+#include <halt.h>
+
+#if CONFIG_PI_AGESA_TEMP_RAM_BASE < 0x100000
+#error "Error: CONFIG_PI_AGESA_TEMP_RAM_BASE must be >= 1MB"
+#endif
+#if CONFIG_PI_AGESA_CAR_HEAP_BASE < 0x100000
+#error "Error: CONFIG_PI_AGESA_CAR_HEAP_BASE must be >= 1MB"
+#endif
+
+/* Set the MMIO Configuration Base Address, Bus Range, and misc MTRRs. */
+static void amd_initmmio(void)
+{
+	msr_t mmconf;
+	msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
+	int mtrr;
+
+	mmconf.hi = 0;
+	mmconf.lo = CONFIG_MMCONF_BASE_ADDRESS | MMIO_RANGE_EN
+			| fms(CONFIG_MMCONF_BUS_NUMBER) << MMIO_BUS_RANGE_SHIFT;
+	wrmsr(MMIO_CONF_BASE, mmconf);
+
+	/*
+	 * todo: AGESA currently writes variable MTRRs.  Once that is
+	 *       corrected, un-hardcode this MTRR.
+	 *
+	 *       Be careful not to use get_free_var_mtrr/set_var_mtrr pairs
+	 *       where all cores execute the path.  Both cores within a compute
+	 *       unit share MTRRs.  Programming core0 has the appearance of
+	 *       modifying core1 too.  Using the pair again will create
+	 *       duplicate copies.
+	 */
+	mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_FLASH;
+	set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
+
+	mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_CAR_HEAP;
+	set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,
+			CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_WRBACK);
+
+	mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_TEMPRAM;
+	set_var_mtrr(mtrr, CONFIG_PI_AGESA_TEMP_RAM_BASE,
+			CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_UNCACHEABLE);
+}
+
+asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
+{
+	amd_initmmio();
+	/*
+	 * Call lib/bootblock.c main with BSP, shortcut for APs
+	 */
+	if (!boot_cpu()) {
+		void (*ap_romstage_entry)(void) =
+				(void (*)(void))get_ap_entry_ptr();
+
+		ap_romstage_entry(); /* execution does not return */
+		halt();
+	}
+
+	/* TSC cannot be relied upon. Override the TSC value passed in. */
+	bootblock_main_with_timestamp(timestamp_get(), NULL, 0);
+}
+
+void bootblock_soc_early_init(void)
+{
+	/*
+	 * This call (sb_reset_i2c_slaves) was originally early at
+	 * bootblock_c_entry, but had to be moved here. There was an
+	 * unexplained delay in the middle of the i2c transaction when
+	 * we had it in bootblock_c_entry.  Moving it to this point
+	 * (or adding delays) fixes the issue.  It seems like the processor
+	 * just pauses but we don't know why.
+	 */
+	sb_reset_i2c_slaves();
+	bootblock_fch_early_init();
+	post_code(0x90);
+}
+
+void bootblock_soc_init(void)
+{
+	if (CONFIG(STONEYRIDGE_UART))
+		assert(CONFIG_UART_FOR_CONSOLE >= 0
+					&& CONFIG_UART_FOR_CONSOLE <= 1);
+
+	u32 val = cpuid_eax(1);
+	printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
+
+	bootblock_fch_init();
+
+	/* Initialize any early i2c buses. */
+	i2c_soc_early_init();
+}
diff --git a/src/soc/amd/picasso/chip.c b/src/soc/amd/picasso/chip.c
new file mode 100644
index 0000000..7221f95
--- /dev/null
+++ b/src/soc/amd/picasso/chip.c
@@ -0,0 +1,175 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <bootstate.h>
+#include <console/console.h>
+#include <cpu/amd/mtrr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <drivers/i2c/designware/dw_i2c.h>
+#include <romstage_handoff.h>
+#include <soc/acpi.h>
+#include <soc/cpu.h>
+#include <soc/northbridge.h>
+#include <soc/pci_devs.h>
+#include <soc/southbridge.h>
+#include <amdblocks/psp.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/agesawrapper_call.h>
+
+#include "chip.h"
+
+/* Supplied by i2c.c */
+extern struct device_operations stoneyridge_i2c_mmio_ops;
+extern const char *i2c_acpi_name(const struct device *dev);
+
+struct device_operations cpu_bus_ops = {
+	.read_resources	  = DEVICE_NOOP,
+	.set_resources	  = DEVICE_NOOP,
+	.enable_resources = DEVICE_NOOP,
+	.init		  = stoney_init_cpus,
+	.acpi_fill_ssdt_generator = generate_cpu_entries,
+};
+
+const char *soc_acpi_name(const struct device *dev)
+{
+	if (dev->path.type == DEVICE_PATH_DOMAIN)
+		return "PCI0";
+
+	if (dev->path.type == DEVICE_PATH_USB) {
+		switch (dev->path.usb.port_type) {
+		case 0:
+			/* Root Hub */
+			return "RHUB";
+		case 2:
+			/* USB2 ports */
+			switch (dev->path.usb.port_id) {
+			case 0: return "HS01";
+			case 1: return "HS02";
+			case 2: return "HS03";
+			case 3: return "HS04";
+			case 4: return "HS05";
+			case 5: return "HS06";
+			case 6: return "HS07";
+			case 7: return "HS08";
+			}
+			break;
+		case 3:
+			/* USB3 ports */
+			switch (dev->path.usb.port_id) {
+			case 0: return "SS01";
+			case 1: return "SS02";
+			case 2: return "SS03";
+			}
+			break;
+		}
+		return NULL;
+	}
+
+	if (dev->path.type != DEVICE_PATH_PCI)
+		return NULL;
+
+	switch (dev->path.pci.devfn) {
+	case GFX_DEVFN:
+		return "IGFX";
+	case PCIE0_DEVFN:
+		return "PBR4";
+	case PCIE1_DEVFN:
+		return "PBR5";
+	case PCIE2_DEVFN:
+		return "PBR6";
+	case PCIE3_DEVFN:
+		return "PBR7";
+	case PCIE4_DEVFN:
+		return "PBR8";
+	case HDA1_DEVFN:
+		return "AZHD";
+	case EHCI1_DEVFN:
+		return "EHC0";
+	case LPC_DEVFN:
+		return "LPCB";
+	case SATA_DEVFN:
+		return "STCR";
+	case SD_DEVFN:
+		return "SDCN";
+	case SMBUS_DEVFN:
+		return "SBUS";
+	case XHCI_DEVFN:
+		return "XHC0";
+	default:
+		return NULL;
+	}
+};
+
+struct device_operations pci_domain_ops = {
+	.read_resources	  = pci_domain_read_resources,
+	.set_resources	  = domain_set_resources,
+	.enable_resources = domain_enable_resources,
+	.scan_bus	  = pci_domain_scan_bus,
+	.acpi_name	  = soc_acpi_name,
+};
+
+static void enable_dev(struct device *dev)
+{
+	/* Set the operations if it is a special bus type */
+	if (dev->path.type == DEVICE_PATH_DOMAIN)
+		dev->ops = &pci_domain_ops;
+	else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
+		dev->ops = &cpu_bus_ops;
+	else if (dev->path.type == DEVICE_PATH_PCI)
+		sb_enable(dev);
+	else if (dev->path.type == DEVICE_PATH_MMIO)
+		if (i2c_acpi_name(dev) != NULL)
+			dev->ops = &stoneyridge_i2c_mmio_ops;
+}
+
+static void soc_init(void *chip_info)
+{
+	southbridge_init(chip_info);
+	setup_bsp_ramtop();
+}
+
+static void soc_final(void *chip_info)
+{
+	southbridge_final(chip_info);
+	fam15_finalize(chip_info);
+}
+
+struct chip_operations soc_amd_stoneyridge_ops = {
+	CHIP_NAME("AMD StoneyRidge SOC")
+	.enable_dev = enable_dev,
+	.init = soc_init,
+	.final = soc_final
+};
+
+static void earliest_ramstage(void *unused)
+{
+	int s3_resume = acpi_s3_resume_allowed() &&
+			romstage_handoff_is_resume();
+	if (!s3_resume) {
+		post_code(0x46);
+		if (CONFIG(SOC_AMD_PSP_SELECTABLE_SMU_FW))
+			psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW2, "smu_fw2");
+
+		post_code(0x47);
+		do_agesawrapper(AMD_INIT_ENV, "amdinitenv");
+	} else {
+		/* Complete the initial system restoration */
+		post_code(0x46);
+		do_agesawrapper(AMD_S3LATE_RESTORE, "amds3laterestore");
+	}
+}
+
+BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, earliest_ramstage, NULL);
diff --git a/src/soc/amd/picasso/chip.h b/src/soc/amd/picasso/chip.h
new file mode 100644
index 0000000..d1a7d30
--- /dev/null
+++ b/src/soc/amd/picasso/chip.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010-2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_CHIP_H__
+#define __STONEYRIDGE_CHIP_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <commonlib/helpers.h>
+#include <drivers/i2c/designware/dw_i2c.h>
+#include <soc/i2c.h>
+#include <arch/acpi_device.h>
+
+#define MAX_NODES 1
+#define MAX_DRAM_CH 1
+#define MAX_DIMMS_PER_CH 2
+
+#define STONEY_I2C_DEV_MAX 4
+
+struct soc_amd_stoneyridge_config {
+	u8 spd_addr_lookup[MAX_NODES][MAX_DRAM_CH][MAX_DIMMS_PER_CH];
+	enum {
+		DRAM_CONTENTS_KEEP,
+		DRAM_CONTENTS_CLEAR
+	} dram_clear_on_reset;
+
+	enum {
+		/* Do not enable UMA in the system. */
+		UMAMODE_NONE,
+		/* Enable UMA with a specific size. */
+		UMAMODE_SPECIFIED_SIZE,
+		/* Let AGESA determine the proper size. Non-legacy requires
+		 * the resolution to be specified PLATFORM_CONFIGURATION */
+		UMAMODE_AUTO_LEGACY,
+		UMAMODE_AUTO_NON_LEGACY,
+	} uma_mode;
+
+	/* Used if UMAMODE_SPECIFIED_SIZE is set. */
+	size_t uma_size;
+
+	/*
+	 * If sb_reset_i2c_slaves() is called, this devicetree register
+	 * defines which I2C SCL will be toggled 9 times at 100 KHz.
+	 * For example, should we need I2C0 and  I2C3 have their slave
+	 * devices reseted by toggling SCL, use:
+	 *
+	 * register i2c_scl_reset = (GPIO_I2C0_SCL | GPIO_I2C3_SCL)
+	 */
+	u8 i2c_scl_reset;
+	struct dw_i2c_bus_config i2c[STONEY_I2C_DEV_MAX];
+	u8 stapm_percent;
+	u32 stapm_time_ms;
+	u32 stapm_power_mw;
+	/*
+	 * This specifies the LVDS/eDP power-up sequence time for the delay
+	 * between VaryBL and BLON.
+	 * 0 - Use the VBIOS default (default). The video BIOS default is 32ms.
+	 * n - Values other than zero specify a setting of (4 * n) milliseconds
+	 *     time delay.
+	 */
+	u8 lvds_poseq_varybl_to_blon;
+	u8 lvds_poseq_blon_to_varybl;
+};
+
+typedef struct soc_amd_stoneyridge_config config_t;
+
+extern struct device_operations pci_domain_ops;
+
+#endif /* __STONEYRIDGE_CHIP_H__ */
diff --git a/src/soc/amd/picasso/cpu.c b/src/soc/amd/picasso/cpu.c
new file mode 100644
index 0000000..1d9804d
--- /dev/null
+++ b/src/soc/amd/picasso/cpu.c
@@ -0,0 +1,155 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corp.
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <cpu/cpu.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <cpu/x86/lapic.h>
+#include <device/device.h>
+#include <device/pci_ops.h>
+#include <soc/pci_devs.h>
+#include <soc/cpu.h>
+#include <soc/northbridge.h>
+#include <soc/smi.h>
+#include <soc/iomap.h>
+#include <console/console.h>
+
+/*
+ * MP and SMM loading initialization.
+ */
+struct smm_relocation_attrs {
+	uint32_t smbase;
+	uint32_t tseg_base;
+	uint32_t tseg_mask;
+};
+
+static struct smm_relocation_attrs relo_attrs;
+
+/*
+ * Do essential initialization tasks before APs can be fired up -
+ *
+ *  1. Prevent race condition in MTRR solution. Enable MTRRs on the BSP. This
+ *  creates the MTRR solution that the APs will use. Otherwise APs will try to
+ *  apply the incomplete solution as the BSP is calculating it.
+ */
+static void pre_mp_init(void)
+{
+	x86_setup_mtrrs_with_detect();
+	x86_mtrr_check();
+}
+
+static int get_cpu_count(void)
+{
+	return (pci_read_config16(SOC_HT_DEV, D18F0_CPU_CNT) & CPU_CNT_MASK)
+									+ 1;
+}
+
+static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
+				size_t *smm_save_state_size)
+{
+	void *smm_base;
+	size_t smm_size;
+	void *handler_base;
+	size_t handler_size;
+
+	/* Initialize global tracking state. */
+	smm_region_info(&smm_base, &smm_size);
+	smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
+
+	relo_attrs.smbase = (uint32_t)smm_base;
+	relo_attrs.tseg_base = relo_attrs.smbase;
+	relo_attrs.tseg_mask = ALIGN_DOWN(~(smm_size - 1), 128 * KiB);
+	relo_attrs.tseg_mask |= SMM_TSEG_WB;
+
+	*perm_smbase = (uintptr_t)handler_base;
+	*perm_smsize = handler_size;
+	*smm_save_state_size = sizeof(amd64_smm_state_save_area_t);
+}
+
+static void relocation_handler(int cpu, uintptr_t curr_smbase,
+				uintptr_t staggered_smbase)
+{
+	msr_t tseg_base, tseg_mask;
+	amd64_smm_state_save_area_t *smm_state;
+
+	tseg_base.lo = relo_attrs.tseg_base;
+	tseg_base.hi = 0;
+	wrmsr(SMM_ADDR_MSR, tseg_base);
+	tseg_mask.lo = relo_attrs.tseg_mask;
+	tseg_mask.hi = ((1 << (cpu_phys_address_size() - 32)) - 1);
+	wrmsr(SMM_MASK_MSR, tseg_mask);
+	smm_state = (void *)(SMM_AMD64_SAVE_STATE_OFFSET + curr_smbase);
+	smm_state->smbase = staggered_smbase;
+}
+
+static const struct mp_ops mp_ops = {
+	.pre_mp_init = pre_mp_init,
+	.get_cpu_count = get_cpu_count,
+	.get_smm_info = get_smm_info,
+	.relocation_handler = relocation_handler,
+	.post_mp_init = enable_smi_generation,
+};
+
+void stoney_init_cpus(struct device *dev)
+{
+	/* Clear for take-off */
+	if (mp_init_with_smm(dev->link_list, &mp_ops) < 0)
+		printk(BIOS_ERR, "MP initialization failure.\n");
+
+	/* The flash is now no longer cacheable. Reset to WP for performance. */
+	mtrr_use_temp_range(FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
+
+	set_warm_reset_flag();
+}
+
+static void model_15_init(struct device *dev)
+{
+	check_mca();
+	setup_lapic();
+
+	/*
+	 * Per AMD, sync an undocumented MSR with the PSP base address.
+	 * Experiments showed that if you write to the MSR after it has
+	 * been previously programmed, it causes a general protection fault.
+	 * Also, the MSR survives warm reset and S3 cycles, so we need to
+	 * test if it was previously written before writing to it.
+	 */
+	msr_t psp_msr;
+	uint32_t psp_bar; /* Note: NDA BKDG names this 32-bit register BAR3 */
+	psp_bar = pci_read_config32(SOC_PSP_DEV, PCI_BASE_ADDRESS_4);
+	psp_bar &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
+	psp_msr = rdmsr(0xc00110a2);
+	if (psp_msr.lo == 0) {
+		psp_msr.lo = psp_bar;
+		wrmsr(0xc00110a2, psp_msr);
+	}
+}
+
+static struct device_operations cpu_dev_ops = {
+	.init = model_15_init,
+};
+
+static struct cpu_device_id cpu_table[] = {
+	{ X86_VENDOR_AMD, 0x670f00 },
+	{ 0, 0 },
+};
+
+static const struct cpu_driver model_15 __cpu_driver = {
+	.ops      = &cpu_dev_ops,
+	.id_table = cpu_table,
+};
diff --git a/src/soc/amd/picasso/enable_usbdebug.c b/src/soc/amd/picasso/enable_usbdebug.c
new file mode 100644
index 0000000..19b9550
--- /dev/null
+++ b/src/soc/amd/picasso/enable_usbdebug.c
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+// Use simple device model for this file even in ramstage
+#define __SIMPLE_DEVICE__
+
+#include <stdint.h>
+#include <device/pci_ops.h>
+#include <device/pci_ehci.h>
+#include <device/pci_def.h>
+#include <soc/pci_devs.h>
+#include <soc/southbridge.h>
+
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+	pm_io_write8(PM_USB_ENABLE, PM_USB_ALL_CONTROLLERS);
+	return SOC_EHCI1_DEV;
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
+{
+	u32 reg32, value;
+
+	value = (port & 0x3) << DEBUG_PORT_SELECT_SHIFT;
+	value |= DEBUG_PORT_ENABLE;
+	reg32 = pci_read_config32(SOC_EHCI1_DEV, EHCI_HUB_CONFIG4);
+	reg32 &= ~DEBUG_PORT_MASK;
+	reg32 |= value;
+	pci_write_config32(SOC_EHCI1_DEV, EHCI_HUB_CONFIG4, reg32);
+}
diff --git a/src/soc/amd/picasso/finalize.c b/src/soc/amd/picasso/finalize.c
new file mode 100644
index 0000000..6572e1a
--- /dev/null
+++ b/src/soc/amd/picasso/finalize.c
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <bootstate.h>
+#include <timer.h>
+#include <console/console.h>
+
+static void per_core_finalize(void *unused)
+{
+	msr_t hwcr, mask;
+
+	/* Finalize SMM settings */
+	hwcr = rdmsr(HWCR_MSR);
+	if (hwcr.lo & SMM_LOCK) /* Skip if already locked, avoid GPF */
+		return;
+
+	if (CONFIG(SMM_TSEG)) {
+		mask = rdmsr(SMM_MASK_MSR);
+		mask.lo |= SMM_TSEG_VALID;
+		wrmsr(SMM_MASK_MSR, mask);
+	}
+
+	hwcr.lo |= SMM_LOCK;
+	wrmsr(HWCR_MSR, hwcr);
+}
+
+static void finalize_cores(void)
+{
+	int r;
+	printk(BIOS_SPEW, "Lock SMM configuration\n");
+
+	r = mp_run_on_all_cpus(per_core_finalize, NULL, 10 * USECS_PER_MSEC);
+	if (r)
+		printk(BIOS_WARNING, "Failed to finalize all cores\n");
+}
+
+static void soc_finalize(void *unused)
+{
+	finalize_cores();
+
+	post_code(POST_OS_BOOT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);
diff --git a/src/soc/amd/picasso/gpio.c b/src/soc/amd/picasso/gpio.c
new file mode 100644
index 0000000..f63a0d9
--- /dev/null
+++ b/src/soc/amd/picasso/gpio.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015 Intel Corporation
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <amdblocks/gpio_banks.h>
+#include <amdblocks/acpimmio.h>
+#include <soc/gpio.h>
+#include <soc/smi.h>
+
+static const struct soc_amd_event gpio_event_table[] = {
+	{ GPIO_1, GEVENT_19 },
+	{ GPIO_2, GEVENT_8 },
+	{ GPIO_3, GEVENT_2 },
+	{ GPIO_4, GEVENT_4 },
+	{ GPIO_5, GEVENT_7 },
+	{ GPIO_6, GEVENT_10 },
+	{ GPIO_7, GEVENT_11 },
+	{ GPIO_8, GEVENT_23 },
+	{ GPIO_9, GEVENT_22 },
+	{ GPIO_11, GEVENT_18 },
+	{ GPIO_13, GEVENT_21 },
+	{ GPIO_14, GEVENT_6 },
+	{ GPIO_15, GEVENT_20 },
+	{ GPIO_16, GEVENT_12 },
+	{ GPIO_17, GEVENT_13 },
+	{ GPIO_18, GEVENT_14 },
+	{ GPIO_21, GEVENT_5 },
+	{ GPIO_22, GEVENT_3 },
+	{ GPIO_23, GEVENT_16 },
+	{ GPIO_24, GEVENT_15 },
+	{ GPIO_65, GEVENT_0 },
+	{ GPIO_66, GEVENT_1 },
+	{ GPIO_68, GEVENT_9 },
+	{ GPIO_69, GEVENT_17 },
+};
+
+void soc_route_sci(uint8_t event)
+{
+	smi_write8(SMI_SCI_MAP(event), event);
+}
+
+void soc_get_gpio_event_table(const struct soc_amd_event **table, size_t *items)
+{
+	*table = gpio_event_table;
+	*items = ARRAY_SIZE(gpio_event_table);
+}
+
+void soc_gpio_hook(uint8_t gpio, uint8_t mux)
+{
+	/* Always program Gevent when WAKE_L_AGPIO2 is configured as WAKE_L */
+	if ((gpio == 2) && !(mux & AMD_GPIO_MUX_MASK))
+		soc_route_sci(GPIO_2_EVENT);
+}
diff --git a/src/soc/amd/picasso/i2c.c b/src/soc/amd/picasso/i2c.c
new file mode 100644
index 0000000..7f65a4f
--- /dev/null
+++ b/src/soc/amd/picasso/i2c.c
@@ -0,0 +1,241 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Google
+ *
+ * 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.
+ */
+
+#include <device/mmio.h>
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <delay.h>
+#include <drivers/i2c/designware/dw_i2c.h>
+#include <amdblocks/acpimmio.h>
+#include <soc/iomap.h>
+#include <soc/pci_devs.h>
+#include <soc/southbridge.h>
+#include <soc/i2c.h>
+#include "chip.h"
+
+#define I2C_BUS_ADDRESS(x) (I2C_BASE_ADDRESS + I2C_DEVICE_SIZE * (x))
+#define I2CA_BASE_ADDRESS (I2C_BUS_ADDRESS(0))
+#define I2CB_BASE_ADDRESS (I2C_BUS_ADDRESS(1))
+#define I2CC_BASE_ADDRESS (I2C_BUS_ADDRESS(2))
+#define I2CD_BASE_ADDRESS (I2C_BUS_ADDRESS(3))
+
+/* Global to provide access to chip.c */
+const char *i2c_acpi_name(const struct device *dev);
+
+static const uintptr_t i2c_bus_address[] = {
+	I2CA_BASE_ADDRESS,
+	I2CB_BASE_ADDRESS,
+	I2CC_BASE_ADDRESS,
+	I2CD_BASE_ADDRESS,
+};
+
+uintptr_t dw_i2c_base_address(unsigned int bus)
+{
+	return bus < I2C_DEVICE_COUNT ? i2c_bus_address[bus] : 0;
+}
+
+static const struct soc_amd_stoneyridge_config *get_soc_config(void)
+{
+	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
+
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_ERR, "%s: Could not find SoC devicetree config!\n",
+			__func__);
+		return NULL;
+	}
+
+	return dev->chip_info;
+}
+
+const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus)
+{
+	const struct soc_amd_stoneyridge_config *config;
+
+	if (bus >= ARRAY_SIZE(i2c_bus_address))
+		return NULL;
+
+	config = get_soc_config();
+	if (config == NULL)
+		return NULL;
+
+	return &config->i2c[bus];
+}
+
+const char *i2c_acpi_name(const struct device *dev)
+{
+	switch (dev->path.mmio.addr) {
+	case I2CA_BASE_ADDRESS:
+		return "I2CA";
+	case I2CB_BASE_ADDRESS:
+		return "I2CB";
+	case I2CC_BASE_ADDRESS:
+		return "I2CC";
+	case I2CD_BASE_ADDRESS:
+		return "I2CD";
+	default:
+		return NULL;
+	}
+}
+
+int dw_i2c_soc_dev_to_bus(struct device *dev)
+{
+	switch (dev->path.mmio.addr) {
+	case I2CA_BASE_ADDRESS:
+		return 0;
+	case I2CB_BASE_ADDRESS:
+		return 1;
+	case I2CC_BASE_ADDRESS:
+		return 2;
+	case I2CD_BASE_ADDRESS:
+		return 3;
+	}
+	return -1;
+}
+
+static void dw_i2c_soc_init(bool is_early_init)
+{
+	size_t i;
+	const struct soc_amd_stoneyridge_config *config;
+
+	config = get_soc_config();
+
+	if (config == NULL)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(config->i2c); i++) {
+		const struct dw_i2c_bus_config *cfg  = &config->i2c[i];
+
+		if (cfg->early_init != is_early_init)
+			continue;
+
+		if (dw_i2c_init(i, cfg))
+			printk(BIOS_ERR, "Failed to init i2c bus %zd\n", i);
+	}
+}
+
+void i2c_soc_early_init(void)
+{
+	dw_i2c_soc_init(true);
+}
+
+void i2c_soc_init(void)
+{
+	dw_i2c_soc_init(false);
+}
+
+struct device_operations stoneyridge_i2c_mmio_ops = {
+	/* TODO(teravest): Move I2C resource info here. */
+	.read_resources = DEVICE_NOOP,
+	.set_resources = DEVICE_NOOP,
+	.enable_resources = DEVICE_NOOP,
+	.scan_bus = scan_smbus,
+	.acpi_name = i2c_acpi_name,
+	.acpi_fill_ssdt_generator = dw_i2c_acpi_fill_ssdt,
+};
+
+/*
+ * I2C pins are open drain with external pull up, so in order to bit bang them
+ * all, SCL pins must become GPIO inputs with no pull, then they need to be
+ * toggled between input-no-pull and output-low. This table is for the initial
+ * conversion of all SCL pins to input with no pull.
+ */
+static const struct soc_amd_gpio i2c_2_gpi[] = {
+	PAD_GPI(I2C0_SCL_PIN, PULL_NONE),
+	PAD_GPI(I2C1_SCL_PIN, PULL_NONE),
+	PAD_GPI(I2C2_SCL_PIN, PULL_NONE),
+	PAD_GPI(I2C3_SCL_PIN, PULL_NONE),
+};
+#define saved_pins_count ARRAY_SIZE(i2c_2_gpi)
+
+/*
+ * To program I2C pins without destroying their programming, the registers
+ * that will be changed need to be saved first.
+ */
+static void save_i2c_pin_registers(uint8_t gpio,
+					struct soc_amd_i2c_save *save_table)
+{
+	uint32_t *gpio_ptr;
+
+	gpio_ptr = (uint32_t *)gpio_get_address(gpio);
+	save_table->mux_value = iomux_read8(gpio);
+	save_table->control_value = read32(gpio_ptr);
+}
+
+static void restore_i2c_pin_registers(uint8_t gpio,
+					struct soc_amd_i2c_save *save_table)
+{
+	uint32_t *gpio_ptr;
+
+	gpio_ptr = (uint32_t *)gpio_get_address(gpio);
+	iomux_write8(gpio, save_table->mux_value);
+	iomux_read8(gpio);
+	write32(gpio_ptr, save_table->control_value);
+	read32(gpio_ptr);
+}
+
+/* Slaves to be reset are controlled by devicetree register i2c_scl_reset */
+void sb_reset_i2c_slaves(void)
+{
+	const struct soc_amd_stoneyridge_config *cfg;
+	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
+	struct soc_amd_i2c_save save_table[saved_pins_count];
+	uint8_t i, j, control;
+
+	if (!dev || !dev->chip_info)
+		return;
+	cfg = dev->chip_info;
+	control = cfg->i2c_scl_reset & GPIO_I2C_MASK;
+	if (control == 0)
+		return;
+
+	/* Save and reprogram I2C SCL pins */
+	for (i = 0; i < saved_pins_count; i++)
+		save_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]);
+	program_gpios(i2c_2_gpi, saved_pins_count);
+
+	/*
+	 * Toggle SCL back and forth 9 times under 100KHz. A single read is
+	 * needed after the writes to force the posted write to complete.
+	 */
+	for (j = 0; j < 9; j++) {
+		if (control & GPIO_I2C0_SCL)
+			write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_LOW);
+		if (control & GPIO_I2C1_SCL)
+			write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_LOW);
+		if (control & GPIO_I2C2_SCL)
+			write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_LOW);
+		if (control & GPIO_I2C3_SCL)
+			write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_LOW);
+
+		read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */
+		udelay(4); /* 4usec gets 85KHz for 1 pin, 70KHz for 4 pins */
+
+		if (control & GPIO_I2C0_SCL)
+			write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_HIGH);
+		if (control & GPIO_I2C1_SCL)
+			write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_HIGH);
+		if (control & GPIO_I2C2_SCL)
+			write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_HIGH);
+		if (control & GPIO_I2C3_SCL)
+			write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_HIGH);
+
+		read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */
+		udelay(4);
+	}
+
+	/* Restore I2C pins. */
+	for (i = 0; i < saved_pins_count; i++)
+		restore_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]);
+}
diff --git a/src/soc/amd/picasso/include/soc/acpi.h b/src/soc/amd/picasso/include/soc/acpi.h
new file mode 100644
index 0000000..15a41ed
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/acpi.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corp.
+ * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.)
+ *
+ * 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.
+ */
+
+#ifndef __SOC_STONEYRIDGE_ACPI_H__
+#define __SOC_STONEYRIDGE_ACPI_H__
+
+#include <arch/acpi.h>
+
+#if CONFIG(STONEYRIDGE_LEGACY_FREE)
+	#define FADT_BOOT_ARCH ACPI_FADT_LEGACY_FREE
+#else
+	#define FADT_BOOT_ARCH (ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042)
+#endif
+
+#ifndef FADT_PM_PROFILE
+	#define FADT_PM_PROFILE PM_UNSPECIFIED
+#endif
+
+unsigned long southbridge_write_acpi_tables(struct device *device,
+		unsigned long current, struct acpi_rsdp *rsdp);
+
+void southbridge_inject_dsdt(struct device *device);
+
+const char *soc_acpi_name(const struct device *dev);
+
+#endif /* __SOC_STONEYRIDGE_ACPI_H__ */
diff --git a/src/soc/amd/picasso/include/soc/amd_pci_int_defs.h b/src/soc/amd/picasso/include/soc/amd_pci_int_defs.h
new file mode 100644
index 0000000..beef2bc
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/amd_pci_int_defs.h
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __AMD_PCI_INT_DEFS_H__
+#define __AMD_PCI_INT_DEFS_H__
+
+/*
+ * PIRQ and device routing - these define the index into the
+ * FCH PCI_INTR 0xC00/0xC01 interrupt routing table.
+ */
+
+#define PIRQ_NC		0x1f	/* Not Used */
+#define PIRQ_A		0x00	/* INT A */
+#define PIRQ_B		0x01	/* INT B */
+#define PIRQ_C		0x02	/* INT C */
+#define PIRQ_D		0x03	/* INT D */
+#define PIRQ_E		0x04	/* INT E */
+#define PIRQ_F		0x05	/* INT F */
+#define PIRQ_G		0x06	/* INT G */
+#define PIRQ_H		0x07	/* INT H */
+#define PIRQ_MISC	0x08	/* Miscellaneous IRQ Settings - See FCH Spec */
+#define PIRQ_MISC0	0x09	/* Miscellaneous0 IRQ Settings */
+#define PIRQ_MISC1	0x0a	/* Miscellaneous1 IRQ Settings */
+#define PIRQ_MISC2	0x0b	/* Miscellaneous2 IRQ Settings */
+#define PIRQ_SIRQA	0x0c	/* Serial IRQ INTA */
+#define PIRQ_SIRQB	0x0d	/* Serial IRQ INTB */
+#define PIRQ_SIRQC	0x0e	/* Serial IRQ INTC */
+#define PIRQ_SIRQD	0x0f	/* Serial IRQ INTD */
+#define PIRQ_SCI	0x10	/* SCI IRQ */
+#define PIRQ_SMBUS	0x11	/* SMBUS	14h.0 */
+#define PIRQ_ASF	0x12	/* ASF */
+#define PIRQ_HDA	0x13	/* HDA		14h.2 */
+#define PIRQ_FC		0x14	/* FC */
+#define PIRQ_PMON	0x16	/* Performance Monitor */
+#define PIRQ_SD		0x17	/* SD */
+#define PIRQ_SDIO	0x1a	/* SDIO */
+#define PIRQ_EHCI	0x30	/* USB EHCI	12h.0 */
+#define PIRQ_XHCI	0x34	/* USB XHCI	10h.0 */
+#define PIRQ_SATA	0x41	/* SATA		11h.0 */
+#define PIRQ_GPIO	0x62	/* GPIO Controller Interrupt */
+#define PIRQ_I2C0	0x70
+#define PIRQ_I2C1	0x71
+#define PIRQ_I2C2	0x72
+#define PIRQ_I2C3	0x73
+#define PIRQ_UART0	0x74
+#define PIRQ_UART1	0x75
+
+#endif /* __AMD_PCI_INT_DEFS_H__ */
diff --git a/src/soc/amd/picasso/include/soc/cpu.h b/src/soc/amd/picasso/include/soc/cpu.h
new file mode 100644
index 0000000..934a9f2
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/cpu.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_CPU_H__
+#define __STONEYRIDGE_CPU_H__
+
+#include <device/device.h>
+
+/*
+ *  Set a variable MTRR in bootblock and/or romstage.  AGESA will use the lowest
+ *  numbered registers.  Any values defined below are subtracted from the
+ *  highest numbered registers.
+ *
+ *  todo: Revisit this once AGESA no longer programs MTRRs.
+ */
+#define SOC_EARLY_VMTRR_FLASH 1
+#define SOC_EARLY_VMTRR_CAR_HEAP 2
+#define SOC_EARLY_VMTRR_TEMPRAM 3
+
+void stoney_init_cpus(struct device *dev);
+void check_mca(void);
+
+#endif /* __STONEYRIDGE_CPU_H__ */
diff --git a/src/soc/amd/picasso/include/soc/gpio.h b/src/soc/amd/picasso/include/soc/gpio.h
new file mode 100644
index 0000000..d8774f0
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/gpio.h
@@ -0,0 +1,308 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_GPIO_H__
+#define __STONEYRIDGE_GPIO_H__
+
+#define GPIO_DEVICE_NAME	"AMD0030"
+#define GPIO_DEVICE_DESC	"GPIO Controller"
+
+#ifndef __ACPI__
+#include <soc/iomap.h>
+#include <amdblocks/gpio_banks.h>
+
+/* The following sections describe only the GPIOs defined for this SOC */
+
+#define SOC_GPIO_TOTAL_PINS		149
+
+/* Bank 0: GPIO_0 - GPIO_62 */
+#define GPIO_0				0
+#define GPIO_1				1
+#define GPIO_2				2
+#define GPIO_3				3
+#define GPIO_4				4
+#define GPIO_5				5
+#define GPIO_6				6
+#define GPIO_7				7
+#define GPIO_8				8
+#define GPIO_9				9
+#define GPIO_10				10
+#define GPIO_11				11
+#define GPIO_12				12
+#define GPIO_13				13
+#define GPIO_14				14
+#define GPIO_15				15
+#define GPIO_16				16
+#define GPIO_17				17
+#define GPIO_18				18
+#define GPIO_19				19
+#define GPIO_20				20
+#define GPIO_21				21
+#define GPIO_22				22
+#define GPIO_23				23
+#define GPIO_24				24
+#define GPIO_25				25
+#define GPIO_26				26
+#define GPIO_39				39
+#define GPIO_40				40
+#define GPIO_42				42
+
+/* Bank 1: GPIO_64 - GPIO_127 */
+#define GPIO_64				64
+#define GPIO_65				65
+#define GPIO_66				66
+#define GPIO_67				67
+#define GPIO_68				68
+#define GPIO_69				69
+#define GPIO_70				70
+#define GPIO_71				71
+#define GPIO_72				72
+#define GPIO_74				74
+#define GPIO_75				75
+#define GPIO_76				76
+#define GPIO_84				84
+#define GPIO_85				85
+#define GPIO_86				86
+#define GPIO_87				87
+#define GPIO_88				88
+#define GPIO_89				89
+#define GPIO_90				90
+#define GPIO_91				91
+#define GPIO_92				92
+#define GPIO_93				93
+#define GPIO_95				95
+#define GPIO_96				96
+#define GPIO_97				97
+#define GPIO_98				98
+#define GPIO_99				99
+#define GPIO_100			100
+#define GPIO_101			101
+#define GPIO_102			102
+#define GPIO_113			113
+#define GPIO_114			114
+#define GPIO_115			115
+#define GPIO_116			116
+#define GPIO_117			117
+#define GPIO_118			118
+#define GPIO_119			119
+#define GPIO_120			120
+#define GPIO_121			121
+#define GPIO_122			122
+#define GPIO_126			126
+
+/* Bank 2: GPIO_128 - GPIO_183 */
+#define GPIO_129			129
+#define GPIO_130			130
+#define GPIO_131			131
+#define GPIO_132			132
+#define GPIO_133			133
+#define GPIO_134			134
+#define GPIO_135			135
+#define GPIO_136			136
+#define GPIO_137			137
+#define GPIO_138			138
+#define GPIO_139			139
+#define GPIO_140			140
+#define GPIO_141			141
+#define GPIO_142			142
+#define GPIO_143			143
+#define GPIO_144			144
+#define GPIO_145			145
+#define GPIO_146			146
+#define GPIO_147			147
+#define GPIO_148			148
+
+#define GPIO_SCL_HIGH			0
+#define GPIO_SCL_LOW			GPIO_OUTPUT_ENABLE
+
+/* IOMUX function names and values generated from BKDG. */
+#define GPIO_0_IOMUX_PWR_BTN_L 0
+#define GPIO_0_IOMUX_GPIOxx 1
+#define GPIO_1_IOMUX_SYS_RESET_L 0
+#define GPIO_1_IOMUX_GPIOxx 1
+#define GPIO_2_IOMUX_WAKE_L 0
+#define GPIO_2_IOMUX_GPIOxx 1
+#define GPIO_3_IOMUX_GPIOxx 0
+#define GPIO_4_IOMUX_GPIOxx 0
+#define GPIO_5_IOMUX_GPIOxx 0
+#define GPIO_5_IOMUX_DEVSLP0_S5 1
+#define GPIO_6_IOMUX_GPIOxx 0
+#define GPIO_6_IOMUX_LDT_RST_L 1
+#define GPIO_7_IOMUX_GPIOxx 0
+#define GPIO_7_IOMUX_LDT_PWROK 1
+#define GPIO_8_IOMUX_GPIOxx 0
+#define GPIO_8_IOMUX_SerPortTX_OUT 1
+#define GPIO_9_IOMUX_GPIOxx 0
+#define GPIO_9_IOMUX_SerPortRX_OUT 1
+#define GPIO_10_IOMUX_S0A3_GPIO 0
+#define GPIO_10_IOMUX_GPIOxx 1
+#define GPIO_11_IOMUX_GPIOxx 0
+#define GPIO_11_IOMUX_USB_OC7_L 1
+#define GPIO_12_IOMUX_IR_LED_L 0
+#define GPIO_12_IOMUX_LLB_L 1
+#define GPIO_12_IOMUX_GPIOxx 2
+#define GPIO_13_IOMUX_USB_OC5_L 0
+#define GPIO_13_IOMUX_GPIOxx 1
+#define GPIO_14_IOMUX_USB_OC6_L 0
+#define GPIO_14_IOMUX_GPIOxx 1
+#define GPIO_15_IOMUX_IR_RX1 0
+#define GPIO_15_IOMUX_GPIOxx 1
+#define GPIO_16_IOMUX_USB_OC0_L 0
+#define GPIO_16_IOMUX_TRST_L 1
+#define GPIO_16_IOMUX_GPIOxx 2
+#define GPIO_17_IOMUX_USB_OC1_L 0
+#define GPIO_17_IOMUX_TDI 1
+#define GPIO_17_IOMUX_GPIOxx 2
+#define GPIO_18_IOMUX_USB_OC2_L 0
+#define GPIO_18_IOMUX_TCK 1
+#define GPIO_18_IOMUX_GPIOxx 2
+#define GPIO_19_IOMUX_SCL1 0
+#define GPIO_19_IOMUX_I2C3_SCL 1
+#define GPIO_19_IOMUX_GPIOxx 2
+#define GPIO_20_IOMUX_SDA1 0
+#define GPIO_20_IOMUX_I2C3_SDA 1
+#define GPIO_20_IOMUX_GPIOxx 2
+#define GPIO_21_IOMUX_LPC_PD_L 0
+#define GPIO_21_IOMUX_GPIOxx 1
+#define GPIO_22_IOMUX_LPC_PME_L 0
+#define GPIO_22_IOMUX_GPIOxx 1
+#define GPIO_23_IOMUX_USB_OC4_L 0
+#define GPIO_23_IOMUX_IR_RX0 1
+#define GPIO_23_IOMUX_GPIOxx 2
+#define GPIO_24_IOMUX_USB_OC3_L 0
+#define GPIO_24_IOMUX_GPIOxx 1
+#define GPIO_25_IOMUX_SD0_CD 0
+#define GPIO_25_IOMUX_GPIOxx 1
+#define GPIO_26_IOMUX_PCIE_RST_L 0
+#define GPIO_26_IOMUX_GPIOxx 1
+#define GPIO_39_IOMUX_VDDGFX_PD 0
+#define GPIO_39_IOMUX_GPIOxx 1
+#define GPIO_40_IOMUX_GPIOxx 0
+#define GPIO_42_IOMUX_S5_MUX_CTRL 0
+#define GPIO_42_IOMUX_GPIOxx 1
+#define GPIO_64_IOMUX_GPIOxx 0
+#define GPIO_65_IOMUX_GPIOxx 0
+#define GPIO_66_IOMUX_GPIOxx 0
+#define GPIO_67_IOMUX_GPIOxx 0
+#define GPIO_67_IOMUX_DEVSLP0 1
+#define GPIO_69_IOMUX_GPIOxx 0
+#define GPIO_69_IOMUX_SGPIO_LOAD 1
+#define GPIO_70_IOMUX_GPIOxx 0
+#define GPIO_70_IOMUX_DEVSLP1 1
+#define GPIO_74_IOMUX_LPCCLK0 0
+#define GPIO_74_IOMUX_GPIOxx 1
+#define GPIO_75_IOMUX_LPCCLK1 0
+#define GPIO_75_IOMUX_GPIOxx 1
+#define GPIO_76_IOMUX_GPIOxx 0
+#define GPIO_76_IOMUX_SPI_TPM_CS_L 1
+#define GPIO_84_IOMUX_FANIN0 0
+#define GPIO_84_IOMUX_GPIOxx 1
+#define GPIO_85_IOMUX_FANOUT0 0
+#define GPIO_85_IOMUX_GPIOxx 1
+#define GPIO_86_IOMUX_GPIOxx 1
+#define GPIO_87_IOMUX_SERIRQ 0
+#define GPIO_87_IOMUX_GPIOxx 1
+#define GPIO_88_IOMUX_LPC_CLKRUN_L 0
+#define GPIO_88_IOMUX_GPIOxx 1
+#define GPIO_90_IOMUX_GPIOxx 0
+#define GPIO_91_IOMUX_SPKR 0
+#define GPIO_91_IOMUX_GPIOxx 1
+#define GPIO_92_IOMUX_CLK_REQ0_L 0
+#define GPIO_92_IOMUX_SATA_IS0_L 1
+#define GPIO_92_IOMUX_SATA_ZP0_L 2
+#define GPIO_92_IOMUX_GPIOxx 3
+#define GPIO_93_IOMUX_SD0_LED 0
+#define GPIO_93_IOMUX_GPIOxx 1
+#define GPIO_95_IOMUX_GPIOxx 0
+#define GPIO_96_IOMUX_GPIOxx 0
+#define GPIO_97_IOMUX_GPIOxx 0
+#define GPIO_98_IOMUX_GPIOxx 0
+#define GPIO_99_IOMUX_GPIOxx 0
+#define GPIO_100_IOMUX_GPIOxx 0
+#define GPIO_101_IOMUX_SD0_WP 0
+#define GPIO_101_IOMUX_GPIOxx 1
+#define GPIO_102_IOMUX_SD0_PWR_CTRL 0
+#define GPIO_102_IOMUX_GPIOxx 1
+#define GPIO_113_IOMUX_SCL0 0
+#define GPIO_113_IOMUX_I2C2_SCL 1
+#define GPIO_113_IOMUX_GPIOxx 2
+#define GPIO_114_IOMUX_SDA0 0
+#define GPIO_114_IOMUX_I2C2_SDA 1
+#define GPIO_114_IOMUX_GPIOxx 2
+#define GPIO_115_IOMUX_CLK_REQ1_L 0
+#define GPIO_115_IOMUX_GPIOxx 1
+#define GPIO_116_IOMUX_CLK_REQ2_L 0
+#define GPIO_116_IOMUX_GPIOxx 1
+#define GPIO_117_IOMUX_ESPI_CLK 0
+#define GPIO_117_IOMUX_GPIOxx 1
+#define GPIO_118_IOMUX_SPI_CS1_L 0
+#define GPIO_118_IOMUX_GPIOxx 1
+#define GPIO_119_IOMUX_SPI_CS2_L 0
+#define GPIO_119_IOMUX_ESPI_CS_L 1
+#define GPIO_119_IOMUX_GPIOxx 2
+#define GPIO_120_IOMUX_ESPI_DAT1 0
+#define GPIO_120_IOMUX_GPIOxx 1
+#define GPIO_121_IOMUX_ESPI_DAT0 0
+#define GPIO_121_IOMUX_GPIOxx 1
+#define GPIO_122_IOMUX_ESPI_DAT2 0
+#define GPIO_122_IOMUX_GPIOxx 1
+#define GPIO_126_IOMUX_GA20IN 0
+#define GPIO_126_IOMUX_GPIOxx 1
+#define GPIO_129_IOMUX_KBRST_L 0
+#define GPIO_129_IOMUX_GPIOxx 1
+#define GPIO_130_IOMUX_SATA_ACT_L 0
+#define GPIO_130_IOMUX_GPIOxx 1
+#define GPIO_131_IOMUX_CLK_REQ3_L 0
+#define GPIO_131_IOMUX_SATA_IS1_L 1
+#define GPIO_131_IOMUX_SATA_ZP1_L 2
+#define GPIO_131_IOMUX_GPIOxx 3
+#define GPIO_132_IOMUX_CLK_REQG_L 0
+#define GPIO_132_IOMUX_OSCIN 1
+#define GPIO_132_IOMUX_GPIOxx 2
+#define GPIO_133_IOMUX_ESPI_DAT3 0
+#define GPIO_133_IOMUX_GPIOxx 1
+#define GPIO_135_IOMUX_UART0_CTS_L 0
+#define GPIO_135_IOMUX_GPIOxx 1
+#define GPIO_136_IOMUX_UART0_RXD 0
+#define GPIO_136_IOMUX_GPIOxx 1
+#define GPIO_137_IOMUX_UART0_RTS_L 0
+#define GPIO_137_IOMUX_GPIOxx 1
+#define GPIO_138_IOMUX_UART0_TXD 0
+#define GPIO_138_IOMUX_GPIOxx 1
+#define GPIO_139_IOMUX_UART0_INTR 0
+#define GPIO_139_IOMUX_GPIOxx 1
+#define GPIO_140_IOMUX_UART1_CTS_L 0
+#define GPIO_140_IOMUX_GPIOxx 1
+#define GPIO_141_IOMUX_UART1_RXD 0
+#define GPIO_141_IOMUX_GPIOxx 1
+#define GPIO_142_IOMUX_UART1_RTS_L 0
+#define GPIO_142_IOMUX_GPIOxx 1
+#define GPIO_143_IOMUX_UART1_TXD 0
+#define GPIO_143_IOMUX_GPIOxx 1
+#define GPIO_144_IOMUX_UART1_INTR 0
+#define GPIO_144_IOMUX_GPIOxx 1
+#define GPIO_145_IOMUX_I2C0_SCL 0
+#define GPIO_145_IOMUX_GPIOxx 1
+#define GPIO_146_IOMUX_I2C0_SDA 0
+#define GPIO_146_IOMUX_GPIOxx 1
+#define GPIO_147_IOMUX_I2C1_SCL 0
+#define GPIO_147_IOMUX_GPIOxx 1
+#define GPIO_148_IOMUX_I2C1_SDA 0
+#define GPIO_148_IOMUX_GPIOxx 1
+
+#define GPIO_2_EVENT GEVENT_8
+
+#endif /* __ACPI__ */
+#endif /* __STONEYRIDGE_GPIO_H__ */
diff --git a/src/soc/amd/picasso/include/soc/i2c.h b/src/soc/amd/picasso/include/soc/i2c.h
new file mode 100644
index 0000000..62575d0
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/i2c.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_I2C_H__
+#define __STONEYRIDGE_I2C_H__
+
+#include <soc/gpio.h>
+
+struct soc_amd_i2c_save {
+	uint32_t control_value;
+	uint8_t mux_value;
+};
+
+#define GPIO_I2C0_SCL			BIT(0)
+#define GPIO_I2C1_SCL			BIT(1)
+#define GPIO_I2C2_SCL			BIT(2)
+#define GPIO_I2C3_SCL			BIT(3)
+#define GPIO_I2C_MASK			(BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+#define I2C0_SCL_PIN			GPIO_145
+#define I2C1_SCL_PIN			GPIO_147
+#define I2C2_SCL_PIN			GPIO_113
+#define I2C3_SCL_PIN			GPIO_19
+
+#define GPIO_I2C0_ADDRESS		GPIO_BANK2_CONTROL(I2C0_SCL_PIN)
+#define GPIO_I2C1_ADDRESS		GPIO_BANK2_CONTROL(I2C1_SCL_PIN)
+#define GPIO_I2C2_ADDRESS		GPIO_BANK1_CONTROL(I2C2_SCL_PIN)
+#define GPIO_I2C3_ADDRESS		GPIO_BANK0_CONTROL(I2C3_SCL_PIN)
+
+#define I2C0_SCL_PIN_IOMUX_GPIOxx	GPIO_145_IOMUX_GPIOxx
+#define I2C1_SCL_PIN_IOMUX_GPIOxx	GPIO_147_IOMUX_GPIOxx
+#define I2C2_SCL_PIN_IOMUX_GPIOxx	GPIO_113_IOMUX_GPIOxx
+#define I2C3_SCL_PIN_IOMUX_GPIOxx	GPIO_19_IOMUX_GPIOxx
+
+void sb_reset_i2c_slaves(void);
+
+#endif /* __STONEYRIDGE_I2C_H__ */
diff --git a/src/soc/amd/picasso/include/soc/iomap.h b/src/soc/amd/picasso/include/soc/iomap.h
new file mode 100644
index 0000000..612b6e8
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/iomap.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Raptor Engineering, LLC
+ * Copyright 2017 Google Inc.
+ *
+ * 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.
+ */
+
+#ifndef __SOC_STONEYRIDGE_IOMAP_H__
+#define __SOC_STONEYRIDGE_IOMAP_H__
+
+/* MMIO Ranges */
+#define PSP_MAILBOX_BAR3_BASE		0xf0a00000
+#define SPI_BASE_ADDRESS		0xfec10000
+#define IO_APIC2_ADDR			0xfec20000
+
+/*
+ * AcpiMmio blocks are at fixed offsets from FED8_0000h and enabled in PMx04[1].
+ * All ranges not specified as supported below may, or may not, be listed in
+ * any documentation but should be considered reserved through FED8_1FFFh.
+ */
+#include <amdblocks/acpimmio_map.h>
+#define SUPPORTS_ACPIMMIO_SMI_BASE	1 /* 0xfed80100 */
+#define SUPPORTS_ACPIMMIO_PMIO_BASE	1 /* 0xfed80300 */
+#define SUPPORTS_ACPIMMIO_BIOSRAM_BASE	1 /* 0xfed80500 */
+#define SUPPORTS_ACPIMMIO_ACPI_BASE	1 /* 0xfed80800 */
+#define SUPPORTS_ACPIMMIO_ASF_BASE	1 /* 0xfed80900 */
+#define SUPPORTS_ACPIMMIO_SMBUS_BASE	1 /* 0xfed80a00 */
+#define SUPPORTS_ACPIMMIO_IOMUX_BASE	1 /* 0xfed80d00 */
+#define SUPPORTS_ACPIMMIO_MISC_BASE	1 /* 0xfed80e00 */
+#define SUPPORTS_ACPIMMIO_GPIO0_BASE	1 /* 0xfed81500 */
+#define SUPPORTS_ACPIMMIO_GPIO1_BASE	1 /* 0xfed81800 */
+#define SUPPORTS_ACPIMMIO_GPIO2_BASE	1 /* 0xfed81700 */
+#define SUPPORTS_ACPIMMIO_XHCIPM_BASE	1 /* 0xfed81c00 */
+#define SUPPORTS_ACPIMMIO_AOAC_BASE	1 /* 0xfed81e00 */
+
+#define ALINK_AHB_ADDRESS		0xfedc0000
+
+/* I2C fixed address */
+#define I2C_BASE_ADDRESS		0xfedc2000
+#define I2C_DEVICE_SIZE			0x00001000
+#define I2C_DEVICE_COUNT		4
+
+#if CONFIG(HPET_ADDRESS_OVERRIDE)
+#error HPET address override is not allowed and must be fixed at 0xfed00000
+#endif
+#define HPET_BASE_ADDRESS		0xfed00000
+
+#define APU_UART0_BASE			0xfedc6000
+#define APU_UART1_BASE			0xfedc8000
+
+#define FLASH_BASE_ADDR			((0xffffffff - CONFIG_ROM_SIZE) + 1)
+
+/* I/O Ranges */
+#define ACPI_SMI_CTL_PORT		0xb2
+#define STONEYRIDGE_ACPI_IO_BASE	CONFIG_STONEYRIDGE_ACPI_IO_BASE
+#define  ACPI_PM_EVT_BLK	(STONEYRIDGE_ACPI_IO_BASE + 0x00) /* 4 bytes */
+#define  ACPI_PM1_STS		(ACPI_PM_EVT_BLK + 0x00)	  /* 2 bytes */
+#define  ACPI_PM1_EN		(ACPI_PM_EVT_BLK + 0x02)	  /* 2 bytes */
+#define  ACPI_PM1_CNT_BLK	(STONEYRIDGE_ACPI_IO_BASE + 0x04) /* 2 bytes */
+#define  ACPI_CPU_CONTROL	(STONEYRIDGE_ACPI_IO_BASE + 0x08) /* 6 bytes */
+#define  ACPI_GPE0_BLK		(STONEYRIDGE_ACPI_IO_BASE + 0x10) /* 8 bytes */
+#define  ACPI_GPE0_STS		(ACPI_GPE0_BLK + 0x00)		  /* 4 bytes */
+#define  ACPI_GPE0_EN		(ACPI_GPE0_BLK + 0x04)		  /* 4 bytes */
+#define  ACPI_PM_TMR_BLK	(STONEYRIDGE_ACPI_IO_BASE + 0x18) /* 4 bytes */
+#define SMB_BASE_ADDR			0xb00
+#define PM2_INDEX			0xcd0
+#define PM2_DATA			0xcd1
+#define BIOSRAM_INDEX			0xcd4
+#define BIOSRAM_DATA			0xcd5
+#define AB_INDX				0xcd8
+#define AB_DATA				(AB_INDX+4)
+#define SYS_RESET			0xcf9
+
+/* BiosRam Ranges at 0xfed80500 or I/O 0xcd4/0xcd5 */
+#define BIOSRAM_CBMEM_TOP		0xf0 /* 4 bytes */
+#define BIOSRAM_UMA_SIZE		0xf4 /* 4 bytes */
+#define BIOSRAM_UMA_BASE		0xf8 /* 8 bytes */
+
+#endif /* __SOC_STONEYRIDGE_IOMAP_H__ */
diff --git a/src/soc/amd/picasso/include/soc/northbridge.h b/src/soc/amd/picasso/include/soc/northbridge.h
new file mode 100644
index 0000000..60a6ea2
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/northbridge.h
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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.
+ */
+
+#ifndef __PI_STONEYRIDGE_NORTHBRIDGE_H__
+#define __PI_STONEYRIDGE_NORTHBRIDGE_H__
+
+#include <device/device.h>
+#include <types.h>
+
+/* D0F0 - Root Complex */
+
+/* NB IOAPIC registers */
+#define NB_IOAPIC_INDEX		0xf8
+#define NB_IOAPIC_DATA		0xfc
+#define  NB_IOAPIC_FEATURE_CTRL	0x00
+#define  NB_IOAPIC_ADDRESS_LOW	0x01
+#define  NB_IOAPIC_ADDRESS_HIGH	0x02
+#define  NB_IOAPIC_GBIF_IRR	0x0f
+#define  NB_IOAPIC_BR0_IRR	0x10
+#define  NB_IOAPIC_BR1_IRR	0x11
+#define  NB_IOAPIC_BR2_IRR	0x12
+#define  NB_IOAPIC_BR3_IRR	0x13
+#define  NB_IOAPIC_BR4_IRR	0x14
+#define  NB_IOAPIC_APG_IRR	0x2f
+#define  NB_IOAPIC_SPG_IRR	0x30
+#define  NB_IOAPIC_SER_IRQ_IRR	0x31
+#define  NB_IOAPIC_SCRATCH0	0x3e
+#define  NB_IOAPIC_SCRATCH1	0x3f
+
+#define AP_SCRATCH_REG		NB_IOAPIC_SCRATCH0
+
+/* D1F1 - HDA Configuration Registers */
+#define HDA_DEV_CTRL_STATUS	0x60
+#define   HDA_NO_SNOOP_EN	BIT(11)
+
+/* D18F0 - HT Configuration Registers */
+#define D18F0_NODE_ID		0x60
+#define D18F0_CPU_CNT		0x62 /* BKDG defines as a field in DWORD 0x60 */
+# define CPU_CNT_MASK		0x1f /*  CpuCnt + 1 = no. CPUs */
+#define HT_INIT_CONTROL		0x6c
+# define HTIC_BIOSR_DETECT	((1 << 5) | (1 << 9) | (1 << 10))
+# define HTIC_COLD_RST_DET	BIT(4)
+
+/* D18F1 - Address Map Registers */
+
+/* MMIO base and limit */
+#define D18F1_MMIO_BASE0_LO	0x80
+# define MMIO_WE		(1 << 1)
+# define MMIO_RE		(1 << 0)
+#define D18F1_MMIO_LIMIT0_LO	0x84
+# define MMIO_NP		(1 << 7)
+#define D18F1_IO_BASE0_LO	0xc0
+#define D18F1_IO_BASE1_LO	0xc8
+#define D18F1_IO_BASE2_LO	0xd0
+#define D18F1_IO_BASE3_LO	0xd8
+#define D18F1_MMIO_BASE7_LO	0xb8
+#define D18F1_MMIO_BASELIM0_HI	0x180
+#define D18F1_MMIO_BASE8_LO	0x1a0
+#define D18F1_MMIO_LIMIT8_LO	0x1a4
+#define D18F1_MMIO_BASE11_LO	0x1b8
+#define D18F1_MMIO_BASELIM8_HI	0x1c0
+#define NB_MMIO_BASE_LO(reg)	((reg) * 2 * sizeof(uint32_t) + (((reg) < 8) \
+					? D18F1_MMIO_BASE0_LO \
+					: D18F1_MMIO_BASE8_LO \
+						- 8 * sizeof(uint64_t)))
+#define NB_MMIO_LIMIT_LO(reg)	(NB_MMIO_BASE_LO(reg) + sizeof(uint32_t))
+#define NB_MMIO_BASELIM_HI(reg)	((reg) * sizeof(uint32_t) + (((reg) < 8) \
+					? D18F1_MMIO_BASELIM0_HI \
+					: D18F1_MMIO_BASELIM8_HI \
+						- 8 * sizeof(uint32_t)))
+/* I/O base and limit */
+#define D18F1_IO_BASE0		0xc0
+# define IO_WE			(1 << 1)
+# define IO_RE			(1 << 0)
+#define D18F1_IO_LIMIT0		0xc4
+#define NB_IO_BASE(reg)		((reg) * 2 * sizeof(uint32_t) + D18F1_IO_BASE0)
+#define NB_IO_LIMIT(reg)	(NB_IO_BASE(reg) + sizeof(uint32_t))
+
+#define D18F1_DRAM_HOLE		0xf0
+# define DRAM_HOIST_VALID	(1 << 1)
+# define DRAM_HOLE_VALID	(1 << 0)
+#define D18F1_VGAEN		0xf4
+# define VGA_ADDR_ENABLE	(1 << 0)
+
+/* D18F5 */
+#define NB_CAPABILITIES2	0x84
+#define   CMP_CAP_MASK		0xff
+
+enum {
+	/* SMM handler area. */
+	SMM_SUBREGION_HANDLER,
+	/* SMM cache region. */
+	SMM_SUBREGION_CACHE,
+	/* Chipset specific area. */
+	SMM_SUBREGION_CHIPSET,
+	/* Total sub regions supported. */
+	SMM_SUBREGION_NUM,
+};
+
+/*
+ * Fills in the arguments for the entire SMM region covered by chipset
+ * protections. e.g. TSEG.
+ */
+void smm_region_info(void **start, size_t *size);
+/*
+ * Fills in the start and size for the requested SMM subregion. Returns
+ * 0 on success, < 0 on failure.
+ */
+int smm_subregion(int sub, void **start, size_t *size);
+void domain_enable_resources(struct device *dev);
+void domain_set_resources(struct device *dev);
+void fam15_finalize(void *chip_info);
+uint32_t nb_ioapic_read(unsigned int index);
+void nb_ioapic_write(unsigned int index, uint32_t value);
+void *get_ap_entry_ptr(void);
+void set_ap_entry_ptr(void *entry);
+void set_warm_reset_flag(void);
+int is_warm_reset(void);
+
+#endif /* __PI_STONEYRIDGE_NORTHBRIDGE_H__ */
diff --git a/src/soc/amd/picasso/include/soc/nvs.h b/src/soc/amd/picasso/include/soc/nvs.h
new file mode 100644
index 0000000..08d4697
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/nvs.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.)
+ *
+ * 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.
+ */
+
+/*
+ * NOTE: The layout of the global_nvs_t structure below must match the layout
+ * in soc/soc/amd/stoneyridge/acpi/globalnvs.asl !!!
+ *
+ */
+
+#ifndef __SOC_STONEYRIDGE_NVS_H__
+#define __SOC_STONEYRIDGE_NVS_H__
+
+#include <commonlib/helpers.h>
+#include <stdint.h>
+#include <vendorcode/google/chromeos/gnvs.h>
+#include <soc/southbridge.h>
+
+typedef struct global_nvs_t {
+	/* Miscellaneous */
+	uint8_t		pcnt; /* 0x00 - Processor Count */
+	uint8_t		ppcm; /* 0x01 - Max PPC State */
+	uint8_t		lids; /* 0x02 - LID State */
+	uint8_t		pwrs; /* 0x03 - AC Power State */
+	uint8_t		dpte; /* 0x04 - Enable DPTF */
+	uint32_t	cbmc; /* 0x05 - 0x08 - coreboot Memory Console */
+	uint64_t	pm1i; /* 0x09 - 0x10 - System Wake Source - PM1 Index */
+	uint64_t	gpei; /* 0x11 - 0x18 - GPE Wake Source */
+	uint64_t	nhla; /* 0x19 - 0x20 - NHLT Address */
+	uint32_t	nhll; /* 0x21 - 0x24 - NHLT Length */
+	uint32_t	prt0; /* 0x25 - 0x28 - PERST_0 Address */
+	uint8_t		scdp; /* 0x29 - SD_CD GPIO portid */
+	uint8_t		scdo; /* 0x2A - GPIO pad relative offset */
+	uint8_t		tmps; /* 0x2B - Temperature Sensor ID */
+	uint8_t		tlvl; /* 0x2C - Throttle Level Limit */
+	uint8_t		flvl; /* 0x2D - Current FAN Level */
+	uint8_t		tcrt; /* 0x2E - Critical Threshold */
+	uint8_t		tpsv; /* 0x2F - Passive Threshold */
+	uint8_t		tmax; /* 0x30 - CPU Tj_max */
+	uint8_t		pad1[3];
+	aoac_devs_t	aoac; /* 0x34 - AOAC device enables */
+	uint16_t	fw00; /* 0x38 - XhciFwRomAddr_Rom, Boot RAM */
+	uint16_t	fw02; /* 0x3A - XhciFwRomAddr_Ram, Instr RAM */
+	uint32_t	fw01; /* 0x3C - XhciFwRamAddr_Rom, Boot RAM sz/base */
+	uint32_t	fw03; /* 0x40 - XhciFwRomAddr_Ram, Instr RAM sz/base */
+	uint32_t	eh10; /* 0x40 - EHCI BAR */
+	uint8_t		unused[184];
+
+	/* ChromeOS specific (0x100 - 0xfff) */
+	chromeos_acpi_t chromeos;
+} __packed global_nvs_t;
+check_member(global_nvs_t, chromeos, GNVS_CHROMEOS_ACPI_OFFSET);
+
+#endif /* __SOC_STONEYRIDGE_NVS_H__ */
diff --git a/src/soc/amd/picasso/include/soc/pci_devs.h b/src/soc/amd/picasso/include/soc/pci_devs.h
new file mode 100644
index 0000000..02fed7a
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/pci_devs.h
@@ -0,0 +1,198 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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.
+ */
+
+#ifndef __PI_STONEYRIDGE_PCI_DEVS_H__
+#define __PI_STONEYRIDGE_PCI_DEVS_H__
+
+#include <device/pci_def.h>
+
+#if !defined(__SIMPLE_DEVICE__)
+#include <device/device.h>
+#define _SOC_DEV(slot, func)	pcidev_on_root(slot, func)
+#else
+#define _SOC_DEV(slot, func)	PCI_DEV(0, slot, func)
+#endif
+
+/* GNB Root Complex */
+#define GNB_DEV			0x0
+#define GNB_FUNC		0
+#define GNB_DEVID		0x1576
+#define GNB_DEVFN		PCI_DEVFN(GNB_DEV, GNB_FUNC)
+#define SOC_GNB_DEV		_SOC_DEV(GNB_DEV, GNB_FUNC)
+
+/* IOMMU */
+#define IOMMU_DEV		0x0
+#define IOMMU_FUNC		2
+#define IOMMU_DEVID		0x1577
+#define IOMMU_DEVFN		PCI_DEVFN(IOMMU_DEV, IOMMU_FUNC)
+#define SOC_IOMMU_DEV		_SOC_DEV(IOMMU_DEV, IOMMU_FUNC)
+
+/* Internal Graphics */
+#define GFX_DEV			0x1
+#define GFX_FUNC		0
+#define GFX_DEVID		0x98e4 /* subject to SKU/OPN variation */
+#define GFX_DEVFN		PCI_DEVFN(GFX_DEV, GFX_FUNC)
+#define SOC_GFX_DEV		_SOC_DEV(GFX_DEV, GFX_FUNC)
+
+/* HD Audio 0 */
+#define HDA0_DEV		0x1
+#define HDA0_FUNC		1
+#define HDA0_DEVID		0x15b3
+#define HDA0_DEVFN		PCI_DEVFN(HDA0_DEV, HDA0_FUNC)
+#define SOC_HDA0_DEV		_SOC_DEV(HDA0_DEV, HDA0_FUNC)
+
+/* Host Bridge */
+#define HOST_DEV		0x2
+#define HOST_FUNC		0
+#define HOST_DEVID		0x157b
+#define HOST_DEVFN		PCI_DEVFN(HOST_DEV, HOST_FUNC)
+#define SOC_HOST_DEV		_SOC_DEV(HOST_DEV, HOST_FUNC)
+
+/* PCIe GPP Bridge 0 */
+#define PCIE0_DEV		0x2
+#define PCIE0_FUNC		1
+#define PCIE0_DEVID		0x157c
+#define PCIE0_DEVFN		PCI_DEVFN(PCIE0_DEV, PCIE0_FUNC)
+#define SOC_PCIE0_DEV		_SOC_DEV(PCIE0_DEV, PCIE0_FUNC)
+
+/* PCIe GPP Bridge 1 */
+#define PCIE1_DEV		0x2
+#define PCIE1_FUNC		2
+#define PCIE1_DEVID		0x157c
+#define PCIE1_DEVFN		PCI_DEVFN(PCIE1_DEV, PCIE1_FUNC)
+#define SOC_PCIE1_DEV		_SOC_DEV(PCIE1_DEV, PCIE1_FUNC)
+
+/* PCIe GPP Bridge 2 */
+#define PCIE2_DEV		0x2
+#define PCIE2_FUNC		3
+#define PCIE2_DEVID		0x157c
+#define PCIE2_DEVFN		PCI_DEVFN(PCIE2_DEV, PCIE2_FUNC)
+#define SOC_PCIE2_DEV		_SOC_DEV(PCIE2_DEV, PCIE2_FUNC)
+
+/* PCIe GPP Bridge 3 */
+#define PCIE3_DEV		0x2
+#define PCIE3_FUNC		4
+#define PCIE3_DEVID		0x157c
+#define PCIE3_DEVFN		PCI_DEVFN(PCIE3_DEV, PCIE3_FUNC)
+#define SOC_PCIE3_DEV		_SOC_DEV(PCIE3_DEV, PCIE3_FUNC)
+
+/* PCIe GPP Bridge 4 */
+#define PCIE4_DEV		0x2
+#define PCIE4_FUNC		5
+#define PCIE4_DEVID		0x157c
+#define PCIE4_DEVFN		PCI_DEVFN(PCIE4_DEV, PCIE4_FUNC)
+#define SOC_PCIE4_DEV		_SOC_DEV(PCIE4_DEV, PCIE4_FUNC)
+
+/* Platform Security Processor */
+#define PSP_DEV			0x8
+#define PSP_FUNC		0
+#define PSP_DEVID		0x1578
+#define PSP_DEVFN		PCI_DEVFN(PSP_DEV, PSP_FUNC)
+#define SOC_PSP_DEV		_SOC_DEV(PSP_DEV, PSP_FUNC)
+
+/* HD Audio 1 */
+#define HDA1_DEV		0x9
+#define HDA1_FUNC		2
+#define HDA1_DEVID		0x157a
+#define HDA1_DEVFN		PCI_DEVFN(HDA1_DEV, HDA1_FUNC)
+#define SOC_HDA1_DEV		_SOC_DEV(HDA1_DEV, HDA1_FUNC)
+
+/* HT Configuration */
+#define HT_DEV			0x18
+#define HT_FUNC			0
+#define HT_DEVID		0x15b0
+#define HT_DEVFN		PCI_DEVFN(HT_DEV, HT_FUNC)
+#define SOC_HT_DEV		_SOC_DEV(HT_DEV, HT_FUNC)
+
+/* Address Maps */
+#define ADDR_DEV		0x18
+#define ADDR_FUNC		1
+#define ADDR_DEVID		0x15b1
+#define ADDR_DEVFN		PCI_DEVFN(ADDR_DEV, ADDR_FUNC)
+#define SOC_ADDR_DEV		_SOC_DEV(ADDR_DEV, ADDR_FUNC)
+
+/* DRAM Configuration */
+#define DCT_DEV			0x18
+#define DCT_FUNC		2
+#define DCT_DEVID		0x15b2
+#define DCT_DEVFN		PCI_DEVFN(DCT_DEV, DCT_FUNC)
+#define SOC_DCT_DEV		_SOC_DEV(DCT_DEV, DCT_FUNC)
+
+/* Misc. Configuration */
+#define MISC_DEV		0x18
+#define MISC_FUNC		3
+#define MISC_DEVID		0x15b3
+#define MISC_DEVFN		PCI_DEVFN(MISC_DEV, MISC_FUNC)
+#define SOC_MISC_DEV		_SOC_DEV(MISC_DEV, MISC_FUNC)
+
+/* PM Configuration */
+#define PM_DEV			0x18
+#define PM_FUNC			4
+#define PM_DEVID		0x15b4
+#define PM_DEVFN		PCI_DEVFN(PM_DEV, PM_FUNC)
+#define SOC_PM_DEV		_SOC_DEV(PM_DEV, PM_FUNC)
+
+/* Northbridge Configuration */
+#define NB_DEV			0x18
+#define NB_FUNC			5
+#define NB_DEVID		0x15b5
+#define NB_DEVFN		PCI_DEVFN(NB_DEV, NB_FUNC)
+#define SOC_NB_DEV		_SOC_DEV(NB_DEV, NB_FUNC)
+
+/* XHCI */
+#define XHCI_DEV		0x10
+#define XHCI_FUNC		0
+#define XHCI_DEVID		0x7914
+#define XHCI_DEVFN		PCI_DEVFN(XHCI_DEV, XHCI_FUNC)
+#define SOC_XHCI_DEV		_SOC_DEV(XHCI_DEV, XHCI_FUNC)
+
+/* SATA */
+#define SATA_DEV		0x11
+#define SATA_FUNC		0
+#define SATA_IDE_DEVID		0x7900
+#define AHCI_DEVID_MS		0x7901
+#define AHCI_DEVID_AMD		0x7904
+#define SATA_DEVFN		PCI_DEVFN(SATA_DEV, SATA_FUNC)
+#define SOC_SATA_DEV		_SOC_DEV(SATA_DEV, SATA_FUNC)
+
+/* EHCI */
+#define EHCI_DEV		0x12
+#define EHCI_FUNC		0
+#define EHCI_DEVID		0x7908
+#define EHCI1_DEVFN		PCI_DEVFN(EHCI_DEV, EHCI_FUNC)
+#define SOC_EHCI1_DEV		_SOC_DEV(EHCI_DEV, EHCI_FUNC)
+
+/* SMBUS */
+#define SMBUS_DEV		0x14
+#define SMBUS_FUNC		0
+#define SMBUS_DEVID		0x790b
+#define SMBUS_DEVFN		PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)
+#define SOC_SMBUS_DEV		_SOC_DEV(SMBUS_DEV, SMBUS_FUNC)
+
+/* LPC BUS */
+#define PCU_DEV			0x14
+#define LPC_FUNC		3
+#define LPC_DEVID		0x790e
+#define LPC_DEVFN		PCI_DEVFN(PCU_DEV, LPC_FUNC)
+#define SOC_LPC_DEV		_SOC_DEV(PCU_DEV, LPC_FUNC)
+
+/* SD Controller */
+#define SD_DEV			0x14
+#define SD_FUNC			7
+#define SD_DEVID		0x7906
+#define SD_DEVFN		PCI_DEVFN(SD_DEV, SD_FUNC)
+#define SOC_SD_DEV		_SOC_DEV(SD_DEV, SD_FUNC)
+
+#endif /* __PI_STONEYRIDGE_PCI_DEVS_H__ */
diff --git a/src/soc/amd/picasso/include/soc/romstage.h b/src/soc/amd/picasso/include/soc/romstage.h
new file mode 100644
index 0000000..6ce79b4
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/romstage.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Google LLC
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_ROMSTAGE_H__
+#define __STONEYRIDGE_ROMSTAGE_H__
+
+void mainboard_romstage_entry(int s3_resume);
+
+#endif /* __STONEYRIDGE_ROMSTAGE_H__ */
diff --git a/src/soc/amd/picasso/include/soc/smbus.h b/src/soc/amd/picasso/include/soc/smbus.h
new file mode 100644
index 0000000..391084d
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/smbus.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_SMBUS_H__
+#define __STONEYRIDGE_SMBUS_H__
+
+#include <stdint.h>
+#include <soc/iomap.h>
+
+#define SMB_SPEED_400KHZ		(66000000 / (400000 * 4))
+
+/*
+ * Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100 * 1000 * 10)
+
+int do_smbus_read_byte(u32 mmio, u8 device, u8 address);
+int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val);
+int do_smbus_recv_byte(u32 mmio, u8 device);
+int do_smbus_send_byte(u32 mmio, u8 device, u8 val);
+
+#endif /* __STONEYRIDGE_SMBUS_H__ */
diff --git a/src/soc/amd/picasso/include/soc/smi.h b/src/soc/amd/picasso/include/soc/smi.h
new file mode 100644
index 0000000..000eed8
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/smi.h
@@ -0,0 +1,242 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ *
+ * 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, 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.
+ */
+
+#ifndef __SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H__
+#define __SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H__
+
+
+#define SMI_GEVENTS			24
+#define SCIMAPS				58
+#define SCI_GPES			32
+
+#define SMI_EVENT_STATUS		0x0
+#define SMI_EVENT_ENABLE		0x04
+#define SMI_SCI_TRIG			0x08
+#define SMI_SCI_LEVEL			0x0c
+#define SMI_SCI_STATUS			0x10
+#define SMI_SCI_EN			0x14
+#define SMI_SCI_MAP0			0x40
+# define SMI_SCI_MAP(X)			(SMI_SCI_MAP0 + (X))
+
+/* SMI source and status */
+#define SMITYPE_AGPIO65				0
+#define SMITYPE_AGPIO66				1
+#define SMITYPE_AGPIO3				2
+#define SMITYPE_LPCPME_AGPIO22			3
+#define SMITYPE_GPIO4				4
+#define SMITYPE_LPCPD_AGPIOG21			5
+#define SMITYPE_IRTX1_G15			6
+#define SMITYPE_AGPIO5_DEVSLP0			7
+#define SMITYPE_WAKE_AGPIO2			8
+#define SMITYPE_APIO68_SGPIOCLK			9
+#define SMITYPE_AGPIO6				10
+#define SMITYPE_GPIO7				11
+#define SMITYPE_USBOC0_TRST_AGPIO16		12
+#define SMITYPE_USB0C1_TDI_AGPIO17		13
+#define SMITYPE_USBOC2_TCK_AGPIO18		14
+#define SMITYPE_TDO_USB0C3_AGPIO24		15
+#define SMITYPE_ACPRES_USBOC4_IRRX0_AGPIO23	16
+/* 17 Reserved */
+#define SMITYPE_BLINK_AGPIO11_USBOC7		18
+#define SMITYPE_SYSRESET_AGPIO1			19
+#define SMITYPE_IRRX1_AGPIO15			20
+#define SMITYPE_IRTX0_USBOC5_AGPIO13		21
+#define SMITYPE_GPIO9_SERPORTRX			22
+#define SMITYPE_GPIO8_SEPORTTX			23
+#define GEVENT_MASK ((1 << SMITYPE_AGPIO65)				\
+			| (1 << SMITYPE_AGPIO66)			\
+			| (1 << SMITYPE_AGPIO3)				\
+			| (1 << SMITYPE_LPCPME_AGPIO22)			\
+			| (1 << SMITYPE_GPIO4)				\
+			| (1 << SMITYPE_LPCPD_AGPIOG21)			\
+			| (1 << SMITYPE_IRTX1_G15)			\
+			| (1 << SMITYPE_AGPIO5_DEVSLP0)			\
+			| (1 << SMITYPE_WAKE_AGPIO2)			\
+			| (1 << SMITYPE_APIO68_SGPIOCLK)		\
+			| (1 << SMITYPE_AGPIO6)				\
+			| (1 << SMITYPE_GPIO7)				\
+			| (1 << SMITYPE_USBOC0_TRST_AGPIO16)		\
+			| (1 << SMITYPE_USB0C1_TDI_AGPIO17)		\
+			| (1 << SMITYPE_USBOC2_TCK_AGPIO18)		\
+			| (1 << SMITYPE_TDO_USB0C3_AGPIO24)		\
+			| (1 << SMITYPE_ACPRES_USBOC4_IRRX0_AGPIO23)	\
+			| (1 << SMITYPE_BLINK_AGPIO11_USBOC7)		\
+			| (1 << SMITYPE_SYSRESET_AGPIO1)		\
+			| (1 << SMITYPE_IRRX1_AGPIO15)			\
+			| (1 << SMITYPE_IRTX0_USBOC5_AGPIO13)		\
+			| (1 << SMITYPE_GPIO9_SERPORTRX))
+#define SMITYPE_EHCI0_WAKE			24
+#define SMITYPE_EHCI1_WAKE			25
+#define SMITYPE_ESPI_SYS			26
+#define SMITYPE_ESPI_WAKE_PME			27
+/* 28-32 Reserved */
+#define SMITYPE_FCH_FAKE0			33
+#define SMITYPE_FCH_FAKE1			34
+#define SMITYPE_FCH_FAKE2			35
+/* 36 Reserved */
+#define SMITYPE_SATA_GEVENT0			37
+#define SMITYPE_SATA_GEVENT1			38
+#define SMITYPE_ACP_WAKE			39
+#define SMITYPE_ECG				40
+#define SMITYPE_GPIO_CTL			41
+#define SMITYPE_CIR_PME				42
+#define SMITYPE_ALT_HPET_ALARM			43
+#define SMITYPE_FAN_THERMAL			44
+#define SMITYPE_ASF_MASTER_SLAVE		45
+#define SMITYPE_I2S_WAKE			46
+#define SMITYPE_SMBUS0_MASTER			47
+#define SMITYPE_TWARN				48
+#define SMITYPE_TRAFFIC_MON			49
+#define SMITYPE_ILLB				50
+#define SMITYPE_PWRBUTTON_UP			51
+#define SMITYPE_PROCHOT				52
+#define SMITYPE_APU_HW				53
+#define SMITYPE_NB_SCI				54
+#define SMITYPE_RAS_SERR			55
+#define SMITYPE_XHC0_PME			56
+/* 57 Reserved */
+#define SMITYPE_ACDC_TIMER			58
+/* 59-62 Reserved */
+#define SMITYPE_TEMP_TSI			63
+#define SMITYPE_KB_RESET			64
+#define SMITYPE_SLP_TYP				65
+#define SMITYPE_AL2H_ACPI			66
+#define SMITYPE_AHCI				67
+/* 68-71 Reserved */
+#define SMITYPE_GBL_RLS				72
+#define SMITYPE_BIOS_RLS			73
+#define SMITYPE_PWRBUTTON_DOWN			74
+#define SMITYPE_SMI_CMD_PORT			75
+#define SMITYPE_USB_SMI				76
+#define SMITYPE_SERIRQ				77
+#define SMITYPE_SMBUS0_INTR			78
+#define SMITYPE_XHC_ERROR			80
+#define SMITYPE_INTRUDER			81
+#define SMITYPE_VBAT_LOW			82
+#define SMITYPE_PROTHOT				83
+#define SMITYPE_PCI_SERR			84
+#define SMITYPE_GPP_SERR			85
+/* 85-88 Reserved */
+#define SMITYPE_TMERTRIP			89
+#define SMITYPE_EMUL60_64			90
+#define SMITYPE_USB_FLR				91
+#define SMITYPE_SATA_FLR			92
+#define SMITYPE_AZ_FLR				93
+/* 94-132 Reserved */
+#define SMITYPE_FANIN0				133
+/* 134-137 Reserved */
+#define SMITYPE_FAKE0				138
+#define SMITYPE_FAKE1				139
+#define SMITYPE_FAKE2				140
+/* 141 Reserved */
+#define SMITYPE_SHORT_TIMER			142
+#define SMITYPE_LONG_TIMER			143
+#define SMITYPE_AB_SMI				144
+#define SMITYPE_SOFT_RESET			145
+/* 146-147 Reserved */
+#define SMITYPE_IOTRAP0				148
+/* 149-151 Reserved */
+#define SMITYPE_MEMTRAP0			152
+/* 153-155 Reserved */
+#define SMITYPE_CFGTRAP0			156
+/* 157-159 Reserved */
+#define NUMBER_SMITYPES				160
+#define TYPE_TO_MASK(X)				(1 << (X) % 32)
+
+#define SMI_REG_SMISTS0			0x80
+#define SMI_REG_SMISTS1			0x84
+#define SMI_REG_SMISTS2			0x88
+#define SMI_REG_SMISTS3			0x8c
+#define SMI_REG_SMISTS4			0x90
+
+#define SMI_REG_POINTER			0x94
+# define SMI_STATUS_SRC_SCI			(1 << 0)
+# define SMI_STATUS_SRC_0			(1 << 1) /* SMIx80 */
+# define SMI_STATUS_SRC_1			(1 << 2) /* SMIx84... */
+# define SMI_STATUS_SRC_2			(1 << 3)
+# define SMI_STATUS_SRC_3			(1 << 4)
+# define SMI_STATUS_SRC_4			(1 << 5)
+
+#define SMI_TIMER			0x96
+#define SMI_TIMER_MASK				0x7fff
+#define SMI_TIMER_EN				(1 << 15)
+
+#define SMI_REG_SMITRIG0		0x98
+# define SMITRG0_EOS				(1 << 28)
+# define SMI_TIMER_SEL				(1 << 29)
+# define SMITRG0_SMIENB				(1 << 31)
+
+#define SMI_REG_CONTROL0		0xa0
+#define SMI_REG_CONTROL1		0xa4
+#define SMI_REG_CONTROL2		0xa8
+#define SMI_REG_CONTROL3		0xac
+#define SMI_REG_CONTROL4		0xb0
+#define SMI_REG_CONTROL5		0xb4
+#define SMI_REG_CONTROL6		0xb8
+#define SMI_REG_CONTROL7		0xbc
+#define SMI_REG_CONTROL8		0xc0
+#define SMI_REG_CONTROL9		0xc4
+
+enum smi_mode {
+	SMI_MODE_DISABLE = 0,
+	SMI_MODE_SMI = 1,
+	SMI_MODE_NMI = 2,
+	SMI_MODE_IRQ13 = 3,
+};
+
+enum smi_sci_type {
+	INTERRUPT_NONE,
+	INTERRUPT_SCI,
+	INTERRUPT_SMI,
+	INTERRUPT_BOTH,
+};
+
+enum smi_sci_lvl {
+	SMI_SCI_LVL_LOW,
+	SMI_SCI_LVL_HIGH,
+};
+
+enum smi_sci_dir {
+	SMI_SCI_EDG,
+	SMI_SCI_LVL,
+};
+
+struct smi_sources_t {
+	int type;
+	void (*handler)(void);
+};
+
+struct sci_source {
+	uint8_t scimap;		/* SCIMAP 0-57 */
+	uint8_t gpe;		/* 32 GPEs */
+	uint8_t direction;	/* Active High or Low,  smi_sci_lvl */
+	uint8_t level;		/* Edge or Level,  smi_sci_dir */
+};
+
+uint16_t pm_acpi_smi_cmd_port(void);
+void configure_smi(uint8_t smi_num, uint8_t mode);
+void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level);
+void configure_scimap(const struct sci_source *sci);
+void disable_gevent_smi(uint8_t gevent);
+void gpe_configure_sci(const struct sci_source *scis, size_t num_gpes);
+void soc_route_sci(uint8_t event);
+
+#ifndef __SMM__
+void enable_smi_generation(void);
+#endif
+
+#endif /* __SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H__ */
diff --git a/src/soc/amd/picasso/include/soc/southbridge.h b/src/soc/amd/picasso/include/soc/southbridge.h
new file mode 100644
index 0000000..ad40407
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/southbridge.h
@@ -0,0 +1,415 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010-2017 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC
+ *
+ * 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.
+ */
+
+#ifndef __STONEYRIDGE_H__
+#define __STONEYRIDGE_H__
+
+#include <types.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <soc/iomap.h>
+#include "chip.h"
+
+/*
+ * AcpiMmio Region
+ *  - fixed addresses offset from 0xfed80000
+ */
+
+/* Power management registers:  0xfed80300 or index/data at IO 0xcd6/cd7 */
+#define PM_DECODE_EN			0x00
+#define   CF9_IO_EN			BIT(1)
+#define   LEGACY_IO_EN			BIT(0)
+#define PM_ISA_CONTROL			0x04
+#define   MMIO_EN			BIT(1)
+#define PM_PCI_CTRL			0x08
+#define   FORCE_SLPSTATE_RETRY		BIT(25)
+#define   FORCE_STPCLK_RETRY		BIT(24)
+
+#define SMB_ASF_IO_BASE			0x01 /* part of PM_DECODE_EN */
+
+#define PWR_RESET_CFG			0x10
+#define   TOGGLE_ALL_PWR_GOOD		BIT(1)
+
+#define PM_SERIRQ_CONF			0x54
+#define   PM_SERIRQ_NUM_BITS_17		0x0000
+#define   PM_SERIRQ_NUM_BITS_18		0x0004
+#define   PM_SERIRQ_NUM_BITS_19		0x0008
+#define   PM_SERIRQ_NUM_BITS_20		0x000c
+#define   PM_SERIRQ_NUM_BITS_21		0x0010
+#define   PM_SERIRQ_NUM_BITS_22		0x0014
+#define   PM_SERIRQ_NUM_BITS_23		0x0018
+#define   PM_SERIRQ_NUM_BITS_24		0x001c
+#define   PM_SERIRQ_MODE		BIT(6)
+#define   PM_SERIRQ_ENABLE		BIT(7)
+
+#define PM_RTC_SHADOW			0x5b	/* state when power resumes */
+#define   PM_S5_AT_POWER_RECOVERY	0x04	/* S5 */
+#define   PM_RESTORE_S0_IF_PREV_S0	0x07	/* S0 if previously at S0 */
+
+#define PM_EVT_BLK			0x60
+#define   WAK_STS			BIT(15) /*AcpiPmEvtBlkx00 Pm1Status */
+#define   PCIEXPWAK_STS			BIT(14)
+#define   RTC_STS			BIT(10)
+#define   PWRBTN_STS			BIT(8)
+#define   GBL_STS			BIT(5)
+#define   BM_STS			BIT(4)
+#define   TIMER_STS			BIT(0)
+#define   PCIEXPWAK_DIS			BIT(14) /*AcpiPmEvtBlkx02 Pm1Enable */
+#define   RTC_EN			BIT(10)
+#define   PWRBTN_EN			BIT(8)
+#define   GBL_EN			BIT(5)
+#define   TIMER_STS			BIT(0)
+#define PM1_CNT_BLK			0x62
+#define PM_TMR_BLK			0x64
+#define PM_CPU_CTRL			0x66
+#define PM_GPE0_BLK			0x68
+#define PM_ACPI_SMI_CMD			0x6a
+#define PM_ACPI_CONF			0x74
+#define   PM_ACPI_DECODE_STD		BIT(0)
+#define   PM_ACPI_GLOBAL_EN		BIT(1)
+#define   PM_ACPI_RTC_EN_EN		BIT(2)
+#define   PM_ACPI_TIMER_EN_EN		BIT(4)
+#define   PM_ACPI_MASK_ARB_DIS		BIT(6)
+#define   PM_ACPI_BIOS_RLS		BIT(7)
+#define   PM_ACPI_PWRBTNEN_EN		BIT(8)
+#define   PM_ACPI_REDUCED_HW_EN		BIT(9)
+#define   PM_ACPI_BLOCK_PCIE_PME	BIT(24)
+#define   PM_ACPI_PCIE_WAK_MASK		BIT(25)
+#define   PM_ACPI_WAKE_AS_GEVENT	BIT(27)
+#define   PM_ACPI_NB_PME_GEVENT		BIT(28)
+#define   PM_ACPI_RTC_WAKE_EN		BIT(29)
+#define PM_RST_CTRL1			0xbe
+#define   SLPTYPE_CONTROL_EN		BIT(5)
+#define PM_RST_STATUS			0xc0
+#define PM_PCIB_CFG			0xea
+#define   PM_GENINT_DISABLE		BIT(0)
+#define PM_LPC_GATING			0xec
+#define   PM_LPC_AB_NO_BYPASS_EN	BIT(2)
+#define   PM_LPC_A20_EN			BIT(1)
+#define   PM_LPC_ENABLE			BIT(0)
+#define PM_USB_ENABLE			0xef
+#define   PM_USB_ALL_CONTROLLERS	0x7f
+
+/* SMBUS MMIO offsets 0xfed80a00 */
+#define SMBHSTSTAT			0x0
+#define   SMBHST_STAT_FAILED		0x10
+#define   SMBHST_STAT_COLLISION		0x08
+#define   SMBHST_STAT_ERROR		0x04
+#define   SMBHST_STAT_INTERRUPT		0x02
+#define   SMBHST_STAT_BUSY		0x01
+#define   SMBHST_STAT_CLEAR		0xff
+#define   SMBHST_STAT_NOERROR		0x02
+#define   SMBHST_STAT_VAL_BITS		0x1f
+#define   SMBHST_STAT_ERROR_BITS	0x1c
+
+#define SMBSLVSTAT			0x1
+#define   SMBSLV_STAT_ALERT		0x20
+#define   SMBSLV_STAT_SHADOW2		0x10
+#define   SMBSLV_STAT_SHADOW1		0x08
+#define   SMBSLV_STAT_SLV_STS		0x04
+#define   SMBSLV_STAT_SLV_INIT		0x02
+#define   SMBSLV_STAT_SLV_BUSY		0x01
+#define   SMBSLV_STAT_CLEAR		0x1f
+
+#define SMBHSTCTRL			0x2
+#define   SMBHST_CTRL_RST		0x80
+#define   SMBHST_CTRL_STRT		0x40
+#define   SMBHST_CTRL_QCK_RW		0x00
+#define   SMBHST_CTRL_BTE_RW		0x04
+#define   SMBHST_CTRL_BDT_RW		0x08
+#define   SMBHST_CTRL_WDT_RW		0x0c
+#define   SMBHST_CTRL_BLK_RW		0x14
+#define   SMBHST_CTRL_MODE_BITS		0x1c
+#define   SMBHST_CTRL_KILL		0x02
+#define   SMBHST_CTRL_IEN		0x01
+
+#define SMBHSTCMD			0x3
+#define SMBHSTADDR			0x4
+#define SMBHSTDAT0			0x5
+#define SMBHSTDAT1			0x6
+#define SMBHSTBLKDAT			0x7
+#define SMBSLVCTRL			0x8
+#define SMBSLVCMD_SHADOW		0x9
+#define SMBSLVEVT			0xa
+#define SMBSLVDAT			0xc
+#define SMBTIMING			0xe
+
+/* FCH MISC Registers 0xfed80e00 */
+#define GPP_CLK_CNTRL			0x00
+#define   GPP_CLK2_REQ_MAP_SHIFT	8
+#define   GPP_CLK2_REQ_MAP_MASK		(0xf << GPP_CLK2_REQ_MAP_SHIFT)
+#define   GPP_CLK2_REQ_MAP_CLK_REQ2	3
+#define   GPP_CLK0_REQ_MAP_SHIFT	0
+#define   GPP_CLK0_REQ_MAP_MASK		(0xf << GPP_CLK0_REQ_MAP_SHIFT)
+#define   GPP_CLK0_REQ_MAP_CLK_REQ0	1
+#define MISC_CGPLL_CONFIG1		0x08
+#define   CG1PLL_SPREAD_SPECTRUM_ENABLE	BIT(0)
+#define MISC_CGPLL_CONFIG3		0x10
+#define   CG1PLL_REFDIV_SHIFT		0
+#define   CG1PLL_REFDIV_MASK		(0x3ff << CG1PLL_REFDIV_SHIFT)
+#define   CG1PLL_FBDIV_SHIFT		10
+#define   CG1PLL_FBDIV_MASK		(0xfff << CG1PLL_FBDIV_SHIFT)
+#define MISC_CGPLL_CONFIG4		0x14
+#define   SS_STEP_SIZE_DSFRAC_SHIFT	0
+#define   SS_STEP_SIZE_DSFRAC_MASK	(0xffff << SS_STEP_SIZE_DSFRAC_SHIFT)
+#define   SS_AMOUNT_DSFRAC_SHIFT	16
+#define   SS_AMOUNT_DSFRAC_MASK		(0xffff << SS_AMOUNT_DSFRAC_SHIFT)
+#define MISC_CGPLL_CONFIG5		0x18
+#define   SS_AMOUNT_NFRAC_SLIP_SHIFT	8
+#define   SS_AMOUNT_NFRAC_SLIP_MASK	(0xf << SS_AMOUNT_NFRAC_SLIP_SHIFT)
+#define MISC_CGPLL_CONFIG6		0x1c
+#define   CG1PLL_LF_MODE_SHIFT		9
+#define   CG1PLL_LF_MODE_MASK		(0x1ff << CG1PLL_LF_MODE_SHIFT)
+#define MISC_CLK_CNTL1			0x40
+#define   CG1PLL_FBDIV_TEST		BIT(26)
+#define   OSCOUT1_CLK_OUTPUT_ENB	BIT(2)  /* 0 = Enabled, 1 = Disabled */
+#define   OSCOUT2_CLK_OUTPUT_ENB	BIT(7)  /* 0 = Enabled, 1 = Disabled */
+
+/* XHCI_PM Registers:  0xfed81c00 */
+#define XHCI_PM_INDIRECT_INDEX		0x48
+#define XHCI_PM_INDIRECT_DATA		0x4c
+#define   XHCI_OVER_CURRENT_CONTROL	0x30
+#define     USB_OC0			0
+#define     USB_OC1			1
+#define     USB_OC2			2
+#define     USB_OC3			3
+#define     USB_OC4			4
+#define     USB_OC5			5
+#define     USB_OC6			6
+#define     USB_OC7			7
+#define     USB_OC_DISABLE		0xf
+#define     USB_OC_DISABLE_ALL		0xffff
+#define     OC_PORT0_SHIFT		0
+#define     OC_PORT1_SHIFT		4
+#define     OC_PORT2_SHIFT		8
+#define     OC_PORT3_SHIFT		12
+
+#define EHCI_OVER_CURRENT_CONTROL	0x70
+#define EHCI_HUB_CONFIG4		0x90
+#define   DEBUG_PORT_SELECT_SHIFT	  16
+#define   DEBUG_PORT_ENABLE		  BIT(18)
+#define   DEBUG_PORT_MASK		(BIT(16) | BIT(17) | BIT(18))
+
+/* FCH AOAC Registers 0xfed81e00 */
+#define FCH_AOAC_D3_CONTROL_CLK_GEN	0x40
+#define FCH_AOAC_D3_CONTROL_I2C0	0x4a
+#define FCH_AOAC_D3_CONTROL_I2C1	0x4c
+#define FCH_AOAC_D3_CONTROL_I2C2	0x4e
+#define FCH_AOAC_D3_CONTROL_I2C3	0x50
+#define FCH_AOAC_D3_CONTROL_UART0	0x56
+#define FCH_AOAC_D3_CONTROL_UART1	0x58
+#define FCH_AOAC_D3_CONTROL_AMBA	0x62
+#define FCH_AOAC_D3_CONTROL_USB2	0x64
+#define FCH_AOAC_D3_CONTROL_USB3	0x6e
+/* Bit definitions for all FCH_AOAC_D3_CONTROL_* Registers */
+#define   FCH_AOAC_TARGET_DEVICE_STATE (BIT(0) + BIT(1))
+#define   FCH_AOAC_DEVICE_STATE		BIT(2)
+#define   FCH_AOAC_PWR_ON_DEV		BIT(3)
+#define   FCH_AOAC_SW_PWR_ON_RSTB	BIT(4)
+#define   FCH_AOAC_SW_REF_CLK_OK	BIT(5)
+#define   FCH_AOAC_SW_RST_B		BIT(6)
+#define   FCH_AOAC_IS_SW_CONTROL	BIT(7)
+
+#define FCH_AOAC_D3_STATE_CLK_GEN	0x41
+#define FCH_AOAC_D3_STATE_I2C0		0x4b
+#define FCH_AOAC_D3_STATE_I2C1		0x4d
+#define FCH_AOAC_D3_STATE_I2C2		0x4f
+#define FCH_AOAC_D3_STATE_I2C3		0x51
+#define FCH_AOAC_D3_STATE_UART0		0x57
+#define FCH_AOAC_D3_STATE_UART1		0x59
+#define FCH_AOAC_D3_STATE_AMBA		0x63
+#define FCH_AOAC_D3_STATE_USB2		0x65
+#define FCH_AOAC_D3_STATE_USB3		0x6f
+/* Bit definitions for all FCH_AOAC_D3_STATE_* Registers */
+#define   FCH_AOAC_PWR_RST_STATE	BIT(0)
+#define   FCH_AOAC_RST_CLK_OK_STATE	BIT(1)
+#define   FCH_AOAC_RST_B_STATE		BIT(2)
+#define   FCH_AOAC_DEV_OFF_GATING_STATE	BIT(3)
+#define   FCH_AOAC_D3COLD		BIT(4)
+#define   FCH_AOAC_CLK_OK_STATE		BIT(5)
+#define   FCH_AOAC_STAT0		BIT(6)
+#define   FCH_AOAC_STAT1		BIT(7)
+
+#define PM1_LIMIT			16
+#define GPE0_LIMIT			28
+#define TOTAL_BITS(a)			(8 * sizeof(a))
+
+/* SATA Controller D11F0 */
+#define SATA_MISC_CONTROL_REG		0x40
+#define SATA_MISC_SUBCLASS_WREN		BIT(0)
+/* Register in AHCIBaseAddress (BAR5 at D11F0x24) */
+#define SATA_CAPABILITIES_REG		0xfc
+#define SATA_CAPABILITY_SPM		BIT(12)
+
+/* SPI Controller (base address in D14F3xA0) */
+#define SPI_BASE_ALIGNMENT		BIT(6)
+
+#define SPI_CNTRL0			0x00
+#define   SPI_BUSY			BIT(31)
+#define   SPI_READ_MODE_MASK		(BIT(30) | BIT(29) | BIT(18))
+/* Nominal is 16.7MHz on older devices, 33MHz on newer */
+#define   SPI_READ_MODE_NOM		0x00000000
+#define   SPI_READ_MODE_DUAL112		(          BIT(29)          )
+#define   SPI_READ_MODE_QUAD114		(          BIT(29) | BIT(18))
+#define   SPI_READ_MODE_DUAL122		(BIT(30)                    )
+#define   SPI_READ_MODE_QUAD144		(BIT(30) |           BIT(18))
+#define   SPI_READ_MODE_NORMAL66	(BIT(30) | BIT(29)          )
+#define   SPI_READ_MODE_FAST		(BIT(30) | BIT(29) | BIT(18))
+#define   SPI_FIFO_PTR_CLR		BIT(20)
+#define   SPI_ARB_ENABLE		BIT(19)
+#define   EXEC_OPCODE			BIT(16)
+#define SPI_CNTRL1			0x0c
+#define SPI_CMD_CODE			0x45
+#define SPI_CMD_TRIGGER			0x47
+#define   SPI_CMD_TRIGGER_EXECUTE	BIT(7)
+#define SPI_TX_BYTE_COUNT		0x48
+#define SPI_RX_BYTE_COUNT		0x4b
+#define SPI_STATUS			0x4c
+#define   SPI_DONE_BYTE_COUNT_SHIFT	0
+#define   SPI_DONE_BYTE_COUNT_MASK	0xff
+#define   SPI_FIFO_WR_PTR_SHIFT		8
+#define   SPI_FIFO_WR_PTR_MASK		0x7f
+#define   SPI_FIFO_RD_PTR_SHIFT		16
+#define   SPI_FIFO_RD_PTR_MASK		0x7f
+#define SPI_FIFO			0x80
+#define   SPI_FIFO_DEPTH		(0xc7 - SPI_FIFO)
+
+#define SPI100_ENABLE			0x20
+#define   SPI_USE_SPI100		BIT(0)
+
+/* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */
+#define SPI100_SPEED_CONFIG		0x22
+#define   SPI_SPEED_66M			(0x0)
+#define   SPI_SPEED_33M			(                  BIT(0))
+#define   SPI_SPEED_22M			(         BIT(1)         )
+#define   SPI_SPEED_16M			(         BIT(1) | BIT(0))
+#define   SPI_SPEED_100M		(BIT(2)                  )
+#define   SPI_SPEED_800K		(BIT(2) |          BIT(0))
+#define   SPI_NORM_SPEED_NEW_SH		12
+#define   SPI_FAST_SPEED_NEW_SH		8
+#define   SPI_ALT_SPEED_NEW_SH		4
+#define   SPI_TPM_SPEED_NEW_SH		0
+
+#define SPI100_HOST_PREF_CONFIG		0x2c
+#define   SPI_RD4DW_EN_HOST		BIT(15)
+
+/* Platform Security Processor D8F0 */
+#define PSP_MAILBOX_BAR			PCI_BASE_ADDRESS_4 /* BKDG: "BAR3" */
+#define PSP_BAR_ENABLES			0x48
+#define  PSP_MAILBOX_BAR_EN		0x10
+
+/* IO 0xcf9 - Reset control port*/
+#define   FULL_RST			BIT(3)
+#define   RST_CMD			BIT(2)
+#define   SYS_RST			BIT(1)
+
+struct stoneyridge_aoac {
+	int enable;
+	int status;
+};
+
+typedef struct aoac_devs {
+	unsigned int :5;
+	unsigned int ic0e:1; /* 5: I2C0 */
+	unsigned int ic1e:1; /* 6: I2C1 */
+	unsigned int ic2e:1; /* 7: I2C2 */
+	unsigned int ic3e:1; /* 8: I2C3 */
+	unsigned int :2;
+	unsigned int ut0e:1; /* 11: UART0 */
+	unsigned int ut1e:1; /* 12: UART1 */
+	unsigned int :2;
+	unsigned int st_e:1; /* 15: SATA */
+	unsigned int :2;
+	unsigned int ehce:1; /* 18: EHCI */
+	unsigned int :4;
+	unsigned int xhce:1; /* 23: xHCI */
+	unsigned int sd_e:1; /* 24: SDIO */
+	unsigned int :2;
+	unsigned int espi:1; /* 27: ESPI */
+	unsigned int :4;
+} __packed aoac_devs_t;
+
+struct soc_power_reg {
+	uint16_t pm1_sts;
+	uint16_t pm1_en;
+	uint32_t gpe0_sts;
+	uint32_t gpe0_en;
+	uint16_t wake_from;
+};
+
+#define XHCI_FW_SIG_OFFSET			0xc
+#define XHCI_FW_ADDR_OFFSET			0x6
+#define XHCI_FW_SIZE_OFFSET			0x8
+#define XHCI_FW_BOOTRAM_SIZE			0x8000
+
+void enable_aoac_devices(void);
+void sb_clk_output_48Mhz(u32 osc);
+void sb_disable_4dw_burst(void);
+void sb_enable(struct device *dev);
+void southbridge_final(void *chip_info);
+void southbridge_init(void *chip_info);
+void sb_read_mode(u32 mode);
+void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm);
+void bootblock_fch_early_init(void);
+void bootblock_fch_init(void);
+/**
+ * @brief Save the UMA bize returned by AGESA
+ *
+ * @param size = in bytes
+ *
+ * @return none
+ */
+void save_uma_size(uint32_t size);
+/**
+ * @brief Save the UMA base address returned by AGESA
+ *
+ * @param base = 64bit base address
+ *
+ * @return none
+ */
+void save_uma_base(uint64_t base);
+/**
+ * @brief Get the saved UMA size
+ *
+ * @param none
+ *
+ * @return size in bytes
+ */
+uint32_t get_uma_size(void);
+/**
+ * @brief Get the saved UMA base
+ *
+ * @param none
+ *
+ * @return 64bit base address
+ */
+uint64_t get_uma_base(void);
+/*
+ * Call the mainboard to get the USB Over Current Map. The mainboard
+ * returns the map and 0 on Success or -1 on error or no map. There is
+ * a default weak function in usb.c if the mainboard doesn't have any
+ * over current support.
+ */
+int mainboard_get_xhci_oc_map(uint16_t *usb_oc_map);
+int mainboard_get_ehci_oc_map(uint16_t *usb_oc_map);
+
+/* Initialize all the i2c buses that are marked with early init. */
+void i2c_soc_early_init(void);
+
+/* Initialize all the i2c buses that are not marked with early init. */
+void i2c_soc_init(void);
+
+#endif /* __STONEYRIDGE_H__ */
diff --git a/src/soc/amd/picasso/makefile.inc b/src/soc/amd/picasso/makefile.inc
new file mode 100644
index 0000000..babd878
--- /dev/null
+++ b/src/soc/amd/picasso/makefile.inc
@@ -0,0 +1,316 @@
+#*****************************************************************************
+#
+# Copyright (c) 2012, 2016-2017 Advanced Micro Devices, Inc.
+#               2013 - 2014 Sage Electronic Engineering, LLC
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Advanced Micro Devices, Inc. nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#*****************************************************************************
+ifeq ($(CONFIG_SOC_AMD_STONEYRIDGE_FP4)$(CONFIG_SOC_AMD_STONEYRIDGE_FT4),y)
+
+subdirs-y += ../../../cpu/amd/mtrr/
+subdirs-y += ../../../cpu/x86/tsc
+subdirs-y += ../../../cpu/x86/lapic
+subdirs-y += ../../../cpu/x86/cache
+subdirs-y += ../../../cpu/x86/mtrr
+subdirs-y += ../../../cpu/x86/pae
+subdirs-y += ../../../cpu/x86/smm
+
+bootblock-$(CONFIG_STONEYRIDGE_UART) += uart.c
+bootblock-y += BiosCallOuts.c
+bootblock-y += bootblock/bootblock.c
+bootblock-y += gpio.c
+bootblock-y += i2c.c
+bootblock-$(CONFIG_USBDEBUG) += enable_usbdebug.c
+bootblock-y += monotonic_timer.c
+bootblock-y += pmutil.c
+bootblock-y += reset.c
+bootblock-y += tsc_freq.c
+bootblock-y += southbridge.c
+bootblock-y += nb_util.c
+bootblock-$(CONFIG_SPI_FLASH) += spi.c
+bootblock-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
+
+romstage-y += BiosCallOuts.c
+romstage-y += i2c.c
+romstage-y += romstage.c
+romstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
+romstage-y += gpio.c
+romstage-y += monotonic_timer.c
+romstage-y += pmutil.c
+romstage-y += reset.c
+romstage-y += smbus.c
+romstage-y += smbus_spd.c
+romstage-y += ramtop.c
+romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
+romstage-y += tsc_freq.c
+romstage-y += southbridge.c
+romstage-y += nb_util.c
+romstage-$(CONFIG_SPI_FLASH) += spi.c
+romstage-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
+
+verstage-y += gpio.c
+verstage-y += i2c.c
+verstage-y += monotonic_timer.c
+verstage-y += pmutil.c
+verstage-y += reset.c
+verstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
+verstage-y += tsc_freq.c
+verstage-y += nb_util.c
+verstage-$(CONFIG_SPI_FLASH) += spi.c
+
+postcar-y += monotonic_timer.c
+postcar-$(CONFIG_STONEYRIDGE_UART) += uart.c
+postcar-y += ramtop.c
+postcar-y += nb_util.c
+postcar-$(CONFIG_VBOOT_MEASURED_BOOT) += i2c.c
+postcar-y += tsc_freq.c
+
+ramstage-y += BiosCallOuts.c
+ramstage-y += i2c.c
+ramstage-y += chip.c
+ramstage-y += cpu.c
+ramstage-y += mca.c
+ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
+ramstage-y += gpio.c
+ramstage-y += monotonic_timer.c
+ramstage-y += southbridge.c
+ramstage-y += northbridge.c
+ramstage-y += pmutil.c
+ramstage-y += reset.c
+ramstage-y += sata.c
+ramstage-y += sm.c
+ramstage-y += smbus.c
+ramstage-y += ramtop.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.c
+ramstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
+ramstage-y += usb.c
+ramstage-y += tsc_freq.c
+ramstage-$(CONFIG_SPI_FLASH) += spi.c
+ramstage-y += finalize.c
+ramstage-y += nb_util.c
+
+smm-y += monotonic_timer.c
+smm-y += smihandler.c
+smm-y += smi_util.c
+smm-y += tsc_freq.c
+smm-$(CONFIG_DEBUG_SMI) += uart.c
+smm-$(CONFIG_SPI_FLASH) += spi.c
+smm-y += nb_util.c
+smm-y += gpio.c
+
+CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge
+CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/include
+CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/acpi
+
+# ROMSIG Normally At ROMBASE + 0x20000
+# Overridden by CONFIG_AMD_FWM_POSITION_INDEX
+# +-----------+---------------+----------------+------------+
+# |0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM    |
+# +-----------+---------------+----------------+------------+
+# |PSPDIR ADDR|
+# +-----------+
+#
+# EC ROM should be 64K aligned.
+STONEYRIDGE_FWM_POSITION=$(call int-add, \
+	$(call int-subtract, 0xffffffff \
+	$(call int-shift-left, \
+	0x80000 $(CONFIG_AMD_FWM_POSITION_INDEX))) 0x20000 1)
+
+### 0
+FIRMWARE_LOCATE=$(dir $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)))
+FIRMWARE_TYPE=ST
+
+###5
+PUBSIGNEDKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/RtmPubSigned$(FIRMWARE_TYPE).key
+
+###1
+PSPBTLDR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspBootLoader_prod_$(FIRMWARE_TYPE).sbin
+
+###3
+PSPRCVR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspRecoveryBootLoader_prod_$(FIRMWARE_TYPE).sbin
+
+###4
+PSPNVRAM_FILE=$(top)/$(FIRMWARE_LOCATE)/PspNvram$(FIRMWARE_TYPE).bin
+
+###8 - Check for SMU firmware named either *.sbin or *.csbin
+###    TODO: Remove *.sbin section after the blobs repo is updated.
+SMUFWM_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware_$(FIRMWARE_TYPE).csbin
+SMUFWM_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware_$(FIRMWARE_TYPE)_FN.csbin
+ifeq ("$(wildcard $(SMUFWM_FILE))","")
+SMUFWM_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE).sbin
+SMUFWM_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE)_FN.sbin
+endif
+
+###95
+SMUSCS_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuScs$(FIRMWARE_TYPE).bin
+
+###9
+PSPSECUREDEBUG_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureDebug$(FIRMWARE_TYPE).Key
+
+ifeq ($(CONFIG_USE_PSPSECUREOS),y)
+###2
+PSPSCUREOS_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureOs_prod_$(FIRMWARE_TYPE).csbin
+
+###12
+PSPTRUSTLETS_FILE=$(wildcard $(top)/$(FIRMWARE_LOCATE)/PspTrustlets*_prod_$(FIRMWARE_TYPE).cbin)
+
+###13
+TRUSTLETKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/TrustletKey_prod_$(FIRMWARE_TYPE).sbin
+endif
+
+###18- Check for SMU firmware2 named either *.sbin or *.csbin
+###    TODO: Remove *.sbin section after the blobs repo is updated.
+SMUFIRMWARE2_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE).csbin
+SMUFIRMWARE2_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE)_FN.csbin
+ifeq ("$(wildcard $(SMUFIRMWARE2_FILE))","")
+SMUFIRMWARE2_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE).sbin
+SMUFIRMWARE2_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE)_FN.sbin
+endif
+
+add_opt_prefix=$(if $(call strip_quotes, $(1)), $(2) $(call strip_quotes, $(1)), )
+
+OPT_STONEYRIDGE_XHCI_FWM_FILE=$(call add_opt_prefix, $(CONFIG_STONEYRIDGE_XHCI_FWM_FILE), --xhci)
+OPT_STONEYRIDGE_GEC_FWM_FILE=$(call add_opt_prefix, $(CONFIG_STONEYRIDGE_GEC_FWM_FILEddd), --gec)
+
+OPT_AMD_PUBKEY_FILE=$(call add_opt_prefix, $(CONFIG_AMD_PUBKEY_FILE), --pubkey)
+OPT_PSPBTLDR_FILE=$(call add_opt_prefix, $(PSPBTLDR_FILE), --bootloader)
+OPT_SMUFWM_FILE=$(call add_opt_prefix, $(SMUFWM_FILE), --smufirmware)
+OPT_PSPRCVR_FILE=$(call add_opt_prefix, $(PSPRCVR_FILE), --recovery)
+OPT_PUBSIGNEDKEY_FILE=$(call add_opt_prefix, $(PUBSIGNEDKEY_FILE), --rtmpubkey)
+OPT_PSPNVRAM_FILE=$(call add_opt_prefix, $(PSPNVRAM_FILE), --nvram)
+OPT_PSPSECUREDEBUG_FILE=$(call add_opt_prefix, $(PSPSECUREDEBUG_FILE), --securedebug)
+ifeq ($(CONFIG_USE_PSPSECUREOS),y)
+OPT_PSPSCUREOS_FILE=$(call add_opt_prefix, $(PSPSCUREOS_FILE), --secureos)
+OPT_PSPTRUSTLETS_FILE=$(call add_opt_prefix, $(PSPTRUSTLETS_FILE), --trustlets)
+OPT_TRUSTLETKEY_FILE=$(call add_opt_prefix, $(TRUSTLETKEY_FILE), --trustletkey)
+endif
+OPT_SMUFIRMWARE2_FILE=$(call add_opt_prefix, $(SMUFIRMWARE2_FILE), --smufirmware2)
+OPT_SMUSCS_FILE=$(call add_opt_prefix, $(SMUSCS_FILE), --smuscs)
+SUBPROG_FN_SMU_FW=1
+OPT_SMUFWM_FN_FILE=$(call add_opt_prefix, $(SMUFWM_FN_FILE), --subprogram $(SUBPROG_FN_SMU_FW) --smufirmware)
+OPT_SMUFIRMWARE2_FN_FILE=$(call add_opt_prefix, $(SMUFIRMWARE2_FN_FILE), --subprogram $(SUBPROG_FN_SMU_FW) --smufirmware2)
+
+
+$(obj)/amdfw.rom:	$(call strip_quotes, $(CONFIG_STONEYRIDGE_XHCI_FWM_FILE)) \
+			$(call strip_quotes, $(CONFIG_STONEYRIDGE_GEC_FWM_FILE)) \
+			$(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)) \
+			$(call strip_quotes, $(PUBSIGNEDKEY_FILE)) \
+			$(call strip_quotes, $(PSPBTLDR_FILE)) \
+			$(call strip_quotes, $(PSPRCVR_FILE)) \
+			$(call strip_quotes, $(PSPSCUREOS_FILE)) \
+			$(call strip_quotes, $(PSPNVRAM_FILE)) \
+			$(call strip_quotes, $(SMUFWM_FILE)) \
+			$(call strip_quotes, $(SMUFWM_FN_FILE)) \
+			$(call strip_quotes, $(SMUSCS_FILE)) \
+			$(call strip_quotes, $(PSPSECUREDEBUG_FILE)) \
+			$(call strip_quotes, $(PSPTRUSTLETS_FILE)) \
+			$(call strip_quotes, $(TRUSTLETKEY_FILE)) \
+			$(call strip_quotes, $(SMUFIRMWARE2_FILE)) \
+			$(call strip_quotes, $(SMUFIRMWARE2_FN_FILE)) \
+			$(AMDFWTOOL)
+	rm -f $@
+	@printf "    AMDFWTOOL  $(subst $(obj)/,,$(@))\n"
+	$(AMDFWTOOL) \
+		$(OPT_STONEYRIDGE_XHCI_FWM_FILE) \
+		$(OPT_STONEYRIDGE_GEC_FWM_FILE) \
+		$(OPT_AMD_PUBKEY_FILE) \
+		$(OPT_PSPBTLDR_FILE) \
+		$(OPT_SMUFWM_FILE) \
+		$(OPT_PSPRCVR_FILE) \
+		$(OPT_PUBSIGNEDKEY_FILE) \
+		$(OPT_PSPSCUREOS_FILE) \
+		$(OPT_PSPNVRAM_FILE) \
+		$(OPT_PSPSECUREDEBUG_FILE) \
+		$(OPT_PSPTRUSTLETS_FILE) \
+		$(OPT_TRUSTLETKEY_FILE) \
+		$(OPT_SMUFIRMWARE2_FILE) \
+		$(OPT_SMUSCS_FILE) \
+		$(OPT_AMD_PUBKEY_FILE) \
+		$(OPT_PSPBTLDR_FILE) \
+		$(OPT_SMUFWM_FILE) \
+		$(OPT_SMUFWM_FN_FILE) \
+		$(OPT_PSPRCVR_FILE) \
+		$(OPT_PUBSIGNEDKEY_FILE) \
+		$(OPT_PSPSCUREOS_FILE) \
+		$(OPT_PSPNVRAM_FILE) \
+		$(OPT_PSPSECUREDEBUG_FILE) \
+		$(OPT_PSPTRUSTLETS_FILE) \
+		$(OPT_TRUSTLETKEY_FILE) \
+		$(OPT_SMUFIRMWARE2_FILE) \
+		$(OPT_SMUFIRMWARE2_FN_FILE) \
+		$(OPT_SMUSCS_FILE) \
+		--combo-capable \
+		--flashsize $(CONFIG_ROM_SIZE) \
+		--location $(shell printf "0x%x" $(STONEYRIDGE_FWM_POSITION)) \
+		--output	$@
+
+ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
+PHONY+=add_amdfw
+INTERMEDIATE+=add_amdfw
+
+# Calculate firmware position inside the ROM
+STONEYRIDGE_FWM_ROM_POSITION=$(call int-add, \
+	$(call int-subtract, $(CONFIG_ROM_SIZE) \
+	$(call int-shift-left, \
+	0x80000 $(CONFIG_AMD_FWM_POSITION_INDEX))) 0x20000)
+
+add_amdfw: $(obj)/coreboot.pre $(obj)/amdfw.rom
+	printf "    DD         Adding AMD Firmware at ROM offset 0x%x\n" \
+		"$(STONEYRIDGE_FWM_ROM_POSITION)"
+	dd if=$(obj)/amdfw.rom \
+		of=$(obj)/coreboot.pre conv=notrunc bs=1 \
+		seek=$(STONEYRIDGE_FWM_ROM_POSITION) >/dev/null 2>&1
+
+else # ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
+
+cbfs-files-y += apu/amdfw
+apu/amdfw-file := $(obj)/amdfw.rom
+apu/amdfw-position := $(STONEYRIDGE_FWM_POSITION)
+apu/amdfw-type := raw
+
+endif # ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
+
+ifeq ($(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW),y)
+
+cbfs-files-y += smu_fw
+cbfs-files-y += smu_fw2
+smu_fw-type := raw
+smu_fw2-type := raw
+
+ifeq ($(CONFIG_SOC_AMD_SMU_FANLESS),y)
+smu_fw-file := $(SMUFWM_FN_FILE)
+smu_fw2-file := $(SMUFIRMWARE2_FN_FILE)
+else ifeq ($(CONFIG_SOC_AMD_SMU_FANNED),y)
+smu_fw-file := $(SMUFWM_FILE)
+smu_fw2-file := $(SMUFIRMWARE2_FILE)
+else
+$(error "Proper SMU Firmware not selected")
+endif
+
+endif # ifeq ($(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW),y)
+
+endif # ($(CONFIG_SOC_AMD_STONEYRIDGE_FP4)$(CONFIG_SOC_AMD_STONEYRIDGE_FT4),y)
diff --git a/src/soc/amd/picasso/mca.c b/src/soc/amd/picasso/mca.c
new file mode 100644
index 0000000..8a875d9
--- /dev/null
+++ b/src/soc/amd/picasso/mca.c
@@ -0,0 +1,214 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <cpu/x86/msr.h>
+#include <arch/acpi.h>
+#include <soc/cpu.h>
+#include <soc/northbridge.h>
+#include <console/console.h>
+#include <arch/bert_storage.h>
+#include <cper.h>
+
+struct mca_bank {
+	int bank;
+	msr_t ctl;
+	msr_t sts;
+	msr_t addr;
+	msr_t misc;
+	msr_t cmask;
+};
+
+static inline size_t mca_report_size_reqd(void)
+{
+	size_t size;
+
+	size = sizeof(acpi_generic_error_status_t);
+
+	size += sizeof(acpi_hest_generic_data_v300_t);
+	size += sizeof(cper_proc_generic_error_section_t);
+
+	size += sizeof(acpi_hest_generic_data_v300_t);
+	size += sizeof(cper_ia32x64_proc_error_section_t);
+
+	/* Check Error */
+	size += cper_ia32x64_check_sz();
+
+	/* Context of MCG_CAP, MCG_STAT, MCG_CTL */
+	size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 3);
+
+	/* Context of MCi_CTL, MCi_STATUS, MCi_ADDR, MCi_MISC */
+	size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 4);
+
+	/* Context of CTL_MASK */
+	size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 1);
+
+	return size;
+}
+
+static enum cper_x86_check_type error_to_chktype(struct mca_bank *mci)
+{
+	int error = mca_err_type(mci->sts);
+
+	if (error == MCA_ERRTYPE_BUS)
+		return X86_PROCESSOR_BUS_CHK;
+	if (error == MCA_ERRTYPE_INT)
+		return X86_PROCESSOR_MS_CHK;
+	if (error == MCA_ERRTYPE_MEM)
+		return X86_PROCESSOR_CACHE_CHK;
+	if (error == MCA_ERRTYPE_TLB)
+		return X86_PROCESSOR_TLB_CHK;
+
+	return X86_PROCESSOR_MS_CHK; /* unrecognized */
+}
+
+/* Fill additional information in the Generic Processor Error Section. */
+static void fill_generic_section(cper_proc_generic_error_section_t *sec,
+		struct mca_bank *mci)
+{
+	int type = mca_err_type(mci->sts);
+
+	if (type == MCA_ERRTYPE_BUS) /* try to map MCA errors to CPER types */
+		sec->error_type = GENPROC_ERRTYPE_BUS;
+	else if (type == MCA_ERRTYPE_INT)
+		sec->error_type = GENPROC_ERRTYPE_UARCH;
+	else if (type == MCA_ERRTYPE_MEM)
+		sec->error_type = GENPROC_ERRTYPE_CACHE;
+	else if (type == MCA_ERRTYPE_TLB)
+		sec->error_type = GENPROC_ERRTYPE_TLB;
+	else
+		sec->error_type = GENPROC_ERRTYPE_UNKNOWN;
+	sec->validation |= GENPROC_VALID_PROC_ERR_TYPE;
+}
+
+/* Convert an error reported by an MCA bank into BERT information to be reported
+ * by the OS.  The ACPI driver doesn't recognize/parse the IA32/X64 structure,
+ * which is the best method to report MSR context.  As a result, add two
+ * structures:  A "processor generic error" that is parsed, and an IA32/X64 one
+ * to capture complete information.
+ *
+ * Future work may attempt to interpret the specific Family 15h error symptoms
+ * found in the MCA registers.  This data could enhance the reporting of the
+ * Processor Generic section and the failing error/check added to the
+ * IA32/X64 section.
+ */
+static void build_bert_mca_error(struct mca_bank *mci)
+{
+	acpi_generic_error_status_t *status;
+	acpi_hest_generic_data_v300_t *gen_entry;
+	acpi_hest_generic_data_v300_t *x86_entry;
+	cper_proc_generic_error_section_t *gen_sec;
+	cper_ia32x64_proc_error_section_t *x86_sec;
+	cper_ia32x64_proc_error_info_t *chk;
+	cper_ia32x64_context_t *ctx;
+
+	if (mca_report_size_reqd() > bert_storage_remaining())
+		goto failed;
+
+	status = bert_new_event(&CPER_SEC_PROC_GENERIC_GUID);
+	if (!status)
+		goto failed;
+
+	gen_entry = acpi_hest_generic_data3(status);
+	gen_sec = section_of_acpientry(gen_sec, gen_entry);
+
+	fill_generic_section(gen_sec, mci);
+
+	x86_entry = bert_append_ia32x64(status);
+	x86_sec = section_of_acpientry(x86_sec, x86_entry);
+
+	chk = new_cper_ia32x64_check(status, x86_sec, error_to_chktype(mci));
+	if (!chk)
+		goto failed;
+
+	ctx = cper_new_ia32x64_context_msr(status, x86_sec, IA32_MCG_CAP, 3);
+	if (!ctx)
+		goto failed;
+	ctx = cper_new_ia32x64_context_msr(status, x86_sec,
+					IA32_MC0_CTL + (mci->bank * 4), 4);
+	if (!ctx)
+		goto failed;
+	ctx = cper_new_ia32x64_context_msr(status, x86_sec,
+					MC0_CTL_MASK + mci->bank, 1);
+	if (!ctx)
+		goto failed;
+
+	return;
+
+failed:
+	/* We're here because of a hardware error, don't break something else */
+	printk(BIOS_ERR, "Error: Not enough room in BERT region for Machine Check error\n");
+}
+
+static const char *const mca_bank_name[] = {
+	"Load-store unit",
+	"Instruction fetch unit",
+	"Combined unit",
+	"Reserved",
+	"Northbridge",
+	"Execution unit",
+	"Floating point unit"
+};
+
+void check_mca(void)
+{
+	int i;
+	msr_t cap;
+	struct mca_bank mci;
+	int num_banks;
+
+	cap = rdmsr(IA32_MCG_CAP);
+	num_banks = cap.lo & MCA_BANKS_MASK;
+
+	if (is_warm_reset()) {
+		for (i = 0 ; i < num_banks ; i++) {
+			if (i == 3) /* Reserved in Family 15h */
+				continue;
+
+			mci.sts = rdmsr(IA32_MC0_STATUS + (i * 4));
+			if (mci.sts.hi || mci.sts.lo) {
+				int core = cpuid_ebx(1) >> 24;
+
+				printk(BIOS_WARNING, "#MC Error: core %d, bank %d %s\n",
+						core, i, mca_bank_name[i]);
+
+				printk(BIOS_WARNING, "   MC%d_STATUS =   %08x_%08x\n",
+						i, mci.sts.hi, mci.sts.lo);
+				mci.addr = rdmsr(MC0_ADDR + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_ADDR =     %08x_%08x\n",
+						i, mci.addr.hi, mci.addr.lo);
+				mci.misc = rdmsr(MC0_MISC + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_MISC =     %08x_%08x\n",
+						i, mci.misc.hi, mci.misc.lo);
+				mci.ctl = rdmsr(IA32_MC0_CTL + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_CTL =      %08x_%08x\n",
+						i, mci.ctl.hi, mci.ctl.lo);
+				mci.cmask = rdmsr(MC0_CTL_MASK + i);
+				printk(BIOS_WARNING, "   MC%d_CTL_MASK = %08x_%08x\n",
+						i, mci.cmask.hi, mci.cmask.lo);
+
+				mci.bank = i;
+				if (CONFIG(ACPI_BERT)
+						&& mca_valid(mci.sts))
+					build_bert_mca_error(&mci);
+			}
+		}
+	}
+
+	/* zero the machine check error status registers */
+	mci.sts.lo = 0;
+	mci.sts.hi = 0;
+	for (i = 0 ; i < num_banks ; i++)
+		wrmsr(IA32_MC0_STATUS + (i * 4), mci.sts);
+}
diff --git a/src/soc/amd/picasso/monotonic_timer.c b/src/soc/amd/picasso/monotonic_timer.c
new file mode 100644
index 0000000..7ea571f
--- /dev/null
+++ b/src/soc/amd/picasso/monotonic_timer.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Google Inc.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <cpu/x86/msr.h>
+#include <timer.h>
+#include <timestamp.h>
+
+#define CU_PTSC_MSR	0xc0010280
+#define PTSC_FREQ_MHZ	100
+
+void timer_monotonic_get(struct mono_time *mt)
+{
+	mono_time_set_usecs(mt, timestamp_get());
+}
+
+uint64_t timestamp_get(void)
+{
+	unsigned long long val;
+	msr_t msr;
+
+	msr = rdmsr(CU_PTSC_MSR);
+
+	val = ((unsigned long long)msr.hi << 32) | msr.lo;
+
+	return val / PTSC_FREQ_MHZ;
+}
diff --git a/src/soc/amd/picasso/nb_util.c b/src/soc/amd/picasso/nb_util.c
new file mode 100644
index 0000000..d5de067
--- /dev/null
+++ b/src/soc/amd/picasso/nb_util.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices
+ *
+ * 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.
+ */
+
+#include <soc/northbridge.h>
+#include <soc/pci_devs.h>
+#include <device/pci_ops.h>
+
+uint32_t nb_ioapic_read(unsigned int index)
+{
+	pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, index);
+	return pci_read_config32(SOC_GNB_DEV, NB_IOAPIC_DATA);
+}
+
+void nb_ioapic_write(unsigned int index, uint32_t value)
+{
+	pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, index);
+	pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_DATA, value);
+}
+
+void *get_ap_entry_ptr(void)
+{
+	return (void *)nb_ioapic_read(AP_SCRATCH_REG);
+}
+
+void set_ap_entry_ptr(void *entry)
+{
+	nb_ioapic_write(AP_SCRATCH_REG, (uintptr_t)entry);
+}
diff --git a/src/soc/amd/picasso/northbridge.c b/src/soc/amd/picasso/northbridge.c
new file mode 100644
index 0000000..5985832
--- /dev/null
+++ b/src/soc/amd/picasso/northbridge.c
@@ -0,0 +1,492 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <device/pci_ops.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/amd/mtrr.h>
+#include <cpu/x86/lapic_def.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <romstage_handoff.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/agesawrapper_call.h>
+#include <agesa_headers.h>
+#include <soc/cpu.h>
+#include <soc/northbridge.h>
+#include <soc/southbridge.h>
+#include <soc/pci_devs.h>
+#include <soc/iomap.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/bert_storage.h>
+
+#include "chip.h"
+
+static void set_io_addr_reg(struct device *dev, u32 nodeid, u32 linkn, u32 reg,
+			u32 io_min, u32 io_max)
+{
+	u32 tempreg;
+
+	/* io range allocation.  Limit */
+	tempreg = (nodeid & 0xf) | ((nodeid & 0x30) << (8 - 4)) | (linkn << 4)
+						| ((io_max & 0xf0) << (12 - 4));
+	pci_write_config32(SOC_ADDR_DEV, reg + 4, tempreg);
+	tempreg = 3 | ((io_min & 0xf0) << (12 - 4)); /* base: ISA and VGA ? */
+	pci_write_config32(SOC_ADDR_DEV, reg, tempreg);
+}
+
+static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index,
+						u32 mmio_min, u32 mmio_max)
+{
+	u32 tempreg;
+
+	/* io range allocation.  Limit */
+	tempreg = (nodeid & 0xf) | (linkn << 4) | (mmio_max & 0xffffff00);
+		pci_write_config32(SOC_ADDR_DEV, reg + 4, tempreg);
+	tempreg = 3 | (nodeid & 0x30) | (mmio_min & 0xffffff00);
+		pci_write_config32(SOC_ADDR_DEV, reg, tempreg);
+}
+
+static void read_resources(struct device *dev)
+{
+	struct resource *res;
+
+	/*
+	 * This MMCONF resource must be reserved in the PCI domain.
+	 * It is not honored by the coreboot resource allocator if it is in
+	 * the CPU_CLUSTER.
+	 */
+	mmconf_resource(dev, MMIO_CONF_BASE);
+
+	/* NB IOAPIC2 resource */
+	res = new_resource(dev, IO_APIC2_ADDR); /* IOAPIC2 */
+	res->base = IO_APIC2_ADDR;
+	res->size = 0x00001000;
+	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void set_resource(struct device *dev, struct resource *res, u32 nodeid)
+{
+	resource_t rbase, rend;
+	unsigned int reg, link_num;
+	char buf[50];
+
+	/* Make certain the resource has actually been set */
+	if (!(res->flags & IORESOURCE_ASSIGNED))
+		return;
+
+	/* If I have already stored this resource don't worry about it */
+	if (res->flags & IORESOURCE_STORED)
+		return;
+
+	/* Only handle PCI memory and IO resources */
+	if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+		return;
+
+	/* Ensure I am actually looking at a resource of function 1 */
+	if ((res->index & 0xffff) < 0x1000)
+		return;
+
+	/* Get the base address */
+	rbase = res->base;
+
+	/* Get the limit (rounded up) */
+	rend  = resource_end(res);
+
+	/* Get the register and link */
+	reg  = res->index & 0xfff; /* 4k */
+	link_num = IOINDEX_LINK(res->index);
+
+	if (res->flags & IORESOURCE_IO)
+		set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
+	else if (res->flags & IORESOURCE_MEM)
+		set_mmio_addr_reg(nodeid, link_num, reg,
+				(res->index >> 24), rbase >> 8, rend >> 8);
+
+	res->flags |= IORESOURCE_STORED;
+	snprintf(buf, sizeof(buf), " <node %x link %x>",
+			nodeid, link_num);
+	report_resource_stored(dev, res, buf);
+}
+
+/**
+ * I tried to reuse the resource allocation code in set_resource()
+ * but it is too difficult to deal with the resource allocation magic.
+ */
+
+static void create_vga_resource(struct device *dev)
+{
+	struct bus *link;
+
+	/* find out which link the VGA card is connected,
+	 * we only deal with the 'first' vga card */
+	for (link = dev->link_list ; link ; link = link->next)
+		if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
+			break;
+
+	/* no VGA card installed */
+	if (link == NULL)
+		return;
+
+	printk(BIOS_DEBUG, "VGA: %s has VGA device\n",	dev_path(dev));
+	/* Route A0000-BFFFF, IO 3B0-3BB 3C0-3DF */
+	pci_write_config32(SOC_ADDR_DEV, D18F1_VGAEN, VGA_ADDR_ENABLE);
+}
+
+static void set_resources(struct device *dev)
+{
+	struct bus *bus;
+	struct resource *res;
+
+
+	/* do we need this? */
+	create_vga_resource(dev);
+
+	/* Set each resource we have found */
+	for (res = dev->resource_list ; res ; res = res->next)
+		set_resource(dev, res, 0);
+
+	for (bus = dev->link_list ; bus ; bus = bus->next)
+		if (bus->children)
+			assign_resources(bus);
+}
+
+static void northbridge_init(struct device *dev)
+{
+	setup_ioapic((u8 *)IO_APIC2_ADDR, CONFIG_MAX_CPUS+1);
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+
+	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
+					     CONFIG_MMCONF_BASE_ADDRESS,
+					     0,
+					     0,
+					     CONFIG_MMCONF_BUS_NUMBER);
+
+	return current;
+}
+
+static unsigned long acpi_fill_hest(acpi_hest_t *hest)
+{
+	void *addr, *current;
+
+	/* Skip the HEST header. */
+	current = (void *)(hest + 1);
+
+	addr = agesawrapper_getlateinitptr(PICK_WHEA_MCE);
+	if (addr != NULL)
+		current += acpi_create_hest_error_source(hest, current, 0,
+				(void *)((u32)addr + 2), *(uint16_t *)addr - 2);
+
+	addr = agesawrapper_getlateinitptr(PICK_WHEA_CMC);
+	if (addr != NULL)
+		current += acpi_create_hest_error_source(hest, current, 1,
+				(void *)((u32)addr + 2), *(uint16_t *)addr - 2);
+
+	return (unsigned long)current;
+}
+
+static void northbridge_fill_ssdt_generator(struct device *device)
+{
+	msr_t msr;
+	char pscope[] = "\\_SB.PCI0";
+
+	acpigen_write_scope(pscope);
+	msr = rdmsr(TOP_MEM);
+	acpigen_write_name_dword("TOM1", msr.lo);
+	msr = rdmsr(TOP_MEM2);
+	/*
+	 * Since XP only implements parts of ACPI 2.0, we can't use a qword
+	 * here.
+	 * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
+	 * slide 22ff.
+	 * Shift value right by 20 bit to make it fit into 32bit,
+	 * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
+	 */
+	acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
+	acpigen_pop_len();
+}
+
+static unsigned long agesa_write_acpi_tables(struct device *device,
+					     unsigned long current,
+					     acpi_rsdp_t *rsdp)
+{
+	acpi_srat_t *srat;
+	acpi_slit_t *slit;
+	acpi_header_t *ssdt;
+	acpi_header_t *alib;
+	acpi_header_t *ivrs;
+	acpi_hest_t *hest;
+	acpi_bert_t *bert;
+
+	/* HEST */
+	current = ALIGN(current, 8);
+	hest = (acpi_hest_t *)current;
+	acpi_write_hest(hest, acpi_fill_hest);
+	acpi_add_table(rsdp, (void *)current);
+	current += hest->header.length;
+
+	/* BERT */
+	if (CONFIG(ACPI_BERT) && bert_errors_present()) {
+		/* Skip the table if no errors are present.  ACPI driver reports
+		 * a table with a 0-length region:
+		 *   BERT: [Firmware Bug]: table invalid.
+		 */
+		void *rgn;
+		size_t size;
+		bert_errors_region(&rgn, &size);
+		if (!rgn) {
+			printk(BIOS_ERR, "Error: Can't find BERT storage area\n");
+		} else {
+			current = ALIGN(current, 8);
+			bert = (acpi_bert_t *)current;
+			acpi_write_bert(bert, (uintptr_t)rgn, size);
+			acpi_add_table(rsdp, (void *)current);
+			current += bert->header.length;
+		}
+	}
+
+	current = ALIGN(current, 8);
+	printk(BIOS_DEBUG, "ACPI:    * IVRS at %lx\n", current);
+	ivrs = agesawrapper_getlateinitptr(PICK_IVRS);
+	if (ivrs != NULL) {
+		memcpy((void *)current, ivrs, ivrs->length);
+		ivrs = (acpi_header_t *)current;
+		current += ivrs->length;
+		acpi_add_table(rsdp, ivrs);
+	} else {
+		printk(BIOS_DEBUG, "  AGESA IVRS table NULL. Skipping.\n");
+	}
+
+	/* SRAT */
+	current = ALIGN(current, 8);
+	printk(BIOS_DEBUG, "ACPI:    * SRAT at %lx\n", current);
+	srat = (acpi_srat_t *)agesawrapper_getlateinitptr(PICK_SRAT);
+	if (srat != NULL) {
+		memcpy((void *)current, srat, srat->header.length);
+		srat = (acpi_srat_t *)current;
+		current += srat->header.length;
+		acpi_add_table(rsdp, srat);
+	} else {
+		printk(BIOS_DEBUG, "  AGESA SRAT table NULL. Skipping.\n");
+	}
+
+	/* SLIT */
+	current = ALIGN(current, 8);
+	printk(BIOS_DEBUG, "ACPI:   * SLIT at %lx\n", current);
+	slit = (acpi_slit_t *)agesawrapper_getlateinitptr(PICK_SLIT);
+	if (slit != NULL) {
+		memcpy((void *)current, slit, slit->header.length);
+		slit = (acpi_slit_t *)current;
+		current += slit->header.length;
+		acpi_add_table(rsdp, slit);
+	} else {
+		printk(BIOS_DEBUG, "  AGESA SLIT table NULL. Skipping.\n");
+	}
+
+	/* ALIB */
+	current = ALIGN(current, 16);
+	printk(BIOS_DEBUG, "ACPI:  * AGESA ALIB SSDT at %lx\n", current);
+	alib = (acpi_header_t *)agesawrapper_getlateinitptr(PICK_ALIB);
+	if (alib != NULL) {
+		memcpy((void *)current, alib, alib->length);
+		alib = (acpi_header_t *)current;
+		current += alib->length;
+		acpi_add_table(rsdp, (void *)alib);
+	} else {
+		printk(BIOS_DEBUG, "	AGESA ALIB SSDT table NULL."
+							" Skipping.\n");
+	}
+
+	current   = ALIGN(current, 16);
+	printk(BIOS_DEBUG, "ACPI:    * SSDT at %lx\n", current);
+	ssdt = (acpi_header_t *)agesawrapper_getlateinitptr(PICK_PSTATE);
+	if (ssdt != NULL) {
+		memcpy((void *)current, ssdt, ssdt->length);
+		ssdt = (acpi_header_t *)current;
+		current += ssdt->length;
+	} else {
+		printk(BIOS_DEBUG, "  AGESA PState table NULL. Skipping.\n");
+	}
+	acpi_add_table(rsdp, ssdt);
+
+	printk(BIOS_DEBUG, "ACPI:    * SSDT for PState at %lx\n", current);
+	return current;
+}
+
+static struct device_operations northbridge_operations = {
+	.read_resources	  = read_resources,
+	.set_resources	  = set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init		  = northbridge_init,
+	.acpi_fill_ssdt_generator = northbridge_fill_ssdt_generator,
+	.write_acpi_tables = agesa_write_acpi_tables,
+	.enable		  = 0,
+	.ops_pci	  = 0,
+};
+
+static const struct pci_driver family15_northbridge __pci_driver = {
+	.ops	= &northbridge_operations,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_AMD_15H_MODEL_707F_NB_HT,
+};
+
+/*
+ * Enable VGA cycles.  Set memory ranges of the FCH legacy devices (TPM, HPET,
+ * BIOS RAM, Watchdog Timer, IOAPIC and ACPI) as non-posted.  Set remaining
+ * MMIO to posted.  Route all I/O to the southbridge.
+ */
+void amd_initcpuio(void)
+{
+	uintptr_t topmem = bsp_topmem();
+	uintptr_t base, limit;
+
+	/* Enable legacy video routing: D18F1xF4 VGA Enable */
+	pci_write_config32(SOC_ADDR_DEV, D18F1_VGAEN, VGA_ADDR_ENABLE);
+
+	/* Non-posted: range(HPET-LAPIC) or 0xfed00000 through 0xfee00000-1 */
+	base = (HPET_BASE_ADDRESS >> 8) | MMIO_WE | MMIO_RE;
+	limit = (ALIGN_DOWN(LOCAL_APIC_ADDR - 1, 64 * KiB) >> 8) | MMIO_NP;
+	pci_write_config32(SOC_ADDR_DEV, NB_MMIO_LIMIT_LO(0), limit);
+	pci_write_config32(SOC_ADDR_DEV, NB_MMIO_BASE_LO(0), base);
+
+	/* Remaining PCI hole posted MMIO: TOM-HPET (TOM through 0xfed00000-1 */
+	base = (topmem >> 8) | MMIO_WE | MMIO_RE;
+	limit = ALIGN_DOWN(HPET_BASE_ADDRESS - 1, 64 * KiB) >> 8;
+	pci_write_config32(SOC_ADDR_DEV, NB_MMIO_LIMIT_LO(1), limit);
+	pci_write_config32(SOC_ADDR_DEV, NB_MMIO_BASE_LO(1), base);
+
+	/* Route all I/O downstream */
+	base = 0 | IO_WE | IO_RE;
+	limit = ALIGN_DOWN(0xffff, 4 * KiB);
+	pci_write_config32(SOC_ADDR_DEV, NB_IO_LIMIT(0), limit);
+	pci_write_config32(SOC_ADDR_DEV, NB_IO_BASE(0), base);
+}
+
+void fam15_finalize(void *chip_info)
+{
+	u32 value;
+
+	/* TODO: move IOAPIC code to dsdt.asl */
+	pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_INDEX, 0);
+	pci_write_config32(SOC_GNB_DEV, NB_IOAPIC_DATA, 5);
+
+	/* disable No Snoop */
+	value = pci_read_config32(SOC_HDA0_DEV, HDA_DEV_CTRL_STATUS);
+	value &= ~HDA_NO_SNOOP_EN;
+	pci_write_config32(SOC_HDA0_DEV, HDA_DEV_CTRL_STATUS, value);
+}
+
+void domain_enable_resources(struct device *dev)
+{
+	/* Must be called after PCI enumeration and resource allocation */
+	if (!romstage_handoff_is_resume())
+		do_agesawrapper(AMD_INIT_MID, "amdinitmid");
+}
+
+void domain_set_resources(struct device *dev)
+{
+	uint64_t uma_base = get_uma_base();
+	uint32_t uma_size = get_uma_size();
+	uint32_t mem_useable = (uintptr_t)cbmem_top();
+	msr_t tom = rdmsr(TOP_MEM);
+	msr_t high_tom = rdmsr(TOP_MEM2);
+	uint64_t high_mem_useable;
+	int idx = 0x10;
+
+	/* 0x0 -> 0x9ffff */
+	ram_resource(dev, idx++, 0, 0xa0000 / KiB);
+
+	/* 0xa0000 -> 0xbffff: legacy VGA */
+	mmio_resource(dev, idx++, 0xa0000 / KiB, 0x20000 / KiB);
+
+	/* 0xc0000 -> 0xfffff: Option ROM */
+	reserved_ram_resource(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
+
+	/*
+	 * 0x100000 (1MiB) -> low top useable RAM
+	 * cbmem_top() accounts for low UMA and TSEG if they are used.
+	 */
+	ram_resource(dev, idx++, (1 * MiB) / KiB,
+			(mem_useable - (1 * MiB)) / KiB);
+
+	/* Low top useable RAM -> Low top RAM (bottom pci mmio hole) */
+	reserved_ram_resource(dev, idx++, mem_useable / KiB,
+					(tom.lo - mem_useable) / KiB);
+
+	/* If there is memory above 4GiB */
+	if (high_tom.hi) {
+		/* 4GiB -> high top useable */
+		if (uma_base >= (4ull * GiB))
+			high_mem_useable = uma_base;
+		else
+			high_mem_useable = ((uint64_t)high_tom.lo |
+						((uint64_t)high_tom.hi << 32));
+
+		ram_resource(dev, idx++, (4ull * GiB) / KiB,
+				((high_mem_useable - (4ull * GiB)) / KiB));
+
+		/* High top useable RAM -> high top RAM */
+		if (uma_base >= (4ull * GiB)) {
+			reserved_ram_resource(dev, idx++, uma_base / KiB,
+						uma_size / KiB);
+		}
+	}
+
+	assign_resources(dev->link_list);
+}
+
+/*********************************************************************
+ * Change the vendor / device IDs to match the generic VBIOS header. *
+ *********************************************************************/
+u32 map_oprom_vendev(u32 vendev)
+{
+	u32 new_vendev;
+	new_vendev =
+		((vendev >= 0x100298e0) && (vendev <= 0x100298ef)) ?
+				0x100298e0 : vendev;
+
+	if (vendev != new_vendev)
+		printk(BIOS_NOTICE, "Mapping PCI device %8x to %8x\n",
+				vendev, new_vendev);
+
+	return new_vendev;
+}
+
+__weak void set_board_env_params(GNB_ENV_CONFIGURATION *params) { }
+
+void SetNbEnvParams(GNB_ENV_CONFIGURATION *params)
+{
+	const struct device *dev = SOC_IOMMU_DEV;
+	params->IommuSupport = dev && dev->enabled;
+	set_board_env_params(params);
+}
+
+void SetNbMidParams(GNB_MID_CONFIGURATION *params)
+{
+	/* 0=Primary and decode all VGA resources, 1=Secondary - decode none */
+	params->iGpuVgaMode = 0;
+	params->GnbIoapicAddress = IO_APIC2_ADDR;
+}
diff --git a/src/soc/amd/picasso/pmutil.c b/src/soc/amd/picasso/pmutil.c
new file mode 100644
index 0000000..59de348
--- /dev/null
+++ b/src/soc/amd/picasso/pmutil.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Google Inc.
+ *
+ * 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.
+ */
+
+#include <arch/acpi.h>
+#include <soc/southbridge.h>
+#include <amdblocks/acpimmio.h>
+#include <security/vboot/vboot_common.h>
+#include <security/vboot/vbnv.h>
+#include <pc80/mc146818rtc.h>
+
+int vbnv_cmos_failed(void)
+{
+	/* If CMOS power has failed, the century will be set to 0xff */
+	return cmos_read(RTC_CLK_ALTCENTURY) == 0xff;
+}
diff --git a/src/soc/amd/picasso/ramtop.c b/src/soc/amd/picasso/ramtop.c
new file mode 100644
index 0000000..7c855bb
--- /dev/null
+++ b/src/soc/amd/picasso/ramtop.c
@@ -0,0 +1,151 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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.
+ */
+
+#define __SIMPLE_DEVICE__
+
+#include <assert.h>
+#include <stdint.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <cbmem.h>
+#include <stage_cache.h>
+#include <arch/bert_storage.h>
+#include <soc/northbridge.h>
+#include <soc/iomap.h>
+#include <amdblocks/acpimmio.h>
+
+void backup_top_of_low_cacheable(uintptr_t ramtop)
+{
+	biosram_write32(BIOSRAM_CBMEM_TOP, ramtop);
+}
+
+uintptr_t restore_top_of_low_cacheable(void)
+{
+	return biosram_read32(BIOSRAM_CBMEM_TOP);
+}
+
+#if CONFIG(ACPI_BERT)
+ #if CONFIG_SMM_TSEG_SIZE == 0x0
+  #define BERT_REGION_MAX_SIZE 0x100000
+ #else
+  /* SMM_TSEG_SIZE must stay on a boundary appropriate for its granularity */
+  #define BERT_REGION_MAX_SIZE CONFIG_SMM_TSEG_SIZE
+ #endif
+#else
+ #define BERT_REGION_MAX_SIZE 0
+#endif
+
+void bert_reserved_region(void **start, size_t *size)
+{
+	if (CONFIG(ACPI_BERT))
+		*start = cbmem_top();
+	else
+		start = NULL;
+	*size = BERT_REGION_MAX_SIZE;
+}
+
+void *cbmem_top(void)
+{
+	msr_t tom = rdmsr(TOP_MEM);
+
+	if (!tom.lo)
+		return 0;
+
+	/* 8MB alignment to keep MTRR usage low */
+	return (void *)ALIGN_DOWN(restore_top_of_low_cacheable()
+			- CONFIG_SMM_TSEG_SIZE
+			- BERT_REGION_MAX_SIZE, 8*MiB);
+}
+
+static uintptr_t smm_region_start(void)
+{
+	return (uintptr_t)cbmem_top() + BERT_REGION_MAX_SIZE;
+}
+
+static size_t smm_region_size(void)
+{
+	return CONFIG_SMM_TSEG_SIZE;
+}
+
+void stage_cache_external_region(void **base, size_t *size)
+{
+	if (smm_subregion(SMM_SUBREGION_CACHE, base, size)) {
+		printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
+		*base = NULL;
+		*size = 0;
+	}
+}
+
+void smm_region_info(void **start, size_t *size)
+{
+	*start = (void *)smm_region_start();
+	*size = smm_region_size();
+}
+
+/*
+ * For data stored in TSEG, ensure TValid is clear so R/W access can reach
+ * the DRAM when not in SMM.
+ */
+static void clear_tvalid(void)
+{
+	msr_t hwcr = rdmsr(HWCR_MSR);
+	msr_t mask = rdmsr(SMM_MASK_MSR);
+	int tvalid = !!(mask.lo & SMM_TSEG_VALID);
+
+	if (hwcr.lo & SMM_LOCK) {
+		if (!tvalid) /* not valid but locked means still accessible */
+			return;
+
+		printk(BIOS_ERR, "Error: can't clear TValid, already locked\n");
+		return;
+	}
+
+	mask.lo &= ~SMM_TSEG_VALID;
+	wrmsr(SMM_MASK_MSR, mask);
+}
+
+int smm_subregion(int sub, void **start, size_t *size)
+{
+	uintptr_t sub_base;
+	size_t sub_size;
+	const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+	sub_base = smm_region_start();
+	sub_size = smm_region_size();
+
+	assert(sub_size > CONFIG_SMM_RESERVED_SIZE);
+
+	switch (sub) {
+	case SMM_SUBREGION_HANDLER:
+		/* Handler starts at the base of TSEG. */
+		sub_size -= cache_size;
+		break;
+	case SMM_SUBREGION_CACHE:
+		/* External cache is in the middle of TSEG. */
+		sub_base += sub_size - cache_size;
+		sub_size = cache_size;
+		clear_tvalid();
+		break;
+	default:
+		return -1;
+	}
+
+	*start = (void *)sub_base;
+	*size = sub_size;
+
+	return 0;
+}
diff --git a/src/soc/amd/picasso/reset.c b/src/soc/amd/picasso/reset.c
new file mode 100644
index 0000000..ec5ee91
--- /dev/null
+++ b/src/soc/amd/picasso/reset.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2017 Google, Inc.
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+#include <soc/northbridge.h>
+#include <soc/pci_devs.h>
+#include <device/pci_ops.h>
+#include <soc/southbridge.h>
+#include <amdblocks/acpimmio.h>
+#include <amdblocks/reset.h>
+
+void set_warm_reset_flag(void)
+{
+	u32 htic;
+	htic = pci_read_config32(SOC_HT_DEV, HT_INIT_CONTROL);
+	htic |= HTIC_COLD_RST_DET;
+	pci_write_config32(SOC_HT_DEV, HT_INIT_CONTROL, htic);
+}
+
+int is_warm_reset(void)
+{
+	u32 htic;
+	htic = pci_read_config32(SOC_HT_DEV, HT_INIT_CONTROL);
+	return !!(htic & HTIC_COLD_RST_DET);
+}
+
+/* Clear bits 5, 9 & 10, used to signal the reset type */
+static void clear_bios_reset(void)
+{
+	u32 htic;
+	htic = pci_read_config32(SOC_HT_DEV, HT_INIT_CONTROL);
+	htic &= ~HTIC_BIOSR_DETECT;
+	pci_write_config32(SOC_HT_DEV, HT_INIT_CONTROL, htic);
+}
+
+void do_cold_reset(void)
+{
+	clear_bios_reset();
+
+	/* De-assert and then assert all PwrGood signals on CF9 reset. */
+	pm_write16(PWR_RESET_CFG, pm_read16(PWR_RESET_CFG) |
+		TOGGLE_ALL_PWR_GOOD);
+	outb(RST_CMD | SYS_RST, SYS_RESET);
+}
+
+void do_warm_reset(void)
+{
+	set_warm_reset_flag();
+	clear_bios_reset();
+
+	/* Assert reset signals only. */
+	outb(RST_CMD | SYS_RST, SYS_RESET);
+}
+
+void do_board_reset(void)
+{
+	/* TODO: Would a warm_reset() suffice? */
+	do_cold_reset();
+}
diff --git a/src/soc/amd/picasso/romstage.c b/src/soc/amd/picasso/romstage.c
new file mode 100644
index 0000000..12ee2a8
--- /dev/null
+++ b/src/soc/amd/picasso/romstage.c
@@ -0,0 +1,247 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <device/pci_ops.h>
+#include <arch/cpu.h>
+#include <arch/acpi.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/amd/mtrr.h>
+#include <cbmem.h>
+#include <commonlib/helpers.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <program_loading.h>
+#include <romstage_handoff.h>
+#include <elog.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/agesawrapper_call.h>
+#include <soc/northbridge.h>
+#include <soc/romstage.h>
+#include <soc/southbridge.h>
+#include <amdblocks/psp.h>
+
+#include "chip.h"
+
+void __weak mainboard_romstage_entry(int s3_resume)
+{
+	/* By default, don't do anything */
+}
+
+static void load_smu_fw1(void)
+{
+	u32 base, limit, cmd;
+
+	/* Open a posted hole from 0x80000000 : 0xfed00000-1 */
+	base = (0x80000000 >> 8) | MMIO_WE | MMIO_RE;
+	limit = (ALIGN_DOWN(HPET_BASE_ADDRESS - 1, 64 * KiB) >> 8);
+	pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_LIMIT0_LO, limit);
+	pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_BASE0_LO, base);
+
+	/* Preload a value into "BAR3" and enable it */
+	pci_write_config32(SOC_PSP_DEV, PSP_MAILBOX_BAR, PSP_MAILBOX_BAR3_BASE);
+	pci_write_config32(SOC_PSP_DEV, PSP_BAR_ENABLES, PSP_MAILBOX_BAR_EN);
+
+	/* Enable memory access and master */
+	cmd = pci_read_config32(SOC_PSP_DEV, PCI_COMMAND);
+	cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	pci_write_config32(SOC_PSP_DEV, PCI_COMMAND, cmd);
+
+	psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW, "smu_fw");
+}
+
+static void agesa_call(void)
+{
+	post_code(0x37);
+	do_agesawrapper(AMD_INIT_RESET, "amdinitreset");
+
+	post_code(0x38);
+	/* APs will not exit amdinitearly */
+	do_agesawrapper(AMD_INIT_EARLY, "amdinitearly");
+}
+
+static void bsp_agesa_call(void)
+{
+	set_ap_entry_ptr(agesa_call); /* indicate the path to the AP */
+	agesa_call();
+}
+
+asmlinkage void car_stage_entry(void)
+{
+	struct postcar_frame pcf;
+	uintptr_t top_of_ram;
+	void *smm_base;
+	size_t smm_size;
+	uintptr_t tseg_base;
+	msr_t base, mask;
+	msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
+	int vmtrrs = mtrr_cap.lo & MTRR_CAP_VCNT;
+	int s3_resume = acpi_s3_resume_allowed() && acpi_is_wakeup_s3();
+	int i;
+
+	console_init();
+
+	if (CONFIG(SOC_AMD_PSP_SELECTABLE_SMU_FW))
+		load_smu_fw1();
+
+	mainboard_romstage_entry(s3_resume);
+
+	bsp_agesa_call();
+
+	if (!s3_resume) {
+		post_code(0x40);
+		do_agesawrapper(AMD_INIT_POST, "amdinitpost");
+
+		post_code(0x41);
+		/*
+		 * TODO: This is a hack to work around current AGESA behavior.
+		 *       AGESA needs to change to reflect that coreboot owns
+		 *       the MTRRs.
+		 *
+		 * After setting up DRAM, AGESA also completes the configuration
+		 * of the MTRRs, setting regions to WB.  Anything written to
+		 * memory between now and and when CAR is dismantled will be
+		 * in cache and lost.  For now, set the regions UC to ensure
+		 * the writes get to DRAM.
+		 */
+		for (i = 0 ; i < vmtrrs ; i++) {
+			base = rdmsr(MTRR_PHYS_BASE(i));
+			mask = rdmsr(MTRR_PHYS_MASK(i));
+			if (!(mask.lo & MTRR_PHYS_MASK_VALID))
+				continue;
+
+			if ((base.lo & 0x7) == MTRR_TYPE_WRBACK) {
+				base.lo &= ~0x7;
+				base.lo |= MTRR_TYPE_UNCACHEABLE;
+				wrmsr(MTRR_PHYS_BASE(i), base);
+			}
+		}
+		/* Disable WB from to region 4GB-TOM2. */
+		msr_t sys_cfg = rdmsr(SYSCFG_MSR);
+		sys_cfg.lo &= ~SYSCFG_MSR_TOM2WB;
+		wrmsr(SYSCFG_MSR, sys_cfg);
+		if (CONFIG(ELOG_BOOT_COUNT))
+			boot_count_increment();
+	} else {
+		printk(BIOS_INFO, "S3 detected\n");
+		post_code(0x60);
+		do_agesawrapper(AMD_INIT_RESUME, "amdinitresume");
+
+		post_code(0x61);
+	}
+
+	post_code(0x42);
+	psp_notify_dram();
+
+	post_code(0x43);
+	if (cbmem_recovery(s3_resume))
+		printk(BIOS_CRIT, "Failed to recover cbmem\n");
+	if (romstage_handoff_init(s3_resume))
+		printk(BIOS_ERR, "Failed to set romstage handoff data\n");
+
+	post_code(0x44);
+	if (postcar_frame_init(&pcf, 1 * KiB))
+		die("Unable to initialize postcar frame.\n");
+
+	/*
+	 * We need to make sure ramstage will be run cached. At this point exact
+	 * location of ramstage in cbmem is not known. Instruct postcar to cache
+	 * 16 megs under cbmem top which is a safe bet to cover ramstage.
+	 */
+	top_of_ram = (uintptr_t) cbmem_top();
+	postcar_frame_add_mtrr(&pcf, top_of_ram - 16*MiB, 16*MiB,
+		MTRR_TYPE_WRBACK);
+
+	/* Cache the memory-mapped boot media. */
+	postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);
+
+	/*
+	 * Cache the TSEG region at the top of ram. This region is
+	 * not restricted to SMM mode until SMM has been relocated.
+	 * By setting the region to cacheable it provides faster access
+	 * when relocating the SMM handler as well as using the TSEG
+	 * region for other purposes.
+	 */
+	smm_region_info(&smm_base, &smm_size);
+	tseg_base = (uintptr_t)smm_base;
+	postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);
+
+	post_code(0x45);
+	run_postcar_phase(&pcf);
+
+	post_code(0x50);  /* Should never see this post code. */
+}
+
+void SetMemParams(AMD_POST_PARAMS *PostParams)
+{
+	const struct soc_amd_stoneyridge_config *cfg;
+	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
+
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_ERR, "ERROR: Cannot find SoC devicetree config\n");
+		/* In case of a BIOS error, only attempt to set UMA. */
+		PostParams->MemConfig.UmaMode = CONFIG(GFXUMA) ?
+					UMA_AUTO : UMA_NONE;
+		return;
+	}
+
+	cfg = dev->chip_info;
+
+	PostParams->MemConfig.EnableMemClr = cfg->dram_clear_on_reset;
+
+	switch (cfg->uma_mode) {
+	case UMAMODE_NONE:
+		PostParams->MemConfig.UmaMode = UMA_NONE;
+		break;
+	case UMAMODE_SPECIFIED_SIZE:
+		PostParams->MemConfig.UmaMode = UMA_SPECIFIED;
+		/* 64 KiB blocks. */
+		PostParams->MemConfig.UmaSize = cfg->uma_size / (64 * KiB);
+		break;
+	case UMAMODE_AUTO_LEGACY:
+		PostParams->MemConfig.UmaMode = UMA_AUTO;
+		PostParams->MemConfig.UmaVersion = UMA_LEGACY;
+		break;
+	case UMAMODE_AUTO_NON_LEGACY:
+		PostParams->MemConfig.UmaMode = UMA_AUTO;
+		PostParams->MemConfig.UmaVersion = UMA_NON_LEGACY;
+		break;
+	}
+}
+
+void soc_customize_init_early(AMD_EARLY_PARAMS *InitEarly)
+{
+	const struct soc_amd_stoneyridge_config *cfg;
+	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
+	struct _PLATFORM_CONFIGURATION *platform;
+
+	if (!dev || !dev->chip_info) {
+		printk(BIOS_WARNING, "Warning: Cannot find SoC devicetree"
+					" config, STAPM unchanged\n");
+		return;
+	}
+	cfg = dev->chip_info;
+	platform = &InitEarly->PlatformConfig;
+	if ((cfg->stapm_percent) && (cfg->stapm_time_ms) &&
+				    (cfg->stapm_power_mw)) {
+		platform->PlatStapmConfig.CfgStapmScalar = cfg->stapm_percent;
+		platform->PlatStapmConfig.CfgStapmTimeConstant =
+							cfg->stapm_time_ms;
+		platform->PkgPwrLimitDC = cfg->stapm_power_mw;
+		platform->PkgPwrLimitAC = cfg->stapm_power_mw;
+		platform->PlatStapmConfig.CfgStapmBoost = StapmBoostEnabled;
+	}
+}
diff --git a/src/soc/amd/picasso/sata.c b/src/soc/amd/picasso/sata.c
new file mode 100644
index 0000000..6740698
--- /dev/null
+++ b/src/soc/amd/picasso/sata.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pci_def.h>
+#include <amdblocks/sata.h>
+#include <soc/southbridge.h>
+
+void soc_enable_sata_features(struct device *dev)
+{
+	u8 *ahci_ptr;
+	u32 misc_ctl, cap_cfg;
+
+	u32 temp;
+
+	/* unlock the write-protect */
+	misc_ctl = pci_read_config32(dev, SATA_MISC_CONTROL_REG);
+	misc_ctl |= SATA_MISC_SUBCLASS_WREN;
+	pci_write_config32(dev, SATA_MISC_CONTROL_REG, misc_ctl);
+
+	/* set the SATA AHCI mode to allow port expanders */
+	ahci_ptr = (u8 *)(uintptr_t)ALIGN_DOWN(
+		pci_read_config32(dev, PCI_BASE_ADDRESS_5), 256);
+
+	cap_cfg = read32(ahci_ptr + SATA_CAPABILITIES_REG);
+	cap_cfg |= SATA_CAPABILITY_SPM;
+	write32(ahci_ptr + SATA_CAPABILITIES_REG, cap_cfg);
+
+	/* lock the write-protect */
+	temp = pci_read_config32(dev, SATA_MISC_CONTROL_REG);
+	temp &= ~SATA_MISC_SUBCLASS_WREN;
+	pci_write_config32(dev, SATA_MISC_CONTROL_REG, temp);
+};
diff --git a/src/soc/amd/picasso/sm.c b/src/soc/amd/picasso/sm.c
new file mode 100644
index 0000000..803e628
--- /dev/null
+++ b/src/soc/amd/picasso/sm.c
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <cpu/x86/lapic.h>
+#include <arch/ioapic.h>
+#include <stdlib.h>
+#include <soc/southbridge.h>
+#include <soc/smbus.h>
+
+/*
+* The southbridge enables all USB controllers by default in SMBUS Control.
+* The southbridge enables SATA by default in SMBUS Control.
+*/
+
+static void sm_init(struct device *dev)
+{
+	setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS);
+}
+
+static u32 get_sm_mmio(struct device *dev)
+{
+	struct resource *res;
+	struct bus *pbus;
+
+	pbus = get_pbus_smbus(dev);
+	res = find_resource(pbus->dev, 0x90);
+	if (res->base == SMB_BASE_ADDR)
+		return ACPIMMIO_SMBUS_BASE;
+
+	return ACPIMMIO_ASF_BASE;
+}
+
+static int lsmbus_recv_byte(struct device *dev)
+{
+	u8 device;
+
+	device = dev->path.i2c.device;
+	return do_smbus_recv_byte(get_sm_mmio(dev), device);
+}
+
+static int lsmbus_send_byte(struct device *dev, u8 val)
+{
+	u8 device;
+
+	device = dev->path.i2c.device;
+	return do_smbus_send_byte(get_sm_mmio(dev), device, val);
+}
+
+static int lsmbus_read_byte(struct device *dev, u8 address)
+{
+	u8 device;
+
+	device = dev->path.i2c.device;
+	return do_smbus_read_byte(get_sm_mmio(dev), device, address);
+}
+
+static int lsmbus_write_byte(struct device *dev, u8 address, u8 val)
+{
+	u8 device;
+
+	device = dev->path.i2c.device;
+	return do_smbus_write_byte(get_sm_mmio(dev), device, address, val);
+}
+static struct smbus_bus_operations lops_smbus_bus = {
+	.recv_byte = lsmbus_recv_byte,
+	.send_byte = lsmbus_send_byte,
+	.read_byte = lsmbus_read_byte,
+	.write_byte = lsmbus_write_byte,
+};
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+static struct device_operations smbus_ops = {
+	.read_resources = DEVICE_NOOP,
+	.set_resources = DEVICE_NOOP,
+	.enable_resources = pci_dev_enable_resources,
+	.init = sm_init,
+	.scan_bus = scan_smbus,
+	.ops_pci = &lops_pci,
+	.ops_smbus_bus = &lops_smbus_bus,
+};
+static const struct pci_driver smbus_driver __pci_driver = {
+	.ops = &smbus_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.device = PCI_DEVICE_ID_AMD_CZ_SMBUS,
+};
diff --git a/src/soc/amd/picasso/smbus.c b/src/soc/amd/picasso/smbus.c
new file mode 100644
index 0000000..31457f9
--- /dev/null
+++ b/src/soc/amd/picasso/smbus.c
@@ -0,0 +1,191 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <arch/io.h>
+#include <stdint.h>
+#include <console/console.h>
+#include <amdblocks/acpimmio.h>
+#include <soc/smbus.h>
+#include <soc/southbridge.h>
+
+static u8 controller_read8(u32 base, u8 reg)
+{
+	switch (base) {
+	case ACPIMMIO_SMBUS_BASE:
+		return smbus_read8(reg);
+	case ACPIMMIO_ASF_BASE:
+		return asf_read8(reg);
+	default:
+		printk(BIOS_ERR, "Error attempting to read SMBus at address 0x%x\n",
+				base);
+	}
+	return 0xff;
+}
+
+static void controller_write8(u32 base, u8 reg, u8 val)
+{
+	switch (base) {
+	case ACPIMMIO_SMBUS_BASE:
+		smbus_write8(reg, val);
+		break;
+	case ACPIMMIO_ASF_BASE:
+		asf_write8(reg, val);
+		break;
+	default:
+		printk(BIOS_ERR, "Error attempting to write SMBus at address 0x%x\n",
+				base);
+	}
+}
+
+static int smbus_wait_until_ready(u32 mmio)
+{
+	u32 loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		u8 val;
+		val = controller_read8(mmio, SMBHSTSTAT);
+		val &= SMBHST_STAT_VAL_BITS;
+		if (val == 0) {	/* ready now */
+			return 0;
+		}
+		controller_write8(mmio, SMBHSTSTAT, val);
+	} while (--loops);
+	return -2;		/* time out */
+}
+
+static int smbus_wait_until_done(u32 mmio)
+{
+	u32 loops;
+	loops = SMBUS_TIMEOUT;
+	do {
+		u8 val;
+
+		val = controller_read8(mmio, SMBHSTSTAT);
+		val &= SMBHST_STAT_VAL_BITS;	/* mask off reserved bits */
+		if (val & SMBHST_STAT_ERROR_BITS)
+			return -5;	/* error */
+		if (val == SMBHST_STAT_NOERROR) {
+			controller_write8(mmio, SMBHSTSTAT, val); /* clr sts */
+			return 0;
+		}
+	} while (--loops);
+	return -3;		/* timeout */
+}
+
+int do_smbus_recv_byte(u32 mmio, u8 device)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(mmio) < 0)
+		return -2;	/* not ready */
+
+	/* set the device I'm talking to */
+	controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1);
+
+	byte = controller_read8(mmio, SMBHSTCTRL);
+	byte &= ~SMBHST_CTRL_MODE_BITS;			/* Clear [4:2] */
+	byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW;	/* set mode, start */
+	controller_write8(mmio, SMBHSTCTRL, byte);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(mmio) < 0)
+		return -3;	/* timeout or error */
+
+	/* read results of transaction */
+	byte = controller_read8(mmio, SMBHSTDAT0);
+
+	return byte;
+}
+
+int do_smbus_send_byte(u32 mmio, u8 device, u8 val)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(mmio) < 0)
+		return -2;	/* not ready */
+
+	/* set the command... */
+	controller_write8(mmio, SMBHSTDAT0, val);
+
+	/* set the device I'm talking to */
+	controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0);
+
+	byte = controller_read8(mmio, SMBHSTCTRL);
+	byte &= ~SMBHST_CTRL_MODE_BITS;			/* Clear [4:2] */
+	byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW;	/* set mode, start */
+	controller_write8(mmio, SMBHSTCTRL, byte);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(mmio) < 0)
+		return -3;	/* timeout or error */
+
+	return 0;
+}
+
+int do_smbus_read_byte(u32 mmio, u8 device, u8 address)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(mmio) < 0)
+		return -2;	/* not ready */
+
+	/* set the command/address... */
+	controller_write8(mmio, SMBHSTCMD, address & 0xff);
+
+	/* set the device I'm talking to */
+	controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1);
+
+	byte = controller_read8(mmio, SMBHSTCTRL);
+	byte &= ~SMBHST_CTRL_MODE_BITS;			/* Clear [4:2] */
+	byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW;	/* set mode, start */
+	controller_write8(mmio, SMBHSTCTRL, byte);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(mmio) < 0)
+		return -3;	/* timeout or error */
+
+	/* read results of transaction */
+	byte = controller_read8(mmio, SMBHSTDAT0);
+
+	return byte;
+}
+
+int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val)
+{
+	u8 byte;
+
+	if (smbus_wait_until_ready(mmio) < 0)
+		return -2;	/* not ready */
+
+	/* set the command/address... */
+	controller_write8(mmio, SMBHSTCMD, address & 0xff);
+
+	/* set the device I'm talking to */
+	controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0);
+
+	/* output value */
+	controller_write8(mmio, SMBHSTDAT0, val);
+
+	byte = controller_read8(mmio, SMBHSTCTRL);
+	byte &= ~SMBHST_CTRL_MODE_BITS;			/* Clear [4:2] */
+	byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW;	/* set mode, start */
+	controller_write8(mmio, SMBHSTCTRL, byte);
+
+	/* poll for transaction completion */
+	if (smbus_wait_until_done(mmio) < 0)
+		return -3;	/* timeout or error */
+
+	return 0;
+}
diff --git a/src/soc/amd/picasso/smbus_spd.c b/src/soc/amd/picasso/smbus_spd.c
new file mode 100644
index 0000000..e57ecde
--- /dev/null
+++ b/src/soc/amd/picasso/smbus_spd.c
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012, 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <amdblocks/agesawrapper.h>
+#include <console/console.h>
+#include <device/pci_def.h>
+#include <device/device.h>
+#include <soc/southbridge.h>
+#include <soc/smbus.h>
+#include <amdblocks/dimm_spd.h>
+
+/*
+ * readspd - Read one or more SPD bytes from a DIMM.
+ *           Start with offset zero and read sequentially.
+ *           Optimization relies on autoincrement to avoid
+ *           sending offset for every byte.
+ *          Reads 128 bytes in 7-8 ms at 400 KHz.
+ */
+static int readspd(uint8_t SmbusSlaveAddress, char *buffer, size_t count)
+{
+	uint8_t dev_addr;
+	size_t index;
+	int error;
+	char *pbuf = buffer;
+
+	printk(BIOS_SPEW, "-------------READING SPD-----------\n");
+	printk(BIOS_SPEW, "SmbusSlave: 0x%08X, count: %zd\n",
+					SmbusSlaveAddress, count);
+
+	/*
+	 * Convert received device address to the format accepted by
+	 * do_smbus_read_byte and do_smbus_recv_byte.
+	 */
+	dev_addr = (SmbusSlaveAddress >> 1);
+
+	/* Read the first SPD byte */
+	error = do_smbus_read_byte(ACPIMMIO_SMBUS_BASE, dev_addr, 0);
+	if (error < 0) {
+		printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
+		return error;
+	}
+	*pbuf = (char) error;
+	pbuf++;
+
+	/* Read the remaining SPD bytes using do_smbus_recv_byte for speed */
+	for (index = 1 ; index < count ; index++) {
+		error = do_smbus_recv_byte(ACPIMMIO_SMBUS_BASE, dev_addr);
+		if (error < 0) {
+			printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
+			return error;
+		}
+		*pbuf = (char) error;
+		pbuf++;
+	}
+	printk(BIOS_SPEW, "\n");
+	printk(BIOS_SPEW, "-------------FINISHED READING SPD-----------\n");
+
+	return 0;
+}
+
+int sb_read_spd(uint8_t spdAddress, char *buf, size_t len)
+{
+	return readspd(spdAddress, buf, len);
+}
diff --git a/src/soc/amd/picasso/smi.c b/src/soc/amd/picasso/smi.c
new file mode 100644
index 0000000..4a0d833
--- /dev/null
+++ b/src/soc/amd/picasso/smi.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ *
+ * 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, 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.
+ */
+
+/*
+ * Utilities for SMM setup
+ */
+
+#include <console/console.h>
+#include <amdblocks/acpimmio.h>
+#include <soc/southbridge.h>
+#include <soc/smi.h>
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+	printk(BIOS_DEBUG, "%s STUB!!!\n", __func__);
+}
+
+/** Set the EOS bit and enable SMI generation from southbridge */
+void enable_smi_generation(void)
+{
+	uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
+	reg &= ~SMITRG0_SMIENB;	/* Enable SMI generation */
+	reg |= SMITRG0_EOS;	/* Set EOS bit */
+	smi_write32(SMI_REG_SMITRIG0, reg);
+}
diff --git a/src/soc/amd/picasso/smi_util.c b/src/soc/amd/picasso/smi_util.c
new file mode 100644
index 0000000..8759e2a
--- /dev/null
+++ b/src/soc/amd/picasso/smi_util.c
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ *
+ * 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, 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.
+ */
+
+/*
+ * SMM utilities used in both SMM and normal mode
+ */
+
+#include <console/console.h>
+#include <soc/southbridge.h>
+#include <soc/smi.h>
+#include <amdblocks/acpimmio.h>
+
+void configure_smi(uint8_t smi_num, uint8_t mode)
+{
+	uint8_t reg32_offset, bit_offset;
+	uint32_t reg32;
+
+	if (smi_num >= NUMBER_SMITYPES) {
+		printk(BIOS_WARNING, "BUG: Invalid SMI: %u\n", smi_num);
+		return;
+	}
+
+	/* 16 sources per register, 2 bits per source; registers are 4 bytes */
+	reg32_offset = (smi_num / 16) * 4;
+	bit_offset = (smi_num % 16) * 2;
+
+	reg32 = smi_read32(SMI_REG_CONTROL0 + reg32_offset);
+	reg32 &= ~(0x3 << (bit_offset));
+	reg32 |= (mode & 0x3) << bit_offset;
+	smi_write32(SMI_REG_CONTROL0 + reg32_offset, reg32);
+}
+
+/**
+ * Configure generation of interrupts for given GEVENT pin
+ *
+ * @param gevent The GEVENT pin number. Valid values are 0 thru 23
+ * @param mode The type of event this pin should generate. Note that only
+ *	       SMI_MODE_SMI generates an SMI. SMI_MODE_DISABLE disables events.
+ * @param level SMI__SCI_LVL_LOW or SMI_SCI_LVL_HIGH
+ */
+void configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
+{
+	uint32_t reg32;
+	/* GEVENT pins range from [0:23] */
+	if (gevent >= SMI_GEVENTS) {
+		printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
+		return;
+	}
+
+	/* SMI0 source is GEVENT0 and so on */
+	configure_smi(gevent, mode);
+
+	/* And set set the trigger level */
+	reg32 = smi_read32(SMI_REG_SMITRIG0);
+	reg32 &= ~(1 << gevent);
+	reg32 |= (level & 0x1) << gevent;
+	smi_write32(SMI_REG_SMITRIG0, reg32);
+}
+
+/**
+ * Configure generation of SCIs.
+ */
+void configure_scimap(const struct sci_source *sci)
+{
+	uint32_t reg32;
+
+	/* GEVENT pins range */
+	if (sci->scimap >= SCIMAPS) {
+		printk(BIOS_WARNING, "BUG: Invalid SCIMAP: %u\n",
+			sci->scimap);
+		return;
+	}
+
+	/* GPEs range from [0:31] */
+	if (sci->gpe >= SCI_GPES) {
+		printk(BIOS_WARNING, "BUG: Invalid SCI GPE: %u\n", sci->gpe);
+		return;
+	}
+
+	printk(BIOS_DEBUG, "SCIMAP %u maps to GPE %u (active %s, %s trigger)\n",
+		sci->scimap, sci->gpe,
+		(!!sci->direction) ? "high" : "low",
+		(!!sci->level) ? "level" : "edge");
+
+	/* Map Gevent to SCI GPE# */
+	smi_write8(SMI_SCI_MAP(sci->scimap), sci->gpe);
+
+	/* Set the trigger direction (high/low) */
+	reg32 = smi_read32(SMI_SCI_TRIG);
+	reg32 &= ~(1 << sci->gpe);
+	reg32 |= !!sci->direction << sci->gpe;
+	smi_write32(SMI_SCI_TRIG, reg32);
+
+	/* Set the trigger level (edge/level) */
+	reg32 = smi_read32(SMI_SCI_LEVEL);
+	reg32 &= ~(1 << sci->gpe);
+	reg32 |= !!sci->level << sci->gpe;
+	smi_write32(SMI_SCI_LEVEL, reg32);
+}
+
+void gpe_configure_sci(const struct sci_source *scis, size_t num_gpes)
+{
+	size_t i;
+
+	for (i = 0; i < num_gpes; i++)
+		configure_scimap(scis + i);
+}
+
+/** Disable events from given GEVENT pin */
+void disable_gevent_smi(uint8_t gevent)
+{
+	/* GEVENT pins range from [0:23] */
+	if (gevent > 23) {
+		printk(BIOS_WARNING, "BUG: Invalid GEVENT: %u\n", gevent);
+		return;
+	}
+
+	/* SMI0 source is GEVENT0 and so on */
+	configure_smi(gevent, SMI_MODE_DISABLE);
+}
+
+uint16_t pm_acpi_smi_cmd_port(void)
+{
+	return pm_read16(PM_ACPI_SMI_CMD);
+}
diff --git a/src/soc/amd/picasso/smihandler.c b/src/soc/amd/picasso/smihandler.c
new file mode 100644
index 0000000..d8438bb
--- /dev/null
+++ b/src/soc/amd/picasso/smihandler.c
@@ -0,0 +1,287 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ *
+ * 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, 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.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <cpu/x86/cache.h>
+#include <arch/acpi.h>
+#include <arch/hlt.h>
+#include <device/pci_def.h>
+#include <soc/smi.h>
+#include <soc/southbridge.h>
+#include <amdblocks/acpimmio.h>
+#include <amdblocks/acpi.h>
+#include <elog.h>
+
+/* bits in smm_io_trap   */
+#define SMM_IO_TRAP_PORT_OFFSET		16
+#define SMM_IO_TRAP_PORT_ADDRESS_MASK	0xffff
+#define SMM_IO_TRAP_RW			(1 << 0)
+#define SMM_IO_TRAP_VALID		(1 << 1)
+
+static inline u16 get_io_address(u32 info)
+{
+	return ((info >> SMM_IO_TRAP_PORT_OFFSET) &
+		SMM_IO_TRAP_PORT_ADDRESS_MASK);
+}
+
+static void *find_save_state(int cmd)
+{
+	int core;
+	amd64_smm_state_save_area_t *state;
+	u32 smm_io_trap;
+	u8 reg_al;
+
+	/* Check all nodes looking for the one that issued the IO */
+	for (core = 0; core < CONFIG_MAX_CPUS; core++) {
+		state = smm_get_save_state(core);
+		smm_io_trap = state->smm_io_trap_offset;
+		/* Check for Valid IO Trap Word (bit1==1) */
+		if (!(smm_io_trap & SMM_IO_TRAP_VALID))
+			continue;
+		/* Make sure it was a write (bit0==0) */
+		if (smm_io_trap & SMM_IO_TRAP_RW)
+			continue;
+		/* Check for APMC IO port */
+		if (pm_acpi_smi_cmd_port() != get_io_address(smm_io_trap))
+			continue;
+		/* Check AL against the requested command */
+		reg_al = state->rax;
+		if (reg_al == cmd)
+			return state;
+	}
+	return NULL;
+}
+
+static void southbridge_smi_gsmi(void)
+{
+	u8 sub_command;
+	amd64_smm_state_save_area_t *io_smi;
+	u32 reg_ebx;
+
+	io_smi = find_save_state(APM_CNT_ELOG_GSMI);
+	if (!io_smi)
+		return;
+	/* Command and return value in EAX */
+	sub_command = (io_smi->rax >> 8) & 0xff;
+
+	/* Parameter buffer in EBX */
+	reg_ebx = io_smi->rbx;
+
+	/* drivers/elog/gsmi.c */
+	io_smi->rax = gsmi_exec(sub_command, &reg_ebx);
+}
+
+static void sb_apmc_smi_handler(void)
+{
+	const uint8_t cmd = inb(pm_acpi_smi_cmd_port());
+
+	switch (cmd) {
+	case APM_CNT_ACPI_ENABLE:
+		acpi_enable_sci();
+		break;
+	case APM_CNT_ACPI_DISABLE:
+		acpi_disable_sci();
+		break;
+	case APM_CNT_ELOG_GSMI:
+		if (CONFIG(ELOG_GSMI))
+			southbridge_smi_gsmi();
+		break;
+	}
+
+	mainboard_smi_apmc(cmd);
+}
+
+static void disable_all_smi_status(void)
+{
+	smi_write32(SMI_SCI_STATUS, smi_read32(SMI_SCI_STATUS));
+	smi_write32(SMI_EVENT_STATUS, smi_read32(SMI_EVENT_STATUS));
+	smi_write32(SMI_REG_SMISTS0, smi_read32(SMI_REG_SMISTS0));
+	smi_write32(SMI_REG_SMISTS1, smi_read32(SMI_REG_SMISTS1));
+	smi_write32(SMI_REG_SMISTS2, smi_read32(SMI_REG_SMISTS2));
+	smi_write32(SMI_REG_SMISTS3, smi_read32(SMI_REG_SMISTS3));
+	smi_write32(SMI_REG_SMISTS4, smi_read32(SMI_REG_SMISTS4));
+}
+
+static void sb_slp_typ_handler(void)
+{
+	uint32_t pci_ctrl, reg32;
+	uint16_t pm1cnt, reg16;
+	uint8_t slp_typ, rst_ctrl;
+
+	/* Figure out SLP_TYP */
+	pm1cnt = acpi_read16(MMIO_ACPI_PM1_CNT_BLK);
+	printk(BIOS_SPEW, "SMI#: SLP = 0x%04x\n", pm1cnt);
+	slp_typ = acpi_sleep_from_pm1(pm1cnt);
+
+	/* Do any mainboard sleep handling */
+	mainboard_smi_sleep(slp_typ);
+
+	switch (slp_typ) {
+	case ACPI_S0:
+		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
+		break;
+	case ACPI_S3:
+		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+		break;
+	case ACPI_S4:
+		printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
+		break;
+	case ACPI_S5:
+		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+		break;
+	default:
+		printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
+		break;
+	}
+
+	if (slp_typ >= ACPI_S3) {
+		/* Sleep Type Elog S3, S4, and S5 entry */
+		if (CONFIG(ELOG_GSMI))
+			elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
+
+		wbinvd();
+
+		disable_all_smi_status();
+
+		/* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */
+		pci_ctrl = pm_read32(PM_PCI_CTRL);
+		pci_ctrl &= ~FORCE_SLPSTATE_RETRY;
+		pci_ctrl |= FORCE_STPCLK_RETRY;
+		pm_write32(PM_PCI_CTRL, pci_ctrl);
+
+		/* Enable SlpTyp */
+		rst_ctrl = pm_read8(PM_RST_CTRL1);
+		rst_ctrl |= SLPTYPE_CONTROL_EN;
+		pm_write8(PM_RST_CTRL1, rst_ctrl);
+
+		/*
+		 * Before the final command, check if there's pending wake
+		 * event. Read enable first, so that reading the actual status
+		 * is as close as possible to entering S3. The idea is to
+		 * minimize the opportunity for a wake event to happen before
+		 * actually entering S3. If there's a pending wake event, log
+		 * it and continue normal path. S3 will fail and the wake event
+		 * becomes a SCI.
+		 */
+		if (CONFIG(ELOG_GSMI)) {
+			reg16 = acpi_read16(MMIO_ACPI_PM1_EN);
+			reg16 &= acpi_read16(MMIO_ACPI_PM1_STS);
+			if (reg16)
+				elog_add_extended_event(
+						ELOG_SLEEP_PENDING_PM1_WAKE,
+						(u32)reg16);
+
+			reg32 = acpi_read32(MMIO_ACPI_GPE0_EN);
+			reg32 &= acpi_read32(MMIO_ACPI_GPE0_STS);
+			if (reg32)
+				elog_add_extended_event(
+						ELOG_SLEEP_PENDING_GPE0_WAKE,
+						reg32);
+		} /* if (CONFIG(ELOG_GSMI)) */
+
+		/*
+		 * An IO cycle is required to trigger the STPCLK/STPGNT
+		 * handshake when the Pm1 write is reissued.
+		 */
+		outw(pm1cnt | SLP_EN, pm_read16(PM1_CNT_BLK));
+		hlt();
+	}
+}
+
+int southbridge_io_trap_handler(int smif)
+{
+	return 0;
+}
+
+/*
+ * Table of functions supported in the SMI handler.  Note that SMI source setup
+ * in southbridge.c is unrelated to this list.
+ */
+static const struct smi_sources_t smi_sources[] = {
+	{ .type = SMITYPE_SMI_CMD_PORT, .handler = sb_apmc_smi_handler },
+	{ .type = SMITYPE_SLP_TYP, .handler = sb_slp_typ_handler},
+};
+
+static void process_smi_sci(void)
+{
+	const uint32_t status = smi_read32(SMI_SCI_STATUS);
+
+	/* Clear events to prevent re-entering SMI if event isn't handled */
+	smi_write32(SMI_SCI_STATUS, status);
+}
+
+static void *get_source_handler(int source)
+{
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(smi_sources) ; i++)
+		if (smi_sources[i].type == source)
+			return smi_sources[i].handler;
+
+	return NULL;
+}
+
+static void process_smi_sources(uint32_t reg)
+{
+	const uint32_t status = smi_read32(reg);
+	int bit_zero = 32 / sizeof(uint32_t) * (reg - SMI_REG_SMISTS0);
+	void (*source_handler)(void);
+	int i;
+
+	for (i = 0 ; i < 32 ; i++) {
+		if (status & (1 << i)) {
+			source_handler = get_source_handler(i + bit_zero);
+			if (source_handler)
+				source_handler();
+		}
+	}
+
+	if (reg == SMI_REG_SMISTS0)
+		if (status & GEVENT_MASK)
+			/* Gevent[23:0] are assumed to be mainboard-specific */
+			mainboard_smi_gpi(status & GEVENT_MASK);
+
+	/* Clear all events in this register */
+	smi_write32(reg, status);
+}
+
+void southbridge_smi_handler(void)
+{
+	const uint16_t smi_src = smi_read16(SMI_REG_POINTER);
+
+	if (smi_src & SMI_STATUS_SRC_SCI)
+		process_smi_sci();
+	if (smi_src & SMI_STATUS_SRC_0)
+		process_smi_sources(SMI_REG_SMISTS0);
+	if (smi_src & SMI_STATUS_SRC_1)
+		process_smi_sources(SMI_REG_SMISTS1);
+	if (smi_src & SMI_STATUS_SRC_2)
+		process_smi_sources(SMI_REG_SMISTS2);
+	if (smi_src & SMI_STATUS_SRC_3)
+		process_smi_sources(SMI_REG_SMISTS3);
+	if (smi_src & SMI_STATUS_SRC_4)
+		process_smi_sources(SMI_REG_SMISTS4);
+}
+
+void southbridge_smi_set_eos(void)
+{
+	uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
+	reg |= SMITRG0_EOS;
+	smi_write32(SMI_REG_SMITRIG0, reg);
+}
diff --git a/src/soc/amd/picasso/southbridge.c b/src/soc/amd/picasso/southbridge.c
new file mode 100644
index 0000000..45408ea
--- /dev/null
+++ b/src/soc/amd/picasso/southbridge.c
@@ -0,0 +1,675 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010-2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <device/mmio.h>
+#include <bootstate.h>
+#include <cpu/x86/smm.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cbmem.h>
+#include <amdblocks/amd_pci_util.h>
+#include <amdblocks/agesawrapper.h>
+#include <amdblocks/reset.h>
+#include <amdblocks/acpimmio.h>
+#include <amdblocks/lpc.h>
+#include <amdblocks/acpi.h>
+#include <soc/southbridge.h>
+#include <soc/smbus.h>
+#include <soc/smi.h>
+#include <soc/amd_pci_int_defs.h>
+#include <delay.h>
+#include <soc/pci_devs.h>
+#include <agesa_headers.h>
+#include <soc/nvs.h>
+#include <types.h>
+
+/*
+ * Table of devices that need their AOAC registers enabled and waited
+ * upon (usually about .55 milliseconds). Instead of individual delays
+ * waiting for each device to become available, a single delay will be
+ * executed.
+ */
+const static struct stoneyridge_aoac aoac_devs[] = {
+	{ (FCH_AOAC_D3_CONTROL_UART0 + CONFIG_UART_FOR_CONSOLE * 2),
+		(FCH_AOAC_D3_STATE_UART0 + CONFIG_UART_FOR_CONSOLE * 2) },
+	{ FCH_AOAC_D3_CONTROL_AMBA, FCH_AOAC_D3_STATE_AMBA },
+	{ FCH_AOAC_D3_CONTROL_I2C0, FCH_AOAC_D3_STATE_I2C0 },
+	{ FCH_AOAC_D3_CONTROL_I2C1, FCH_AOAC_D3_STATE_I2C1 },
+	{ FCH_AOAC_D3_CONTROL_I2C2, FCH_AOAC_D3_STATE_I2C2 },
+	{ FCH_AOAC_D3_CONTROL_I2C3, FCH_AOAC_D3_STATE_I2C3 }
+};
+
+static int is_sata_config(void)
+{
+	return !((SataNativeIde == CONFIG_STONEYRIDGE_SATA_MODE)
+			|| (SataLegacyIde == CONFIG_STONEYRIDGE_SATA_MODE));
+}
+
+static inline int sb_sata_enable(void)
+{
+	/* True if IDE or AHCI. */
+	return (SataNativeIde == CONFIG_STONEYRIDGE_SATA_MODE) ||
+		(SataAhci == CONFIG_STONEYRIDGE_SATA_MODE);
+}
+
+static inline int sb_ide_enable(void)
+{
+	/* True if IDE or LEGACY IDE. */
+	return (SataNativeIde == CONFIG_STONEYRIDGE_SATA_MODE) ||
+		(SataLegacyIde == CONFIG_STONEYRIDGE_SATA_MODE);
+}
+
+void SetFchResetParams(FCH_RESET_INTERFACE *params)
+{
+	const struct device *dev = pcidev_path_on_root(SATA_DEVFN);
+	params->Xhci0Enable = CONFIG(STONEYRIDGE_XHCI_ENABLE);
+	if (dev && dev->enabled) {
+		params->SataEnable = sb_sata_enable();
+		params->IdeEnable = sb_ide_enable();
+	} else {
+		params->SataEnable = FALSE;
+		params->IdeEnable = FALSE;
+	}
+}
+
+void SetFchEnvParams(FCH_INTERFACE *params)
+{
+	const struct device *dev = pcidev_path_on_root(SATA_DEVFN);
+	params->AzaliaController = AzEnable;
+	params->SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
+	if (dev && dev->enabled) {
+		params->SataEnable = is_sata_config();
+		params->IdeEnable = !params->SataEnable;
+		params->SataIdeMode = (CONFIG_STONEYRIDGE_SATA_MODE ==
+					SataLegacyIde);
+	} else {
+		params->SataEnable = FALSE;
+		params->IdeEnable = FALSE;
+		params->SataIdeMode = FALSE;
+	}
+}
+
+void SetFchMidParams(FCH_INTERFACE *params)
+{
+	SetFchEnvParams(params);
+}
+
+/*
+ * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
+ * provides a visible association with the index, therefore helping
+ * maintainability of table. If a new index/name is defined in
+ * amd_pci_int_defs.h, just add the pair at the end of this table.
+ * Order is not important.
+ */
+const static struct irq_idx_name irq_association[] = {
+	{ PIRQ_A,	"INTA#" },
+	{ PIRQ_B,	"INTB#" },
+	{ PIRQ_C,	"INTC#" },
+	{ PIRQ_D,	"INTD#" },
+	{ PIRQ_E,	"INTE#" },
+	{ PIRQ_F,	"INTF#" },
+	{ PIRQ_G,	"INTG#" },
+	{ PIRQ_H,	"INTH#" },
+	{ PIRQ_MISC,	"Misc" },
+	{ PIRQ_MISC0,	"Misc0" },
+	{ PIRQ_MISC1,	"Misc1" },
+	{ PIRQ_MISC2,	"Misc2" },
+	{ PIRQ_SIRQA,	"Ser IRQ INTA" },
+	{ PIRQ_SIRQB,	"Ser IRQ INTB" },
+	{ PIRQ_SIRQC,	"Ser IRQ INTC" },
+	{ PIRQ_SIRQD,	"Ser IRQ INTD" },
+	{ PIRQ_SCI,	"SCI" },
+	{ PIRQ_SMBUS,	"SMBUS" },
+	{ PIRQ_ASF,	"ASF" },
+	{ PIRQ_HDA,	"HDA" },
+	{ PIRQ_FC,	"FC" },
+	{ PIRQ_PMON,	"PerMon" },
+	{ PIRQ_SD,	"SD" },
+	{ PIRQ_SDIO,	"SDIOt" },
+	{ PIRQ_EHCI,	"EHCI" },
+	{ PIRQ_XHCI,	"XHCI" },
+	{ PIRQ_SATA,	"SATA" },
+	{ PIRQ_GPIO,	"GPIO" },
+	{ PIRQ_I2C0,	"I2C0" },
+	{ PIRQ_I2C1,	"I2C1" },
+	{ PIRQ_I2C2,	"I2C2" },
+	{ PIRQ_I2C3,	"I2C3" },
+	{ PIRQ_UART0,	"UART0" },
+	{ PIRQ_UART1,	"UART1" },
+};
+
+const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
+{
+	*size = ARRAY_SIZE(irq_association);
+	return irq_association;
+}
+
+static void power_on_aoac_device(int aoac_device_control_register)
+{
+	uint8_t byte;
+
+	/* Power on the UART and AMBA devices */
+	byte = aoac_read8(aoac_device_control_register);
+	byte |= FCH_AOAC_PWR_ON_DEV;
+	aoac_write8(aoac_device_control_register, byte);
+}
+
+static bool is_aoac_device_enabled(int aoac_device_status_register)
+{
+	uint8_t byte;
+
+	byte = aoac_read8(aoac_device_status_register);
+	byte &= (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE);
+	if (byte == (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE))
+		return true;
+	else
+		return false;
+}
+
+void enable_aoac_devices(void)
+{
+	bool status;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(aoac_devs); i++)
+		power_on_aoac_device(aoac_devs[i].enable);
+
+	/* Wait for AOAC devices to indicate power and clock OK */
+	do {
+		udelay(100);
+		status = true;
+		for (i = 0; i < ARRAY_SIZE(aoac_devs); i++)
+			status &= is_aoac_device_enabled(aoac_devs[i].status);
+	} while (!status);
+}
+
+static void sb_enable_lpc(void)
+{
+	u8 byte;
+
+	/* Enable LPC controller */
+	byte = pm_io_read8(PM_LPC_GATING);
+	byte |= PM_LPC_ENABLE;
+	pm_io_write8(PM_LPC_GATING, byte);
+}
+
+static void sb_lpc_decode(void)
+{
+	u32 tmp = 0;
+
+	/* Enable I/O decode to LPC bus */
+	tmp = DECODE_ENABLE_PARALLEL_PORT0 | DECODE_ENABLE_PARALLEL_PORT2
+		| DECODE_ENABLE_PARALLEL_PORT4 | DECODE_ENABLE_SERIAL_PORT0
+		| DECODE_ENABLE_SERIAL_PORT1 | DECODE_ENABLE_SERIAL_PORT2
+		| DECODE_ENABLE_SERIAL_PORT3 | DECODE_ENABLE_SERIAL_PORT4
+		| DECODE_ENABLE_SERIAL_PORT5 | DECODE_ENABLE_SERIAL_PORT6
+		| DECODE_ENABLE_SERIAL_PORT7 | DECODE_ENABLE_AUDIO_PORT0
+		| DECODE_ENABLE_AUDIO_PORT1 | DECODE_ENABLE_AUDIO_PORT2
+		| DECODE_ENABLE_AUDIO_PORT3 | DECODE_ENABLE_MSS_PORT2
+		| DECODE_ENABLE_MSS_PORT3 | DECODE_ENABLE_FDC_PORT0
+		| DECODE_ENABLE_FDC_PORT1 | DECODE_ENABLE_GAME_PORT
+		| DECODE_ENABLE_KBC_PORT | DECODE_ENABLE_ACPIUC_PORT
+		| DECODE_ENABLE_ADLIB_PORT;
+
+	/* Decode SIOs at 2E/2F and 4E/4F */
+	if (CONFIG(STONEYRIDGE_LEGACY_FREE))
+		tmp |= DECODE_ALTERNATE_SIO_ENABLE | DECODE_SIO_ENABLE;
+
+	lpc_enable_decode(tmp);
+}
+
+static void sb_enable_cf9_io(void)
+{
+	uint32_t reg = pm_read32(PM_DECODE_EN);
+
+	pm_write32(PM_DECODE_EN, reg | CF9_IO_EN);
+}
+
+static void sb_enable_legacy_io(void)
+{
+	uint32_t reg = pm_read32(PM_DECODE_EN);
+
+	pm_write32(PM_DECODE_EN, reg | LEGACY_IO_EN);
+}
+
+void sb_clk_output_48Mhz(u32 osc)
+{
+	u32 ctrl;
+
+	/*
+	 * Clear the disable for OSCOUT1 (signal typically named XnnM_25M_48M)
+	 * or OSCOUT2 (USBCLK/25M_48M_OSC).  The frequency defaults to 48MHz.
+	 */
+	ctrl = misc_read32(MISC_CLK_CNTL1);
+
+	switch (osc) {
+	case 1:
+		ctrl &= ~OSCOUT1_CLK_OUTPUT_ENB;
+		break;
+	case 2:
+		ctrl &= ~OSCOUT2_CLK_OUTPUT_ENB;
+		break;
+	default:
+		return; /* do nothing if invalid */
+	}
+	misc_write32(MISC_CLK_CNTL1, ctrl);
+}
+
+static uintptr_t sb_init_spi_base(void)
+{
+	uintptr_t base;
+
+	/* Make sure the base address is predictable */
+	base = lpc_get_spibase();
+
+	if (base)
+		return base;
+
+	lpc_set_spibase(SPI_BASE_ADDRESS, SPI_ROM_ENABLE);
+	return SPI_BASE_ADDRESS;
+}
+
+void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
+{
+	uintptr_t base = sb_init_spi_base();
+	write16((void *)(base + SPI100_SPEED_CONFIG),
+				(norm << SPI_NORM_SPEED_NEW_SH) |
+				(fast << SPI_FAST_SPEED_NEW_SH) |
+				(alt << SPI_ALT_SPEED_NEW_SH) |
+				(tpm << SPI_TPM_SPEED_NEW_SH));
+	write16((void *)(base + SPI100_ENABLE), SPI_USE_SPI100);
+}
+
+void sb_disable_4dw_burst(void)
+{
+	uintptr_t base = sb_init_spi_base();
+	write16((void *)(base + SPI100_HOST_PREF_CONFIG),
+			read16((void *)(base + SPI100_HOST_PREF_CONFIG))
+					& ~SPI_RD4DW_EN_HOST);
+}
+
+void sb_read_mode(u32 mode)
+{
+	uintptr_t base = sb_init_spi_base();
+	write32((void *)(base + SPI_CNTRL0),
+			(read32((void *)(base + SPI_CNTRL0))
+					& ~SPI_READ_MODE_MASK) | mode);
+}
+
+static void setup_spread_spectrum(int *reboot)
+{
+	uint16_t rstcfg = pm_read16(PWR_RESET_CFG);
+
+	rstcfg &= ~TOGGLE_ALL_PWR_GOOD;
+	pm_write16(PWR_RESET_CFG, rstcfg);
+
+	uint32_t cntl1 = misc_read32(MISC_CLK_CNTL1);
+
+	if (cntl1 & CG1PLL_FBDIV_TEST) {
+		printk(BIOS_DEBUG, "Spread spectrum is ready\n");
+		misc_write32(MISC_CGPLL_CONFIG1,
+			     misc_read32(MISC_CGPLL_CONFIG1) |
+				     CG1PLL_SPREAD_SPECTRUM_ENABLE);
+
+		return;
+	}
+
+	printk(BIOS_DEBUG, "Setting up spread spectrum\n");
+
+	uint32_t cfg6 = misc_read32(MISC_CGPLL_CONFIG6);
+	cfg6 &= ~CG1PLL_LF_MODE_MASK;
+	cfg6 |= (0x0f8 << CG1PLL_LF_MODE_SHIFT) & CG1PLL_LF_MODE_MASK;
+	misc_write32(MISC_CGPLL_CONFIG6, cfg6);
+
+	uint32_t cfg3 = misc_read32(MISC_CGPLL_CONFIG3);
+	cfg3 &= ~CG1PLL_REFDIV_MASK;
+	cfg3 |= (0x003 << CG1PLL_REFDIV_SHIFT) & CG1PLL_REFDIV_MASK;
+	cfg3 &= ~CG1PLL_FBDIV_MASK;
+	cfg3 |= (0x04b << CG1PLL_FBDIV_SHIFT) & CG1PLL_FBDIV_MASK;
+	misc_write32(MISC_CGPLL_CONFIG3, cfg3);
+
+	uint32_t cfg5 = misc_read32(MISC_CGPLL_CONFIG5);
+	cfg5 &= ~SS_AMOUNT_NFRAC_SLIP_MASK;
+	cfg5 |= (0x2 << SS_AMOUNT_NFRAC_SLIP_SHIFT) & SS_AMOUNT_NFRAC_SLIP_MASK;
+	misc_write32(MISC_CGPLL_CONFIG5, cfg5);
+
+	uint32_t cfg4 = misc_read32(MISC_CGPLL_CONFIG4);
+	cfg4 &= ~SS_AMOUNT_DSFRAC_MASK;
+	cfg4 |= (0xd000 << SS_AMOUNT_DSFRAC_SHIFT) & SS_AMOUNT_DSFRAC_MASK;
+	cfg4 &= ~SS_STEP_SIZE_DSFRAC_MASK;
+	cfg4 |= (0x02d5 << SS_STEP_SIZE_DSFRAC_SHIFT)
+						& SS_STEP_SIZE_DSFRAC_MASK;
+	misc_write32(MISC_CGPLL_CONFIG4, cfg4);
+
+	rstcfg |= TOGGLE_ALL_PWR_GOOD;
+	pm_write16(PWR_RESET_CFG, rstcfg);
+
+	cntl1 |= CG1PLL_FBDIV_TEST;
+	misc_write32(MISC_CLK_CNTL1, cntl1);
+
+	*reboot = 1;
+}
+
+static void setup_misc(int *reboot)
+{
+	/* Undocumented register */
+	uint32_t reg = misc_read32(0x50);
+	if (!(reg & BIT(16))) {
+		reg |= BIT(16);
+
+		misc_write32(0x50, reg);
+		*reboot = 1;
+	}
+}
+
+static void fch_smbus_init(void)
+{
+	pm_write8(SMB_ASF_IO_BASE, SMB_BASE_ADDR >> 8);
+	smbus_write8(SMBTIMING, SMB_SPEED_400KHZ);
+	/* Clear all SMBUS status bits */
+	smbus_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR);
+	smbus_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR);
+	asf_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR);
+	asf_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR);
+}
+
+/* Before console init */
+void bootblock_fch_early_init(void)
+{
+	int reboot = 0;
+
+	lpc_enable_rom();
+	sb_enable_lpc();
+	lpc_enable_port80();
+	sb_lpc_decode();
+	lpc_enable_spi_prefetch();
+	sb_init_spi_base();
+	sb_disable_4dw_burst(); /* Must be disabled on CZ(ST) */
+	enable_acpimmio_decode();
+	fch_smbus_init();
+	sb_enable_cf9_io();
+	setup_spread_spectrum(&reboot);
+	setup_misc(&reboot);
+
+	if (reboot)
+		warm_reset();
+
+	sb_enable_legacy_io();
+	enable_aoac_devices();
+}
+
+static void print_num_status_bits(int num_bits, uint32_t status,
+				  const char *const bit_names[])
+{
+	int i;
+
+	if (!status)
+		return;
+
+	for (i = num_bits - 1; i >= 0; i--) {
+		if (status & (1 << i)) {
+			if (bit_names[i])
+				printk(BIOS_DEBUG, "%s ", bit_names[i]);
+			else
+				printk(BIOS_DEBUG, "BIT%d ", i);
+		}
+	}
+}
+
+static void sb_print_pmxc0_status(void)
+{
+	/* PMxC0 S5/Reset Status shows the source of previous reset. */
+	uint32_t pmxc0_status = pm_read32(PM_RST_STATUS);
+
+	static const char *const pmxc0_status_bits[32] = {
+		[0] = "ThermalTrip",
+		[1] = "FourSecondPwrBtn",
+		[2] = "Shutdown",
+		[3] = "ThermalTripFromTemp",
+		[4] = "RemotePowerDownFromASF",
+		[5] = "ShutDownFan0",
+		[16] = "UserRst",
+		[17] = "SoftPciRst",
+		[18] = "DoInit",
+		[19] = "DoReset",
+		[20] = "DoFullReset",
+		[21] = "SleepReset",
+		[22] = "KbReset",
+		[23] = "LtReset",
+		[24] = "FailBootRst",
+		[25] = "WatchdogIssueReset",
+		[26] = "RemoteResetFromASF",
+		[27] = "SyncFlood",
+		[28] = "HangReset",
+		[29] = "EcWatchdogRst",
+	};
+
+	printk(BIOS_DEBUG, "PMxC0 STATUS: 0x%x ", pmxc0_status);
+	print_num_status_bits(ARRAY_SIZE(pmxc0_status_bits), pmxc0_status,
+			      pmxc0_status_bits);
+	printk(BIOS_DEBUG, "\n");
+}
+
+/* After console init */
+void bootblock_fch_init(void)
+{
+	sb_print_pmxc0_status();
+}
+
+void sb_enable(struct device *dev)
+{
+	printk(BIOS_DEBUG, "%s\n", __func__);
+}
+
+static void sb_init_acpi_ports(void)
+{
+	u32 reg;
+
+	/* We use some of these ports in SMM regardless of whether or not
+	 * ACPI tables are generated. Enable these ports indiscriminately.
+	 */
+
+	pm_write16(PM_EVT_BLK, ACPI_PM_EVT_BLK);
+	pm_write16(PM1_CNT_BLK, ACPI_PM1_CNT_BLK);
+	pm_write16(PM_TMR_BLK, ACPI_PM_TMR_BLK);
+	pm_write16(PM_GPE0_BLK, ACPI_GPE0_BLK);
+	/* CpuControl is in \_PR.CP00, 6 bytes */
+	pm_write16(PM_CPU_CTRL, ACPI_CPU_CONTROL);
+
+	if (CONFIG(HAVE_SMI_HANDLER)) {
+		/* APMC - SMI Command Port */
+		pm_write16(PM_ACPI_SMI_CMD, APM_CNT);
+		configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI);
+
+		/* SMI on SlpTyp requires sending SMI before completion
+		 * response of the I/O write.  The BKDG also specifies
+		 * clearing ForceStpClkRetry for SMI trapping.
+		 */
+		reg = pm_read32(PM_PCI_CTRL);
+		reg |= FORCE_SLPSTATE_RETRY;
+		reg &= ~FORCE_STPCLK_RETRY;
+		pm_write32(PM_PCI_CTRL, reg);
+
+		/* Disable SlpTyp feature */
+		reg = pm_read8(PM_RST_CTRL1);
+		reg &= ~SLPTYPE_CONTROL_EN;
+		pm_write8(PM_RST_CTRL1, reg);
+
+		configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI);
+	} else {
+		pm_write16(PM_ACPI_SMI_CMD, 0);
+	}
+
+	/* Decode ACPI registers and enable standard features */
+	pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD |
+				PM_ACPI_GLOBAL_EN |
+				PM_ACPI_RTC_EN_EN |
+				PM_ACPI_TIMER_EN_EN);
+}
+
+static int get_index_bit(uint32_t value, uint16_t limit)
+{
+	uint16_t i;
+	uint32_t t;
+
+	if (limit >= TOTAL_BITS(uint32_t))
+		return -1;
+
+	/* get a mask of valid bits. Ex limit = 3, set bits 0-2 */
+	t = (1 << limit) - 1;
+	if ((value & t) == 0)
+		return -1;
+	t = 1;
+	for (i = 0; i < limit; i++) {
+		if (value & t)
+			break;
+		t <<= 1;
+	}
+	return i;
+}
+
+static void set_nvs_sws(void *unused)
+{
+	struct soc_power_reg *sws;
+	struct global_nvs_t *gnvs;
+	int index;
+
+	sws = cbmem_find(CBMEM_ID_POWER_STATE);
+	if (sws == NULL)
+		return;
+	gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+	if (gnvs == NULL)
+		return;
+
+	index = get_index_bit(sws->pm1_sts & sws->pm1_en, PM1_LIMIT);
+	if (index < 0)
+		gnvs->pm1i = ~0ULL;
+	else
+		gnvs->pm1i = index;
+
+	index = get_index_bit(sws->gpe0_sts & sws->gpe0_en, GPE0_LIMIT);
+	if (index < 0)
+		gnvs->gpei = ~0ULL;
+	else
+		gnvs->gpei = index;
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, set_nvs_sws, NULL);
+
+void southbridge_init(void *chip_info)
+{
+	sb_init_acpi_ports();
+	acpi_clear_pm1_status();
+}
+
+static void set_sb_final_nvs(void)
+{
+	uintptr_t amdfw_rom;
+	uintptr_t xhci_fw;
+	uintptr_t fwaddr;
+	size_t fwsize;
+	const struct device *sd, *sata;
+
+	struct global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+	if (gnvs == NULL)
+		return;
+
+	gnvs->aoac.ic0e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_I2C0);
+	gnvs->aoac.ic1e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_I2C1);
+	gnvs->aoac.ic2e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_I2C2);
+	gnvs->aoac.ic3e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_I2C3);
+	gnvs->aoac.ut0e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_UART0);
+	gnvs->aoac.ut1e = is_aoac_device_enabled(FCH_AOAC_D3_STATE_UART1);
+	gnvs->aoac.ehce = is_aoac_device_enabled(FCH_AOAC_D3_STATE_USB2);
+	gnvs->aoac.xhce = is_aoac_device_enabled(FCH_AOAC_D3_STATE_USB3);
+	/* Rely on these being in sync with devicetree */
+	sd = pcidev_path_on_root(SD_DEVFN);
+	gnvs->aoac.sd_e = sd && sd->enabled ? 1 : 0;
+	sata = pcidev_path_on_root(SATA_DEVFN);
+	gnvs->aoac.st_e = sata && sata->enabled ? 1 : 0;
+	gnvs->aoac.espi = 1;
+
+	amdfw_rom = 0x20000 - (0x80000 << CONFIG_AMD_FWM_POSITION_INDEX);
+	xhci_fw = read32((void *)(amdfw_rom + XHCI_FW_SIG_OFFSET));
+
+	fwaddr = 2 + read16((void *)(xhci_fw + XHCI_FW_ADDR_OFFSET
+			+ XHCI_FW_BOOTRAM_SIZE));
+	fwsize = read16((void *)(xhci_fw + XHCI_FW_SIZE_OFFSET
+			+ XHCI_FW_BOOTRAM_SIZE));
+	gnvs->fw00 = 0;
+	gnvs->fw01 = ((32 * KiB) << 16) + 0;
+	gnvs->fw02 = fwaddr + XHCI_FW_BOOTRAM_SIZE;
+	gnvs->fw03 = fwsize << 16;
+
+	gnvs->eh10 = pci_read_config32(SOC_EHCI1_DEV, PCI_BASE_ADDRESS_0)
+			& ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
+}
+
+void southbridge_final(void *chip_info)
+{
+	uint8_t restored_power = PM_S5_AT_POWER_RECOVERY;
+
+	if (CONFIG(MAINBOARD_POWER_RESTORE))
+		restored_power = PM_RESTORE_S0_IF_PREV_S0;
+	pm_write8(PM_RTC_SHADOW, restored_power);
+
+	set_sb_final_nvs();
+}
+
+/*
+ * Update the PCI devices with a valid IRQ number
+ * that is set in the mainboard PCI_IRQ structures.
+ */
+static void set_pci_irqs(void *unused)
+{
+	/* Write PCI_INTR regs 0xC00/0xC01 */
+	write_pci_int_table();
+
+	/* Write IRQs for all devicetree enabled devices */
+	write_pci_cfg_irqs();
+}
+
+/*
+ * Hook this function into the PCI state machine
+ * on entry into BS_DEV_ENABLE.
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL);
+
+void save_uma_size(uint32_t size)
+{
+	biosram_write32(BIOSRAM_UMA_SIZE, size);
+}
+
+void save_uma_base(uint64_t base)
+{
+	biosram_write32(BIOSRAM_UMA_BASE, (uint32_t) base);
+	biosram_write32(BIOSRAM_UMA_BASE + 4, (uint32_t) (base >> 32));
+}
+
+uint32_t get_uma_size(void)
+{
+	return biosram_read32(BIOSRAM_UMA_SIZE);
+}
+
+uint64_t get_uma_base(void)
+{
+	uint64_t base;
+	base = biosram_read32(BIOSRAM_UMA_BASE);
+	base |= ((uint64_t)(biosram_read32(BIOSRAM_UMA_BASE + 4)) << 32);
+	return base;
+}
diff --git a/src/soc/amd/picasso/spi.c b/src/soc/amd/picasso/spi.c
new file mode 100644
index 0000000..8abfa16
--- /dev/null
+++ b/src/soc/amd/picasso/spi.c
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <device/mmio.h>
+#include <lib.h>
+#include <timer.h>
+#include <console/console.h>
+#include <commonlib/helpers.h>
+#include <spi_flash.h>
+#include <spi-generic.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <soc/southbridge.h>
+#include <amdblocks/lpc.h>
+#include <soc/pci_devs.h>
+
+#define SPI_DEBUG_DRIVER CONFIG(DEBUG_SPI_FLASH)
+
+static uintptr_t spibar;
+
+static void set_spibar(uintptr_t base)
+{
+	spibar = base;
+}
+
+static inline uint8_t spi_read8(uint8_t reg)
+{
+	return read8((void *)(spibar + reg));
+}
+
+static inline uint32_t spi_read32(uint8_t reg)
+{
+	return read32((void *)(spibar + reg));
+}
+
+static inline void spi_write8(uint8_t reg, uint8_t val)
+{
+	write8((void *)(spibar + reg), val);
+}
+
+static inline void spi_write32(uint8_t reg, uint32_t val)
+{
+	write32((void *)(spibar + reg), val);
+}
+
+static void dump_state(const char *str)
+{
+	if (!SPI_DEBUG_DRIVER)
+		return;
+
+	printk(BIOS_DEBUG, "SPI: %s\n", str);
+	printk(BIOS_DEBUG, "Cntrl0: %x\n", spi_read32(SPI_CNTRL0));
+	printk(BIOS_DEBUG, "Status: %x\n", spi_read32(SPI_STATUS));
+	printk(BIOS_DEBUG, "TxByteCount: %x\n", spi_read8(SPI_TX_BYTE_COUNT));
+	printk(BIOS_DEBUG, "RxByteCount: %x\n", spi_read8(SPI_RX_BYTE_COUNT));
+	printk(BIOS_DEBUG, "CmdCode: %x\n", spi_read8(SPI_CMD_CODE));
+	hexdump((void *)(spibar + SPI_FIFO), SPI_FIFO_DEPTH);
+}
+
+static int wait_for_ready(void)
+{
+	const uint32_t timeout_ms = 500;
+	struct stopwatch sw;
+
+	stopwatch_init_msecs_expire(&sw, timeout_ms);
+
+	do {
+		if (!(spi_read32(SPI_STATUS) & SPI_BUSY))
+			return 0;
+	} while (!stopwatch_expired(&sw));
+
+	return -1;
+}
+
+static int execute_command(void)
+{
+	dump_state("Before Execute");
+
+	spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE);
+
+	if (wait_for_ready())
+		printk(BIOS_DEBUG,
+			"FCH SPI Error: Timeout executing command\n");
+
+	dump_state("Transaction finished");
+
+	return 0;
+}
+
+void spi_init(void)
+{
+	set_spibar(lpc_get_spibase());
+}
+
+static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
+		size_t bytesout, void *din, size_t bytesin)
+{
+	size_t count;
+	uint8_t cmd;
+	uint8_t *bufin = din;
+	const uint8_t *bufout = dout;
+
+	if (SPI_DEBUG_DRIVER)
+		printk(BIOS_DEBUG, "%s(%zx, %zx)\n", __func__, bytesout,
+			bytesin);
+
+	/* First byte is cmd which cannot be sent through FIFO */
+	cmd = bufout[0];
+	bufout++;
+	bytesout--;
+
+	/*
+	 * Check if this is a write command attempting to transfer more bytes
+	 * than the controller can handle.  Iterations for writes are not
+	 * supported here because each SPI write command needs to be preceded
+	 * and followed by other SPI commands, and this sequence is controlled
+	 * by the SPI chip driver.
+	 */
+	if (bytesout + bytesin > SPI_FIFO_DEPTH) {
+		printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI"
+				" chip driver use spi_crop_chunk()?\n");
+		return -1;
+	}
+
+	if (wait_for_ready())
+		return -1;
+
+	spi_write8(SPI_CMD_CODE, cmd);
+	spi_write8(SPI_TX_BYTE_COUNT, bytesout);
+	spi_write8(SPI_RX_BYTE_COUNT, bytesin);
+
+	for (count = 0; count < bytesout; count++)
+		spi_write8(SPI_FIFO + count, bufout[count]);
+
+	if (execute_command())
+		return -1;
+
+	for (count = 0; count < bytesin; count++)
+		bufin[count] = spi_read8(SPI_FIFO + count + bytesout);
+
+	return 0;
+}
+
+int chipset_volatile_group_begin(const struct spi_flash *flash)
+{
+	return 0;
+}
+
+int chipset_volatile_group_end(const struct spi_flash *flash)
+{
+	return 0;
+}
+
+static int xfer_vectors(const struct spi_slave *slave,
+			struct spi_op vectors[], size_t count)
+{
+	return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer);
+}
+
+static const struct spi_ctrlr spi_ctrlr = {
+	.xfer_vector = xfer_vectors,
+	.max_xfer_size = SPI_FIFO_DEPTH,
+	.flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN,
+};
+
+const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
+	{
+		.ctrlr = &spi_ctrlr,
+		.bus_start = 0,
+		.bus_end = 0,
+	},
+};
+
+const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
diff --git a/src/soc/amd/picasso/tsc_freq.c b/src/soc/amd/picasso/tsc_freq.c
new file mode 100644
index 0000000..29121b9
--- /dev/null
+++ b/src/soc/amd/picasso/tsc_freq.c
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * Copyright (C) 2017 Advanced Micro Devices
+ *
+ * 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.
+ */
+
+#include <cpu/x86/msr.h>
+#include <cpu/amd/msr.h>
+#include <cpu/x86/tsc.h>
+#include <console/console.h>
+#include <soc/pci_devs.h>
+#include <device/pci_ops.h>
+
+unsigned long tsc_freq_mhz(void)
+{
+	msr_t msr;
+	uint8_t cpufid;
+	uint8_t cpudid;
+	uint8_t boost_states;
+
+	/*
+	 * See the Family 15h Models 70h-7Fh BKDG (PID 55072) definition for
+	 * MSR0000_0010.  The TSC increments at the P0 frequency. According
+	 * to the "Software P-state Numbering" section, P0 is the highest
+	 * non-boosted state.  freq = 100MHz * (CpuFid + 10h) / (2^(CpuDid)).
+	 */
+	boost_states = (pci_read_config32(SOC_PM_DEV, CORE_PERF_BOOST_CTRL)
+			>> 2) & 0x7;
+
+	msr = rdmsr(PSTATE_0_MSR + boost_states);
+	if (!(msr.hi & 0x80000000))
+		die("Unknown error: cannot determine P-state 0\n");
+
+	cpufid = (msr.lo & 0x3f);
+	cpudid = (msr.lo & 0x1c0) >> 6;
+
+	return (100 * (cpufid + 0x10)) / (0x01 << cpudid);
+}
diff --git a/src/soc/amd/picasso/uart.c b/src/soc/amd/picasso/uart.c
new file mode 100644
index 0000000..d5d3006
--- /dev/null
+++ b/src/soc/amd/picasso/uart.c
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <console/uart.h>
+#include <soc/southbridge.h>
+
+uintptr_t uart_platform_base(int idx)
+{
+	if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1)
+		return 0;
+
+	return (uintptr_t)(APU_UART0_BASE + 0x2000 * (idx & 1));
+}
+
+unsigned int uart_platform_refclk(void)
+{
+	return 48000000;
+}
diff --git a/src/soc/amd/picasso/usb.c b/src/soc/amd/picasso/usb.c
new file mode 100644
index 0000000..00f8237
--- /dev/null
+++ b/src/soc/amd/picasso/usb.c
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pci_ehci.h>
+#include <soc/acpi.h>
+#include <soc/pci_devs.h>
+#include <soc/southbridge.h>
+#include <amdblocks/acpimmio.h>
+
+static void set_usb_over_current(struct device *dev)
+{
+	uint16_t map = USB_OC_DISABLE_ALL;
+
+	if (dev->path.pci.devfn == XHCI_DEVFN) {
+		if (mainboard_get_xhci_oc_map(&map) == 0) {
+			xhci_pm_write32(XHCI_PM_INDIRECT_INDEX,
+						XHCI_OVER_CURRENT_CONTROL);
+			xhci_pm_write16(XHCI_PM_INDIRECT_DATA, map);
+		}
+	}
+
+	if (dev->path.pci.devfn == EHCI1_DEVFN) {
+		if (mainboard_get_ehci_oc_map(&map) == 0)
+			pci_write_config16(dev, EHCI_OVER_CURRENT_CONTROL, map);
+	}
+}
+
+int __weak mainboard_get_xhci_oc_map(uint16_t *map)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return -1;
+}
+
+int __weak mainboard_get_ehci_oc_map(uint16_t *map)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return -1;
+}
+
+static struct pci_operations lops_pci = {
+	.set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+	.read_resources = pci_ehci_read_resources,
+	.set_resources = pci_dev_set_resources,
+	.enable_resources = pci_dev_enable_resources,
+	.init = set_usb_over_current,
+	.scan_bus = scan_usb_bus,
+	.acpi_name = soc_acpi_name,
+	.ops_pci = &lops_pci,
+};
+
+static const unsigned short pci_device_ids[] = {
+	PCI_DEVICE_ID_AMD_SB900_USB_18_0,
+	PCI_DEVICE_ID_AMD_SB900_USB_18_2,
+	PCI_DEVICE_ID_AMD_SB900_USB_20_5,
+	PCI_DEVICE_ID_AMD_CZ_USB_0,
+	PCI_DEVICE_ID_AMD_CZ_USB_1,
+	PCI_DEVICE_ID_AMD_CZ_USB3_0,
+	0
+};
+
+static const struct pci_driver usb_0_driver __pci_driver = {
+	.ops = &usb_ops,
+	.vendor = PCI_VENDOR_ID_AMD,
+	.devices = pci_device_ids,
+};