soc: Add AMD Stoney Ridge southbridge code

Copy the Hudson/Kern code from southbridge/amd/pi/hudson.  This
is the first of a series of patches to migrate Stoney Ridge
support from cpu, northbridge, and southbridge to soc/

Changes:
- add soc/amd/stoneyridge and soc/amd/common
- remove all other Husdon versions
- update include paths, etc
- clean up Kconfig and Makefile
- create chip.c to contain chip_ops

Change-Id: Ib88a868e654ad127be70ecc506f6b90b784f8d1b
Signed-off-by: Marc Jones <marcj303@gmail.com>
Reviewed-on: https://review.coreboot.org/19722
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Marc Jones 2017-05-04 21:17:45 -06:00 committed by Martin Roth
parent a0199d8e1a
commit 244848462d
48 changed files with 5008 additions and 1 deletions

View File

@ -0,0 +1,4 @@
config SOC_AMD_COMMON
bool
help
common code for AMD SOCs

View File

@ -0,0 +1,5 @@
ifeq ($(CONFIG_SOC_AMD_COMMON),y)
ramstage-y += amd_pci_util.c
endif

View File

@ -0,0 +1,22 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 Raptor 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 _AMD_SB_DEFS_H_
#define _AMD_SB_DEFS_H_
#define AMD_SB_ACPI_MMIO_ADDR 0xfed80000ul
#endif

View File

@ -0,0 +1,200 @@
/*
* 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.
*/
#include <console/console.h>
#include <device/pci.h>
#include <arch/io.h>
#include <string.h>
#include <amd_pci_util.h>
#include <pc80/i8259.h>
#include <amd_pci_int_defs.h>
#include <amd_pci_int_types.h>
#ifndef __PRE_RAM__
const struct pirq_struct * pirq_data_ptr = NULL;
u32 pirq_data_size = 0;
const u8 * intr_data_ptr = NULL;
const u8 * picr_data_ptr = NULL;
/*
* Read the FCH PCI_INTR registers 0xC00/0xC01 at a
* given index and a given PIC (0) or IOAPIC (1) mode
*/
u8 read_pci_int_idx(u8 index, int mode)
{
outb((mode << 7) | index, PCI_INTR_INDEX);
return inb(PCI_INTR_DATA);
}
/*
* Write a value to the FCH PCI_INTR registers 0xC00/0xC01
* at a given index and PIC (0) or IOAPIC (1) mode
*/
void write_pci_int_idx(u8 index, int mode, u8 data)
{
outb((mode << 7) | index, PCI_INTR_INDEX);
outb(data, PCI_INTR_DATA);
}
/*
* Write the FCH PCI_INTR registers 0xC00/0xC01 with values
* given in global variables intr_data and picr_data.
* These variables are defined in mainboard.c
*/
void write_pci_int_table (void)
{
u8 byte;
if (picr_data_ptr == NULL || intr_data_ptr == NULL){
printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01 registers because\n"
"'mainboard_picr_data' or 'mainboard_intr_data' tables are NULL\n");
return;
}
/* PIC IRQ routine */
printk(BIOS_DEBUG, "PCI_INTR tables: Writing registers C00/C01 for PIC mode PCI IRQ routing:\n"
"\tPCI_INTR_INDEX\t\tPCI_INTR_DATA\n");
for (byte = 0; byte < FCH_INT_TABLE_SIZE; byte++) {
if (intr_types[byte]) {
write_pci_int_idx(byte, 0, (u8) picr_data_ptr[byte]);
printk(BIOS_DEBUG, "\t0x%02X %s\t: 0x%02X\n",
byte, intr_types[byte], read_pci_int_idx(byte, 0));
}
}
/* APIC IRQ routine */
printk(BIOS_DEBUG, "PCI_INTR tables: Writing registers C00/C01 for APIC mode PCI IRQ routing:\n"
"\tPCI_INTR_INDEX\t\tPCI_INTR_DATA\n");
for (byte = 0; byte < FCH_INT_TABLE_SIZE; byte++) {
if (intr_types[byte]) {
write_pci_int_idx(byte, 1, (u8) intr_data_ptr[byte]);
printk(BIOS_DEBUG, "\t0x%02X %s\t: 0x%02X\n",
byte, intr_types[byte], read_pci_int_idx(byte, 1));
}
}
}
/*
* Function to write the PCI config space Interrupt
* registers based on the values given in PCI_INTR
* table at I/O port 0xC00/0xC01
*/
void write_pci_cfg_irqs(void)
{
device_t dev = NULL; /* Our current device to route IRQs to */
device_t target_dev = NULL; /* The bridge that a device may be connected to */
u16 int_pin = 0; /* Value of the INT_PIN register 0x3D */
u16 target_pin = 0; /* Pin we will search our tables for */
u16 int_line = 0; /* IRQ number read from PCI_INTR table and programmed to INT_LINE reg 0x3C */
u16 pci_intr_idx = 0; /* Index into PCI_INTR table, 0xC00/0xC01 */
u8 bus = 0; /* A PCI Device Bus number */
u16 devfn = 0; /* A PCI Device and Function number */
u8 bridged_device = 0; /* This device is on a PCI bridge */
u32 i = 0;
if (pirq_data_ptr == NULL) {
printk(BIOS_WARNING, "Warning: Can't write PCI IRQ assignments because"
" 'mainboard_pirq_data' structure does not exist\n");
return;
}
/* Populate the PCI cfg space header with the IRQ assignment */
printk(BIOS_DEBUG, "PCI_CFG IRQ: Write PCI config space IRQ assignments\n");
for (dev = all_devices; dev; dev = dev->next) {
/*
* Step 1: Get the INT_PIN and device structure to look for in the
* PCI_INTR table pirq_data
*/
target_dev = NULL;
target_pin = get_pci_irq_pins(dev, &target_dev);
if (target_dev == NULL)
continue;
if (target_pin < 1)
continue;
/* Get the original INT_PIN for record keeping */
int_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN);
if (int_pin < 1 || int_pin > 4)
continue; /* Device has invalid INT_PIN so skip it */
bus = target_dev->bus->secondary;
devfn = target_dev->path.pci.devfn;
/*
* Step 2: Use the INT_PIN and DevFn number to find the PCI_INTR
* register (0xC00) index for this device
*/
pci_intr_idx = 0xBAD; /* Will check to make sure it changed */
for (i = 0; i < pirq_data_size; i++) {
if (pirq_data_ptr[i].devfn != devfn)
continue;
/* PIN_A is index 0 in pirq_data array but 1 in PCI cfg reg */
pci_intr_idx = pirq_data_ptr[i].PIN[target_pin - 1];
printk(BIOS_SPEW, "\tFound this device in pirq_data table entry %d\n", i);
break;
}
/*
* Step 3: Make sure we got a valid index and use it to get
* the IRQ number from the PCI_INTR register table
*/
if (pci_intr_idx == 0xBAD) { /* Not on a bridge or in pirq_data table, skip it */
printk(BIOS_SPEW, "PCI Devfn (0x%x) not found in pirq_data table\n", devfn);
continue;
} else if (pci_intr_idx == 0x1F) { /* Index found is not defined */
printk(BIOS_SPEW, "Got index 0x1F (Not Connected), perhaps this device was defined wrong?\n");
continue;
} else if (pci_intr_idx >= FCH_INT_TABLE_SIZE) { /* Index out of bounds */
printk(BIOS_ERR, "%s: got 0xC00/0xC01 table index 0x%x, max is 0x%x\n",
__func__, pci_intr_idx, FCH_INT_TABLE_SIZE);
continue;
}
/* Find the value to program into the INT_LINE register from the PCI_INTR registers */
int_line = read_pci_int_idx(pci_intr_idx, 0);
if (int_line == PIRQ_NC) { /* The IRQ found is disabled */
printk(BIOS_SPEW, "Got IRQ 0x1F (disabled), perhaps this device was defined wrong?\n");
continue;
}
/*
* Step 4: Program the INT_LINE register in this device's
* PCI config space with the IRQ number we found in step 3
* and make it Level Triggered
*/
pci_write_config8(dev, PCI_INTERRUPT_LINE, int_line);
/* Set this IRQ to level triggered since it is used by a PCI device */
i8259_configure_irq_trigger(int_line, IRQ_LEVEL_TRIGGERED);
/*
* Step 5: Print out debug info and move on to next device
*/
printk(BIOS_SPEW, "\tOrig INT_PIN\t: %d (%s)\n",
int_pin, pin_to_str(int_pin));
if (bridged_device)
printk(BIOS_SPEW, "\tSwizzled to\t: %d (%s)\n",
target_pin, pin_to_str(target_pin));
printk(BIOS_SPEW, "\tPCI_INTR idx\t: 0x%02x (%s)\n"
"\tINT_LINE\t: 0x%X (IRQ %d)\n",
pci_intr_idx, intr_types[pci_intr_idx], int_line, int_line);
} /* for (dev = all_devices) */
printk(BIOS_DEBUG, "PCI_CFG IRQ: Finished writing PCI config space IRQ assignments\n");
}
#endif /* __PRE_RAM__ */

View File

@ -0,0 +1,41 @@
/*
* 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 AMD_PCI_UTIL_H
#define AMD_PCI_UTIL_H
#include <stdint.h>
#include <amd_pci_int_defs.h>
/* FCH index/data registers */
#define PCI_INTR_INDEX 0xc00
#define PCI_INTR_DATA 0xc01
struct pirq_struct {
u8 devfn;
u8 PIN[4]; /* PINA/B/C/D are index 0/1/2/3 */
};
extern const struct pirq_struct * pirq_data_ptr;
extern u32 pirq_data_size;
extern const u8 * intr_data_ptr;
extern const u8 * picr_data_ptr;
u8 read_pci_int_idx(u8 index, int mode);
void write_pci_int_idx(u8 index, int mode, u8 data);
void write_pci_cfg_irqs(void);
void write_pci_int_table (void);
#endif /* AMD_PCI_UTIL_H */

View File

@ -0,0 +1,167 @@
##
## 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
bool
select IOAPIC
select HAVE_USBDEBUG_OPTIONS
select HAVE_HARD_RESET
select SOC_AMD_COMMON
if SOC_AMD_STONEYRIDGE
config BOOTBLOCK_SOUTHBRIDGE_INIT
string
default "soc/amd/stoneyridge/bootblock/bootblock.c"
config SOUTHBRIDGE_AMD_STONEYRIDGE_SKIP_ISA_DMA_INIT
bool
default n
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 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_IMC_FWM
bool "Add IMC firmware"
default n
help
Add Stoney Ridge IMC Firmware to support the onboard fan control
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/southbridge/amd/kern/xhci.bin"
depends on STONEYRIDGE_XHCI_FWM
config STONEYRIDGE_IMC_FWM_FILE
string "IMC firmware path and filename"
default "3rdparty/blobs/southbridge/amd/kern/imc.bin"
depends on STONEYRIDGE_IMC_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/southbridge/amd/kern/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 AMDFW_OUTSIDE_CBFS
def_bool n
help
The AMDFW (PSP) is typically locatable in cbfs. Select this
option to manually attach the generated amdfw.rom at an
offset of 0x20000 from the bottom of the coreboot ROM image.
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.
endif # SOC_AMD_STONEYRIDGE

View File

@ -0,0 +1,236 @@
#*****************************************************************************
#
# 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),y)
romstage-y += early_setup.c
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
romstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
romstage-y += smbus.c
romstage-y += smbus_spd.c
romstage-$(CONFIG_STONEYRIDGE_UART) += uart.c
ramstage-y += chip.c
ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
ramstage-y += gpio.c
ramstage-y += hda.c
ramstage-y += hudson.c
ramstage-y += ide.c
ramstage-$(CONFIG_STONEYRIDGE_IMC_FWM) += imc.c
ramstage-y += lpc.c
ramstage-y += pci.c
ramstage-y += pcie.c
ramstage-y += reset.c
ramstage-y += sata.c
ramstage-y += sd.c
ramstage-y += sm.c
ramstage-y += smbus.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
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += smi_util.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 At ROMBASE + 0x20000:
# +-----------+---------------+----------------+------------+
# |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 $(CONFIG_ROM_SIZE)) 0x20000 1)
### 0
FIRMWARE_LOCATE=$(dir $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)))
FIRMWARE_TYPE=ST
###5
CONFIG_PUBSIGNEDKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/RtmPubSigned$(FIRMWARE_TYPE).key
###1
CONFIG_PSPBTLDR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspBootLoader_prod_$(FIRMWARE_TYPE).sbin
###3
CONFIG_PSPRCVR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspRecoveryBootLoader_prod_$(FIRMWARE_TYPE).sbin
###2
CONFIG_PSPSCUREOS_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureOs_prod_$(FIRMWARE_TYPE).csbin
###4
CONFIG_PSPNVRAM_FILE=$(top)/$(FIRMWARE_LOCATE)/PspNvram$(FIRMWARE_TYPE).bin
###8
CONFIG_SMUFWM_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE).sbin
CONFIG_SMUFWM_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE)_FN.sbin
###95
CONFIG_SMUSCS_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuScs$(FIRMWARE_TYPE).bin
###9
CONFIG_PSPSECUREDEBUG_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureDebug$(FIRMWARE_TYPE).Key
###12
CONFIG_PSPTRUSTLETS_FILE=$(top)/$(FIRMWARE_LOCATE)/PspTrustlets_prod_$(FIRMWARE_TYPE).cbin
###13
CONFIG_TRUSTLETKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/TrustletKey_prod_$(FIRMWARE_TYPE).sbin
###18
CONFIG_SMUFIRMWARE2_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE).sbin
CONFIG_SMUFIRMWARE2_FN_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware2_prod_$(FIRMWARE_TYPE)_FN.sbin
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_IMC_FWM_FILE=$(call add_opt_prefix, $(CONFIG_STONEYRIDGE_IMC_FWM_FILE), --imc)
OPT_STONEYRIDGE_GEC_FWM_FILE=$(call add_opt_prefix, $(CONFIG_STONEYRIDGE_GEC_FWM_FILEddd), --gec)
CONFIG_2AMD_PUBKEY_FILE =$(CONFIG_AMD_PUBKEY_FILE)
CONFIG_2PSPBTLDR_FILE =$(CONFIG_PSPBTLDR_FILE)
CONFIG_2SMUFWM_FILE =$(CONFIG_SMUFWM_FILE)
CONFIG_2SMUFWM_FN_FILE =$(CONFIG_SMUFWM_FN_FILE)
CONFIG_2PSPRCVR_FILE =$(CONFIG_PSPRCVR_FILE)
CONFIG_2PUBSIGNEDKEY_FILE =$(CONFIG_PUBSIGNEDKEY_FILE)
CONFIG_2PSPSCUREOS_FILE =$(CONFIG_PSPSCUREOS_FILE)
CONFIG_2PSPNVRAM_FILE =$(CONFIG_PSPNVRAM_FILE)
CONFIG_2PSPSECUREDEBUG_FILE =$(CONFIG_PSPSECUREDEBUG_FILE)
CONFIG_2PSPTRUSTLETS_FILE =$(CONFIG_PSPTRUSTLETS_FILE)
CONFIG_2TRUSTLETKEY_FILE =$(CONFIG_TRUSTLETKEY_FILE)
CONFIG_2SMUFIRMWARE2_FILE =$(CONFIG_SMUFIRMWARE2_FILE)
CONFIG_2SMUFIRMWARE2_FN_FILE =$(CONFIG_SMUFIRMWARE2_FN_FILE)
CONFIG_2SMUSCS_FILE =$(CONFIG_SMUSCS_FILE)
OPT_2AMD_PUBKEY_FILE=$(call add_opt_prefix, $(CONFIG_2AMD_PUBKEY_FILE), --pubkey2)
OPT_2PSPBTLDR_FILE=$(call add_opt_prefix, $(CONFIG_2PSPBTLDR_FILE), --bootloader2)
OPT_2SMUFWM_FILE=$(call add_opt_prefix, $(CONFIG_2SMUFWM_FILE), --smufirmware_2)
OPT_2PSPRCVR_FILE=$(call add_opt_prefix, $(CONFIG_2PSPRCVR_FILE), --recovery2)
OPT_2PUBSIGNEDKEY_FILE=$(call add_opt_prefix, $(CONFIG_2PUBSIGNEDKEY_FILE), --rtmpubkey2)
OPT_2PSPSCUREOS_FILE=$(call add_opt_prefix, $(CONFIG_2PSPSCUREOS_FILE), --secureos2)
OPT_2PSPNVRAM_FILE=$(call add_opt_prefix, $(CONFIG_2PSPNVRAM_FILE), --nvram2)
OPT_2PSPSECUREDEBUG_FILE=$(call add_opt_prefix, $(CONFIG_2PSPSECUREDEBUG_FILE), --securedebug2)
OPT_2PSPTRUSTLETS_FILE=$(call add_opt_prefix, $(CONFIG_2PSPTRUSTLETS_FILE), --trustlets2)
OPT_2TRUSTLETKEY_FILE=$(call add_opt_prefix, $(CONFIG_2TRUSTLETKEY_FILE), --trustletkey2)
OPT_2SMUFIRMWARE2_FILE=$(call add_opt_prefix, $(CONFIG_2SMUFIRMWARE2_FILE), --smufirmware2_2)
OPT_2SMUSCS_FILE=$(call add_opt_prefix, $(CONFIG_2SMUSCS_FILE), --smuscs2)
OPT_2SMUFWM_FN_FILE=$(call add_opt_prefix, $(CONFIG_2SMUFWM_FN_FILE), --smufnfirmware_2)
OPT_2SMUFIRMWARE2_FN_FILE=$(call add_opt_prefix, $(CONFIG_2SMUFIRMWARE2_FN_FILE), --smufnfirmware2_2)
$(obj)/amdfw.rom: $(call strip_quotes, $(CONFIG_STONEYRIDGE_XHCI_FWM_FILE)) \
$(call strip_quotes, $(CONFIG_STONEYRIDGE_IMC_FWM_FILE)) \
$(call strip_quotes, $(CONFIG_STONEYRIDGE_GEC_FWM_FILE)) \
$(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)) \
$(call strip_quotes, $(CONFIG_PUBSIGNEDKEY_FILE)) \
$(call strip_quotes, $(CONFIG_PSPBTLDR_FILE)) \
$(call strip_quotes, $(CONFIG_PSPRCVR_FILE)) \
$(call strip_quotes, $(CONFIG_PSPSCUREOS_FILE)) \
$(call strip_quotes, $(CONFIG_PSPNVRAM_FILE)) \
$(call strip_quotes, $(CONFIG_SMUFWM_FILE)) \
$(call strip_quotes, $(CONFIG_SMUSCS_FILE)) \
$(call strip_quotes, $(CONFIG_PSPSECUREDEBUG_FILE)) \
$(call strip_quotes, $(CONFIG_PSPTRUSTLETS_FILE)) \
$(call strip_quotes, $(CONFIG_TRUSTLETKEY_FILE)) \
$(call strip_quotes, $(CONFIG_SMUFIRMWARE2_FILE)) \
$(call strip_quotes, $(CONFIG_2AMD_PUBKEY_FILE)) \
$(call strip_quotes, $(CONFIG_2PUBSIGNEDKEY_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPBTLDR_FILE)) \
$(call strip_quotes, $(CONFIG_2SMUFWM_FILE)) \
$(call strip_quotes, $(CONFIG_2SMUFWM_FN_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPRCVR_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPSCUREOS_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPNVRAM_FILE)) \
$(call strip_quotes, $(CONFIG_2SMUSCS_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPSECUREDEBUG_FILE)) \
$(call strip_quotes, $(CONFIG_2PSPTRUSTLETS_FILE)) \
$(call strip_quotes, $(CONFIG_2TRUSTLETKEY_FILE)) \
$(call strip_quotes, $(CONFIG_2SMUFIRMWARE2_FILE)) \
$(call strip_quotes, $(CONFIG_2SMUFIRMWARE2_FN_FILE)) \
$(AMDFWTOOL)
rm -f $@
@printf " AMDFWTOOL $(subst $(obj)/,,$(@))\n"
$(AMDFWTOOL) \
$(OPT_STONEYRIDGE_XHCI_FWM_FILE) \
$(OPT_STONEYRIDGE_IMC_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_2AMD_PUBKEY_FILE) \
$(OPT_2PSPBTLDR_FILE) \
$(OPT_2SMUFWM_FILE) \
$(OPT_2SMUFWM_FN_FILE) \
$(OPT_2PSPRCVR_FILE) \
$(OPT_2PUBSIGNEDKEY_FILE) \
$(OPT_2PSPSCUREOS_FILE) \
$(OPT_2PSPNVRAM_FILE) \
$(OPT_2PSPSECUREDEBUG_FILE) \
$(OPT_2PSPTRUSTLETS_FILE) \
$(OPT_2TRUSTLETKEY_FILE) \
$(OPT_2SMUFIRMWARE2_FILE) \
$(OPT_2SMUFIRMWARE2_FN_FILE) \
$(OPT_2SMUSCS_FILE) \
--flashsize $(CONFIG_ROM_SIZE) \
--output $@
ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
PHONY+=add_amdfw
INTERMEDIATE+=add_amdfw
add_amdfw: $(obj)/coreboot.pre $(obj)/amdfw.rom
printf " DD Adding AMD Firmware\n"
dd if=$(obj)/amdfw.rom \
of=$(obj)/coreboot.pre conv=notrunc bs=1 seek=131072 >/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)
endif

View File

@ -0,0 +1,184 @@
/*
* 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.
*/
/* South Bridge */
/* _SB.PCI0 */
/* Operating System Capabilities Method */
Method(_OSC,4)
{
// Create DWord-addressable fields from the Capabilities Buffer
CreateDWordField(Arg3,0,CDW1)
CreateDWordField(Arg3,4,CDW2)
CreateDWordField(Arg3,8,CDW3)
/* Check for proper PCI/PCIe UUID */
If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
{
/* Let OS control everything */
Return (Arg3)
} Else {
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 "lpc.asl"
/* 0:14.7 - SD Controller */
Device(SDCN) {
Name(_ADR, 0x00140007)
} /* 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) {
/* 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()
#if IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE)
/* TODO: It is unstable. */
#include "acpi/AmdImc.asl" /* Hudson IMC function */
ITZE() /* enable IMC Fan Control*/
#endif
} /* 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)
}

View File

@ -0,0 +1,103 @@
/*
* 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.
*/
/* 0:14.3 - LPC */
Device(LIBR) {
Name(_ADR, 0x00140003)
/* Method(_INI) {
* DBGO("\\_SB\\PCI0\\LpcIsaBr\\_INI\n")
} */ /* End Method(_SB.SBRDG._INI) */
OperationRegion(CFG,PCI_Config,0x0,0x100) // Map PCI Configuration Space
Field(CFG,DWordAcc,NoLock,Preserve){
Offset(0xA0),
BAR,32} // SPI Controller Base Address Register (Index 0xA0)
Device(LDRC) // LPC device: Resource consumption
{
Name (_HID, EISAID("PNP0C02")) // ID for Motherboard resources
Name (CRS, ResourceTemplate () // Current Motherboard resources
{
Memory32Fixed(ReadWrite, // Setup for fixed resource location for SPI base address
0x00000000, // Address Base
0x00000000, // Address Length
BAR0 // Descriptor Name
)
})
Method(_CRS,0,NotSerialized)
{
CreateDwordField(^CRS,^BAR0._BAS,SPIB) // Field to hold SPI base address
CreateDwordField(^CRS,^BAR0._LEN,SPIL) // Field to hold SPI address length
Store(BAR,SPIB) // SPI base address mapped
Store(0x1000,SPIL) // 4k space mapped
Return(CRS)
}
}
/* Real Time Clock Device */
Device(RTC0) {
Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */
Name(_CRS, ResourceTemplate() {
IRQNoFlags(){8}
IO(Decode16,0x0070, 0x0070, 0, 2)
})
} /* End Device(_SB.PCI0.LpcIsaBr.RTC0) */
Device(TMR) { /* Timer */
Name(_HID,EISAID("PNP0100")) /* System Timer */
Name(_CRS, ResourceTemplate() {
IRQNoFlags(){0}
IO(Decode16, 0x0040, 0x0040, 0, 4)
})
} /* End Device(_SB.PCI0.LpcIsaBr.TMR) */
Device(SPKR) { /* Speaker */
Name(_HID,EISAID("PNP0800")) /* AT style speaker */
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0061, 0x0061, 0, 1)
})
} /* End Device(_SB.PCI0.LpcIsaBr.SPKR) */
Device(PIC) {
Name(_HID,EISAID("PNP0000")) /* AT Interrupt Controller */
Name(_CRS, ResourceTemplate() {
IRQNoFlags(){2}
IO(Decode16,0x0020, 0x0020, 0, 2)
IO(Decode16,0x00A0, 0x00A0, 0, 2)
})
} /* End Device(_SB.PCI0.LpcIsaBr.PIC) */
Device(MAD) { /* 8257 DMA */
Name(_HID,EISAID("PNP0200")) /* Hardware Device ID */
Name(_CRS, ResourceTemplate() {
DMA(Compatibility,BusMaster,Transfer8){4}
IO(Decode16, 0x0000, 0x0000, 0x10, 0x10)
IO(Decode16, 0x0081, 0x0081, 0x01, 0x03)
IO(Decode16, 0x0087, 0x0087, 0x01, 0x01)
IO(Decode16, 0x0089, 0x0089, 0x01, 0x03)
IO(Decode16, 0x008F, 0x008F, 0x01, 0x01)
IO(Decode16, 0x00C0, 0x00C0, 0x10, 0x20)
}) /* End Name(_SB.PCI0.LpcIsaBr.MAD._CRS) */
} /* End Device(_SB.PCI0.LpcIsaBr.MAD) */
Device(COPR) {
Name(_HID,EISAID("PNP0C04")) /* Math Coprocessor */
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x00F0, 0x00F0, 0, 0x10)
IRQNoFlags(){13}
})
} /* End Device(_SB.PCI0.LpcIsaBr.COPR) */
} /* end LIBR */

View File

@ -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) */

View File

@ -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,
}

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
/* Supported sleep states: */
Name(\_S0, Package () {0x00, 0x00, 0x00, 0x00} ) /* (S0) - working state */
If (LAnd(SSFG, 0x01)) {
Name(\_S1, Package () {0x01, 0x01, 0x00, 0x00} ) /* (S1) - sleeping w/CPU context */
}
If (LAnd(SSFG, 0x02)) {
Name(\_S2, Package () {0x02, 0x02, 0x00, 0x00} ) /* (S2) - "light" Suspend to RAM */
}
#if CONFIG_HAVE_ACPI_RESUME
If (LAnd(SSFG, 0x04)) {
Name(\_S3, Package () {0x03, 0x03, 0x00, 0x00} ) /* (S3) - Suspend to RAM */
}
#endif
If (LAnd(SSFG, 0x08)) {
Name(\_S4, Package () {0x04, 0x04, 0x00, 0x00} ) /* (S4) - Suspend to Disk */
}
Name(\_S5, Package () {0x05, 0x05, 0x00, 0x00} ) /* (S5) - Soft Off */
Name(\_SB.CSPS ,0) /* Current Sleep State (S0, S1, S2, S3, S4, S5) */
Name(CSMS, 0) /* Current System State */

View File

View File

@ -0,0 +1,65 @@
/*
* 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 - OHCI */
Device(UOH1) {
Name(_ADR, 0x00120000)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH1 */
/* 0:12.2 - EHCI */
Device(UOH2) {
Name(_ADR, 0x00120002)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH2 */
/* 0:13.0 - OHCI */
Device(UOH3) {
Name(_ADR, 0x00130000)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH3 */
/* 0:13.2 - EHCI */
Device(UOH4) {
Name(_ADR, 0x00130002)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH4 */
/* 0:16.0 - OHCI */
Device(UOH5) {
Name(_ADR, 0x00160000)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH5 */
/* 0:16.2 - EHCI */
Device(UOH6) {
Name(_ADR, 0x00160002)
Name(_PRW, Package() {0x0B, 3})
} /* end UOH5 */
/* 0:10.0 - XHCI 0*/
Device(XHC0) {
Name(_ADR, 0x00100000)
Name(_PRW, Package() {0x0B, 4})
} /* end XHC0 */
#if !CONFIG_SOUTHBRIDGE_AMD_PI_AVALON && !CONFIG_SOUTHBRIDGE_AMD_PI_KERN
/* 0:10.1 - XHCI 1*/
Device(XHC1) {
Name(_ADR, 0x00100001)
Name(_PRW, Package() {0x0B, 4})
} /* end XHC1 */
#endif

View File

@ -0,0 +1,63 @@
/*
* 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 <stdint.h>
#include <arch/io.h>
#include <device/pci_ids.h>
/*
* Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
*
* Hardware should enable LPC ROM by pin straps. This function does not
* handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
*
* The HUDSON power-on default is to map 512K ROM space.
*
*/
static void hudson_enable_rom(void)
{
u8 reg8;
pci_devfn_t dev;
dev = PCI_DEV(0, 0x14, 3);
/* Decode variable LPC ROM address ranges 1 and 2. */
reg8 = pci_io_read_config8(dev, 0x48);
reg8 |= (1 << 3) | (1 << 4);
pci_io_write_config8(dev, 0x48, reg8);
/* LPC ROM address range 1: */
/* Enable LPC ROM range mirroring start at 0x000e(0000). */
pci_io_write_config16(dev, 0x68, 0x000e);
/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
pci_io_write_config16(dev, 0x6a, 0x000f);
/* LPC ROM address range 2: */
/*
* Enable LPC ROM range start at:
* 0xfff8(0000): 512KB
* 0xfff0(0000): 1MB
* 0xffe0(0000): 2MB
* 0xffc0(0000): 4MB
*/
pci_io_write_config16(dev, 0x6c, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
/* Enable LPC ROM range end at 0xffff(ffff). */
pci_io_write_config16(dev, 0x6e, 0xffff);
}
static void bootblock_southbridge_init(void)
{
hudson_enable_rom();
}

View File

@ -0,0 +1,60 @@
/*
* 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 <chip.h>
#include <device/device.h>
#include <device/pci.h>
#include <soc/hudson.h>
static void pci_domain_set_resources(device_t dev)
{
assign_resources(dev->link_list);
}
static struct device_operations pci_domain_ops = {
.set_resources = &pci_domain_set_resources,
};
static struct device_operations cpu_bus_ops = {
};
static void enable_dev(device_t 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) {
hudson_enable(dev);
}
}
static void soc_init(void *chip_info)
{
hudson_init(chip_info);
}
static void soc_final(void *chip_info)
{
hudson_final(chip_info);
}
struct chip_operations soc_amd_stoneyridge_ops = {
CHIP_NAME("AMD StoneyRidge SOC")
.enable_dev = &enable_dev,
.init = &soc_init,
.final = &soc_final
};

View File

@ -0,0 +1,33 @@
/*
* 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_CHIP_H
#define STONEYRIDGE_CHIP_H
#include <stdint.h>
struct soc_amd_stoneyridge_config
{
u32 ide0_enable : 1;
u32 sata0_enable : 1;
u32 boot_switch_sata_ide : 1;
u32 hda_viddid;
u8 gpp_configuration;
u8 sd_mode;
};
typedef struct soc_amd_stoneyridge_config config_t;
#endif /* STONEYRIDGE_CHIP_H */

View File

@ -0,0 +1,334 @@
/*
* 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_EARLY_SETUP_C_
#define _STONEYRIDGE_EARLY_SETUP_C_
#include <assert.h>
#include <stdint.h>
#include <arch/io.h>
#include <arch/acpi.h>
#include <console/console.h>
#include <reset.h>
#include <arch/cpu.h>
#include <cbmem.h>
#include <soc/hudson.h>
#include <soc/pci_devs.h>
#include <Fch/Fch.h>
#include <cpu/x86/msr.h>
#include <delay.h>
void configure_hudson_uart(void)
{
u8 byte;
byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 + CONFIG_UART_FOR_CONSOLE * 2);
byte |= 1 << 3;
write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56 + CONFIG_UART_FOR_CONSOLE * 2, byte);
byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62);
byte |= 1 << 3;
write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62, byte);
write8((void *)FCH_IOMUXx89_UART0_RTS_L_EGPIO137, 0);
write8((void *)FCH_IOMUXx8A_UART0_TXD_EGPIO138, 0);
write8((void *)FCH_IOMUXx8E_UART1_RTS_L_EGPIO142, 0);
write8((void *)FCH_IOMUXx8F_UART1_TXD_EGPIO143, 0);
udelay(2000);
write8((void *)0xFEDC6000 + 0x2000 * CONFIG_UART_FOR_CONSOLE + 0x88, 0x01); /* reset UART */
}
void hudson_pci_port80(void)
{
u8 byte;
pci_devfn_t dev;
/* P2P Bridge */
dev = PCI_DEV(0, 0x14, 4);
/* Chip Control: Enable subtractive decoding */
byte = pci_read_config8(dev, 0x40);
byte |= 1 << 5;
pci_write_config8(dev, 0x40, byte);
/* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
byte = pci_read_config8(dev, 0x4B);
byte |= 1 << 7;
pci_write_config8(dev, 0x4B, byte);
/* The same IO Base and IO Limit here is meaningful because we set the
* bridge to be subtractive. During early setup stage, we have to make
* sure that data can go through port 0x80.
*/
/* IO Base: 0xf000 */
byte = pci_read_config8(dev, 0x1C);
byte |= 0xF << 4;
pci_write_config8(dev, 0x1C, byte);
/* IO Limit: 0xf000 */
byte = pci_read_config8(dev, 0x1D);
byte |= 0xF << 4;
pci_write_config8(dev, 0x1D, byte);
/* PCI Command: Enable IO response */
byte = pci_read_config8(dev, 0x04);
byte |= 1 << 0;
pci_write_config8(dev, 0x04, byte);
/* LPC controller */
dev = PCI_DEV(0, 0x14, 3);
byte = pci_read_config8(dev, 0x4A);
byte &= ~(1 << 5); /* disable lpc port 80 */
pci_write_config8(dev, 0x4A, byte);
}
void hudson_lpc_port80(void)
{
u8 byte;
pci_devfn_t dev;
/* Enable LPC controller */
outb(0xEC, 0xCD6);
byte = inb(0xCD7);
byte |= 1;
outb(0xEC, 0xCD6);
outb(byte, 0xCD7);
/* Enable port 80 LPC decode in pci function 3 configuration space. */
dev = PCI_DEV(0, 0x14, 3);
byte = pci_read_config8(dev, 0x4a);
byte |= 1 << 5; /* enable port 80 */
pci_write_config8(dev, 0x4a, byte);
}
void hudson_lpc_decode(void)
{
pci_devfn_t dev;
u32 tmp = 0;
/* Enable I/O decode to LPC bus */
dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
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;
pci_write_config32(dev, LPC_IO_PORT_DECODE_ENABLE, tmp);
}
static void enable_wideio(uint8_t port, uint16_t size)
{
uint32_t wideio_enable[] = {
LPC_WIDEIO0_ENABLE,
LPC_WIDEIO1_ENABLE,
LPC_WIDEIO2_ENABLE
};
uint32_t alt_wideio_enable[] = {
LPC_ALT_WIDEIO0_ENABLE,
LPC_ALT_WIDEIO1_ENABLE,
LPC_ALT_WIDEIO2_ENABLE
};
pci_devfn_t dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
uint32_t tmp;
/* Only allow port 0-2 */
assert(port <= ARRAY_SIZE(wideio_enable));
if (size == 16) {
tmp = pci_read_config32(dev, LPC_ALT_WIDEIO_RANGE_ENABLE);
tmp |= alt_wideio_enable[port];
pci_write_config32(dev, LPC_ALT_WIDEIO_RANGE_ENABLE, tmp);
} else { /* 512 */
tmp = pci_read_config32(dev, LPC_ALT_WIDEIO_RANGE_ENABLE);
tmp &= ~alt_wideio_enable[port];
pci_write_config32(dev, LPC_ALT_WIDEIO_RANGE_ENABLE, tmp);
}
/* Enable the range */
tmp = pci_read_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE);
tmp |= wideio_enable[port];
pci_write_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE, tmp);
}
/*
* lpc_wideio_window() may be called any point in romstage, but take
* care that AGESA doesn't overwrite the range this function used.
* The function checks if there is an empty range and if all ranges are
* used the function throws an assert. The function doesn't check for a
* duplicate range, for ranges that can be merged into a single
* range, or ranges that overlap.
*
* The developer is expected to ensure that there are no conflicts.
*/
static void lpc_wideio_window(uint16_t base, uint16_t size)
{
pci_devfn_t dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
u32 tmp;
/* Support 512 or 16 bytes per range */
assert(size == 512 || size == 16);
/* Find and open Base Register and program it */
tmp = pci_read_config32(dev, LPC_WIDEIO_GENERIC_PORT);
if ((tmp & 0xFFFF) == 0) { /* WIDEIO0 */
tmp |= base;
pci_write_config32(dev, LPC_WIDEIO_GENERIC_PORT, tmp);
enable_wideio(0, size);
} else if ((tmp & 0xFFFF0000) == 0) { /* WIDEIO1 */
tmp |= (base << 16);
pci_write_config32(dev, LPC_WIDEIO_GENERIC_PORT, tmp);
enable_wideio(1, size);
} else { /* Check WIDEIO2 register */
tmp = pci_read_config32(dev, LPC_WIDEIO2_GENERIC_PORT);
if ((tmp & 0xFFFF) == 0) { /* WIDEIO2 */
tmp |= base;
pci_write_config32(dev, LPC_WIDEIO2_GENERIC_PORT, tmp);
enable_wideio(2, size);
} else { /* All WIDEIO locations used*/
assert(0);
}
}
}
void lpc_wideio_512_window(uint16_t base)
{
assert(IS_ALIGNED(base, 512));
lpc_wideio_window(base, 512);
}
void lpc_wideio_16_window(uint16_t base)
{
assert(IS_ALIGNED(base, 16));
lpc_wideio_window(base, 16);
}
int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
{
int i;
printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
for (i = 0; i < size; i++) {
outb(nvram_pos, BIOSRAM_INDEX);
outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA);
nvram_pos++;
}
return nvram_pos;
}
int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
{
u32 data = *old_dword;
int i;
for (i = 0; i < size; i++) {
outb(nvram_pos, BIOSRAM_INDEX);
data &= ~(0xff << (i * 8));
data |= inb(BIOSRAM_DATA) << (i *8);
nvram_pos++;
}
*old_dword = data;
printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", *old_dword, size,
nvram_pos-size);
return nvram_pos;
}
void hudson_clk_output_48Mhz(void)
{
u32 data, *memptr;
/*
* Enable the X14M_25M_48M_OSC pin and leaving it at it's default so
* 48Mhz will be on ball AP13 (FT3b package)
*/
memptr = (u32 *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40 );
data = *memptr;
/* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */
data &= (u32)~(1<<2);
*memptr = data;
}
static uintptr_t hudson_spibase(void)
{
/* Make sure the base address is predictable */
device_t dev = PCI_DEV(0, 0x14, 3);
u32 base = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER)
& 0xfffffff0;
if (!base){
base = SPI_BASE_ADDRESS;
pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, base
| SPI_ROM_ENABLE);
/* PCI_COMMAND_MEMORY is read-only and enabled. */
}
return (uintptr_t)base;
}
void hudson_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
{
uintptr_t base = hudson_spibase();
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 hudson_disable_4dw_burst(void)
{
uintptr_t base = hudson_spibase();
write16((void *)base + SPI100_HOST_PREF_CONFIG,
read16((void *)base + SPI100_HOST_PREF_CONFIG)
& ~SPI_RD4DW_EN_HOST);
}
/* Hudson 1-3 only. For Hudson 1, call with fast=1 */
void hudson_set_readspeed(u16 norm, u16 fast)
{
uintptr_t base = hudson_spibase();
write16((void *)base + SPI_CNTRL1, (read16((void *)base + SPI_CNTRL1)
& ~SPI_CNTRL1_SPEED_MASK)
| (norm << SPI_NORM_SPEED_SH)
| (fast << SPI_FAST_SPEED_SH));
}
void hudson_read_mode(u32 mode)
{
uintptr_t base = hudson_spibase();
write32((void *)base + SPI_CNTRL0,
(read32((void *)base + SPI_CNTRL0)
& ~SPI_READ_MODE_MASK) | mode);
}
void hudson_tpm_decode_spi(void)
{
device_t dev = PCI_DEV(0, 0x14, 3); /* LPC device */
u32 spibase = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER);
pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, spibase
| ROUTE_TPM_2_SPI);
}
#endif

View File

@ -0,0 +1,59 @@
/*
* 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 <arch/io.h>
#include <device/pci_ehci.h>
#include <device/pci_def.h>
#include <soc/hudson.h>
#define DEBUGPORT_MISC_CONTROL 0x80
pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
{
if (hcd_idx == 3)
return PCI_DEV(0, 0x16, 0);
else if (hcd_idx == 2)
return PCI_DEV(0, 0x13, 0);
else
return PCI_DEV(0, 0x12, 0);
}
void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
u8 *base_regs = pci_ehci_base_regs(dev);
u32 reg32;
/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
reg32 = read32(base_regs + DEBUGPORT_MISC_CONTROL);
reg32 &= ~(0xf << 28);
reg32 |= (port << 28);
reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
write32(base_regs + DEBUGPORT_MISC_CONTROL, reg32);
}
void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
/* Enable all of the USB controllers */
outb(0xEF, PM_INDEX);
outb(0x7F, PM_DATA);
pci_write_config32(dev, EHCI_BAR_INDEX, base);
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
}

View File

@ -0,0 +1,207 @@
/*
* 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.
*/
/*
* ACPI - create the Fixed ACPI Description Tables (FADT)
*/
#include <string.h>
#include <console/console.h>
#include <arch/acpi.h>
#include <arch/io.h>
#include <device/device.h>
#include <soc/hudson.h>
#include <soc/smi.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
/*
* 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 = ACPI_FADT_REV_ACPI_3_0;
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 = 0;
fadt->firmware_ctrl = (u32) facs;
fadt->dsdt = (u32) dsdt;
fadt->model = 0; /* reserved, should be 0 ACPI 3.0 */
fadt->preferred_pm_profile = FADT_PM_PROFILE;
fadt->sci_int = 9; /* HUDSON - IRQ 09 - ACPI SCI */
if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
fadt->smi_cmd = ACPI_SMI_CTL_PORT;
fadt->acpi_enable = ACPI_SMI_CMD_ENABLE;
fadt->acpi_disable = ACPI_SMI_CMD_DISABLE;
fadt->s4bios_req = 0; /* Not supported */
fadt->pstate_cnt = 0; /* Not supported */
fadt->cst_cnt = 0; /* Not supported */
outl(0x0, ACPI_PM1_CNT_BLK); /* clear SCI_EN */
} 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 */
outl(0x1, ACPI_PM1_CNT_BLK); /* set SCI_EN */
}
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 in hudson */
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 = 0xcf9;
fadt->reset_reg.addrh = 0x0;
fadt->reset_value = 6;
fadt->res3 = 0; /* reserved, MUST be 0 ACPI 3.0 */
fadt->res4 = 0; /* reserved, MUST be 0 ACPI 3.0 */
fadt->res5 = 0; /* reserved, 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));
}

View File

@ -0,0 +1,28 @@
/*
* 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 <arch/io.h>
#include <soc/gpio.h>
int gpio_get(gpio_t gpio_num)
{
uint32_t reg;
reg = read32((void*)(uintptr_t)gpio_num);
return !!(reg & GPIO_PIN_STS);
}

View File

@ -0,0 +1,52 @@
/*
* 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 <arch/io.h>
#include <delay.h>
#include <soc/hudson.h>
static const unsigned short pci_device_ids[] = {
PCI_DEVICE_ID_AMD_SB900_HDA,
PCI_DEVICE_ID_AMD_CZ_HDA,
0
};
static void hda_init(struct device *dev)
{
}
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
};
static struct device_operations hda_audio_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = hda_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
static const struct pci_driver hdaaudio_driver __pci_driver = {
.ops = &hda_audio_ops,
.vendor = PCI_VENDOR_ID_AMD,
.devices = pci_device_ids,
};

View File

@ -0,0 +1,132 @@
/*
* 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 <arch/io.h>
#include <arch/acpi.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <cbmem.h>
#include <soc/hudson.h>
#include <soc/smbus.h>
#include <soc/smi.h>
#if IS_ENABLED(CONFIG_STONEYRIDGE_IMC_FWM)
#include <fchec.h>
#endif
int acpi_get_sleep_type(void)
{
u16 tmp = inw(ACPI_PM1_CNT_BLK);
tmp = ((tmp & (7 << 10)) >> 10);
return (int)tmp;
}
void pm_write8(u8 reg, u8 value)
{
write8((void *)(PM_MMIO_BASE + reg), value);
}
u8 pm_read8(u8 reg)
{
return read8((void *)(PM_MMIO_BASE + reg));
}
void pm_write16(u8 reg, u16 value)
{
write16((void *)(PM_MMIO_BASE + reg), value);
}
u16 pm_read16(u16 reg)
{
return read16((void *)(PM_MMIO_BASE + reg));
}
void hudson_enable(device_t dev)
{
printk(BIOS_DEBUG, "hudson_enable()\n");
switch (dev->path.pci.devfn) {
case (0x14 << 3) | 7: /* 0:14.7 SD */
if (dev->enabled == 0) {
// read the VENDEV ID
device_t sd_dev = dev_find_slot( 0, PCI_DEVFN( 0x14, 7));
u32 sd_device_id = pci_read_config32( sd_dev, 0) >> 16;
/* turn off the SDHC controller in the PM reg */
u8 reg8;
if (sd_device_id == PCI_DEVICE_ID_AMD_HUDSON_SD) {
reg8 = pm_read8(PM_HUD_SD_FLASH_CTRL);
reg8 &= ~BIT(0);
pm_write8(PM_HUD_SD_FLASH_CTRL, reg8);
}
else if (sd_device_id == PCI_DEVICE_ID_AMD_YANGTZE_SD) {
reg8 = pm_read8(PM_YANG_SD_FLASH_CTRL);
reg8 &= ~BIT(0);
pm_write8(PM_YANG_SD_FLASH_CTRL, reg8);
}
/* remove device 0:14.7 from PCI space */
reg8 = pm_read8(PM_MANUAL_RESET);
reg8 &= ~BIT(6);
pm_write8(PM_MANUAL_RESET, reg8);
}
break;
default:
break;
}
}
static void hudson_init_acpi_ports(void)
{
/* 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 (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
pm_write16(PM_ACPI_SMI_CMD, ACPI_SMI_CTL_PORT);
hudson_enable_acpi_cmd_smi();
} else {
pm_write16(PM_ACPI_SMI_CMD, 0);
}
/* AcpiDecodeEnable, When set, SB uses the contents of the PM registers
* at index 60-6B to decode ACPI I/O address. AcpiSmiEn & SmiCmdEn
*/
pm_write8(PM_ACPI_CONF, BIT(0) | BIT(1) | BIT(4) | BIT(2));
}
void hudson_init(void *chip_info)
{
hudson_init_acpi_ports();
}
void hudson_final(void *chip_info)
{
#if IS_ENABLED(CONFIG_STONEYRIDGE_IMC_FWM)
agesawrapper_fchecfancontrolservice();
#if !IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE)
enable_imc_thermal_zone();
#endif
#endif
}

View File

@ -0,0 +1,44 @@
/*
* 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 <soc/hudson.h>
static void ide_init(struct device *dev)
{
}
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
};
static struct device_operations ide_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = ide_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
static const struct pci_driver ide_driver __pci_driver = {
.ops = &ide_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_IDE,
};

View File

@ -0,0 +1,101 @@
/*
* 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.
*/
#define __SIMPLE_DEVICE__
#include <soc/imc.h>
#include <arch/io.h>
#include <device/device.h>
#include <delay.h>
#include <Porting.h>
#include <AGESA.h>
#include <Lib/amdlib.h>
#include <Proc/Fch/Common/FchCommonCfg.h>
#include <Proc/Fch/Fch.h>
#include <Proc/Fch/FchPlatform.h>
#define VACPI_MMIO_VBASE ((u8 *)ACPI_MMIO_BASE)
void imc_reg_init(void)
{
u8 reg8;
/* Init Power Management Block 2 (PM2) Registers.
* Check BKDG for AMD Family 16h for details. */
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x00), 0x06);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x01), 0x06);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x02), 0xf7);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x03), 0xff);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x04), 0xff);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x10), 0x06);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x11), 0x06);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x12), 0xf7);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x13), 0xff);
write8((VACPI_MMIO_VBASE + PMIO2_BASE + 0x14), 0xff);
reg8 = pci_read_config8(PCI_DEV(0, 0x18, 0x3), 0x1E4);
reg8 &= 0x8F;
reg8 |= 0x10;
pci_write_config8(PCI_DEV(0, 0x18, 0x3), 0x1E4, reg8);
}
#ifndef __PRE_RAM__
void enable_imc_thermal_zone(void)
{
AMD_CONFIG_PARAMS StdHeader;
UINT8 FunNum;
UINT8 regs[9];
int i;
regs[0] = 0;
regs[1] = 0;
FunNum = Fun_80;
for (i = 0; i <= 1; i++)
WriteECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader);
WaitForEcLDN9MailboxCmdAck(&StdHeader);
for (i = 2; i <= 9; i++)
ReadECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
/* enable thermal zone 0 */
regs[2] |= 1;
regs[0] = 0;
regs[1] = 0;
FunNum = Fun_81;
for (i = 0; i <= 9; i++)
WriteECmsg(MSG_REG0 + i, AccessWidth8, &regs[i], &StdHeader);
WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader);
WaitForEcLDN9MailboxCmdAck(&StdHeader);
}
#endif
/* Bettong Hardware Monitor Fan Control
* Hardware limitation:
* HWM will fail to read the input temperature via I2C if other
* software switches the I2C address. AMD recommends using IMC
* to control fans, instead of HWM.
*/
void oem_fan_control(FCH_DATA_BLOCK *FchParams)
{
/* Enable IMC fan control. the recommand way */
imc_reg_init();
FchParams->Imc.ImcEnable = TRUE;
FchParams->Hwm.HwmControl = 1; /* 1 IMC, 0 HWM */
FchParams->Imc.ImcEnableOverWrite = 1; /* 2 disable IMC, 1 enable IMC, 0 following hw strap setting */
LibAmdMemFill(&(FchParams->Imc.EcStruct), 0, sizeof(FCH_EC), FchParams->StdHeader);
}

View File

@ -0,0 +1,75 @@
/*
* 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 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_GEC 0x15 /* GEC */
#define PIRQ_PMON 0x16 /* Performance Monitor */
#define PIRQ_SD 0x17 /* SD */
#define PIRQ_IMC0 0x20 /* IMC INT0 */
#define PIRQ_IMC1 0x21 /* IMC INT1 */
#define PIRQ_IMC2 0x22 /* IMC INT2 */
#define PIRQ_IMC3 0x23 /* IMC INT3 */
#define PIRQ_IMC4 0x24 /* IMC INT4 */
#define PIRQ_IMC5 0x25 /* IMC INT5 */
#define PIRQ_OHCI1 0x30 /* USB OHCI 12h.0 */
#define PIRQ_EHCI1 0x31 /* USB EHCI 12h.2 */
#define PIRQ_OHCI2 0x32 /* USB OHCI 13h.0 */
#define PIRQ_EHCI2 0x33 /* USB EHCI 13h.2 */
#define PIRQ_OHCI3 0x34 /* USB OHCI 16h.0 */
#define PIRQ_EHCI3 0x35 /* USB EHCI 16h.2 */
#define PIRQ_OHCI4 0x36 /* USB OHCI 14h.5 */
#define PIRQ_IDE 0x40 /* IDE 14h.1 */
#define PIRQ_SATA 0x41 /* SATA 11h.0 */
#define FCH_INT_TABLE_SIZE 0x76
#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 */

View File

@ -0,0 +1,32 @@
/*
* 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 AMD_PCI_INT_TYPES_H
#define AMD_PCI_INT_TYPES_H
const char * intr_types[] = {
[0x00] = "INTA#\t", "INTB#\t", "INTC#\t", "INTD#\t", "INTE#\t", "INTF#\t", "INTG#\t", "INTH#\t",
[0x08] = "Misc\t", "Misc0\t", "Misc1\t", "Misc2\t", "Ser IRQ INTA", "Ser IRQ INTB", "Ser IRQ INTC", "Ser IRQ INTD",
[0x10] = "SCI\t", "SMBUS0\t", "ASF\t", "HDA\t", "FC\t\t", "GEC\t", "PerMon\t", "SD\t\t",
[0x20] = "IMC INT0\t", "IMC INT1\t", "IMC INT2\t", "IMC INT3\t", "IMC INT4\t", "IMC INT5\t",
[0x30] = "Dev18.0 INTA", "Dev18.2 INTB", "Dev19.0 INTA", "Dev19.2 INTB", "Dev22.0 INTA", "Dev22.2 INTB", "Dev20.5 INTC",
[0x7F] = "RSVD\t",
[0x40] = "IDE\t", "SATA\t",
[0x50] = "GPPInt0\t", "GPPInt1\t", "GPPInt2\t", "GPPInt3\t",
[0x62] = "GPIO\t",
[0x70] = "I2C0\t", "I2C1\t", "I2C2\t","I2C3\t", "UART0\t", "UART1\t",
};
#endif /* AMD_PCI_INT_TYPES_H */

View File

@ -0,0 +1,131 @@
/*
* 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_
#include <soc/amd/common/amd_defs.h>
#include <types.h>
#define CROS_GPIO_DEVICE_NAME "AmdKern"
#define GPIO_PIN_STS (1 << 16)
#define GPIO_OUTPUT_VALUE (1 << 22)
#define GPIO_OUTPUT_ENABLE (1 << 23)
/* GPIO_0 - GPIO_62 */
#define GPIO_BANK0_CONTROL (AMD_SB_ACPI_MMIO_ADDR + 0x1500)
#define GPIO_0 (GPIO_BANK0_CONTROL + 0x00)
#define GPIO_1 (GPIO_BANK0_CONTROL + 0x04)
#define GPIO_2 (GPIO_BANK0_CONTROL + 0x08)
#define GPIO_3 (GPIO_BANK0_CONTROL + 0x0C)
#define GPIO_4 (GPIO_BANK0_CONTROL + 0x10)
#define GPIO_5 (GPIO_BANK0_CONTROL + 0x14)
#define GPIO_6 (GPIO_BANK0_CONTROL + 0x18)
#define GPIO_7 (GPIO_BANK0_CONTROL + 0x1C)
#define GPIO_8 (GPIO_BANK0_CONTROL + 0x20)
#define GPIO_9 (GPIO_BANK0_CONTROL + 0x24)
#define GPIO_10 (GPIO_BANK0_CONTROL + 0x28)
#define GPIO_11 (GPIO_BANK0_CONTROL + 0x2C)
#define GPIO_12 (GPIO_BANK0_CONTROL + 0x30)
#define GPIO_13 (GPIO_BANK0_CONTROL + 0x34)
#define GPIO_14 (GPIO_BANK0_CONTROL + 0x38)
#define GPIO_15 (GPIO_BANK0_CONTROL + 0x3C)
#define GPIO_16 (GPIO_BANK0_CONTROL + 0x40)
#define GPIO_17 (GPIO_BANK0_CONTROL + 0x44)
#define GPIO_18 (GPIO_BANK0_CONTROL + 0x48)
#define GPIO_19 (GPIO_BANK0_CONTROL + 0x4C)
#define GPIO_20 (GPIO_BANK0_CONTROL + 0x50)
#define GPIO_21 (GPIO_BANK0_CONTROL + 0x54)
#define GPIO_22 (GPIO_BANK0_CONTROL + 0x58)
#define GPIO_23 (GPIO_BANK0_CONTROL + 0x5C)
#define GPIO_24 (GPIO_BANK0_CONTROL + 0x60)
#define GPIO_25 (GPIO_BANK0_CONTROL + 0x64)
#define GPIO_26 (GPIO_BANK0_CONTROL + 0x68)
#define GPIO_39 (GPIO_BANK0_CONTROL + 0x9C)
#define GPIO_42 (GPIO_BANK0_CONTROL + 0xA8)
/* GPIO_64 - GPIO_127 */
#define GPIO_BANK1 (CONTROL AMD_SB_ACPI_MMIO_ADDR + 0x1600)
#define GPIO_64 (GPIO_BANK1_CONTROL + 0x00)
#define GPIO_65 (GPIO_BANK1_CONTROL + 0x04)
#define GPIO_66 (GPIO_BANK1_CONTROL + 0x08)
#define GPIO_67 (GPIO_BANK1_CONTROL + 0x0C)
#define GPIO_68 (GPIO_BANK1_CONTROL + 0x10)
#define GPIO_69 (GPIO_BANK1_CONTROL + 0x14)
#define GPIO_70 (GPIO_BANK1_CONTROL + 0x18)
#define GPIO_71 (GPIO_BANK1_CONTROL + 0x1C)
#define GPIO_72 (GPIO_BANK1_CONTROL + 0x20)
#define GPIO_74 (GPIO_BANK1_CONTROL + 0x28)
#define GPIO_75 (GPIO_BANK1_CONTROL + 0x2C)
#define GPIO_76 (GPIO_BANK1_CONTROL + 0x30)
#define GPIO_84 (GPIO_BANK1_CONTROL + 0x50)
#define GPIO_85 (GPIO_BANK1_CONTROL + 0x54)
#define GPIO_86 (GPIO_BANK1_CONTROL + 0x58)
#define GPIO_87 (GPIO_BANK1_CONTROL + 0x5C)
#define GPIO_88 (GPIO_BANK1_CONTROL + 0x60)
#define GPIO_89 (GPIO_BANK1_CONTROL + 0x64)
#define GPIO_90 (GPIO_BANK1_CONTROL + 0x68)
#define GPIO_91 (GPIO_BANK1_CONTROL + 0x6C)
#define GPIO_92 (GPIO_BANK1_CONTROL + 0x70)
#define GPIO_93 (GPIO_BANK1_CONTROL + 0x74)
#define GPIO_95 (GPIO_BANK1_CONTROL + 0x7C)
#define GPIO_96 (GPIO_BANK1_CONTROL + 0x80)
#define GPIO_97 (GPIO_BANK1_CONTROL + 0x84)
#define GPIO_98 (GPIO_BANK1_CONTROL + 0x88)
#define GPIO_99 (GPIO_BANK1_CONTROL + 0x8C)
#define GPIO_100 (GPIO_BANK1_CONTROL + 0x90)
#define GPIO_101 (GPIO_BANK1_CONTROL + 0x94)
#define GPIO_102 (GPIO_BANK1_CONTROL + 0x98)
#define GPIO_113 (GPIO_BANK1_CONTROL + 0xC4)
#define GPIO_114 (GPIO_BANK1_CONTROL + 0xC8)
#define GPIO_115 (GPIO_BANK1_CONTROL + 0xCC)
#define GPIO_116 (GPIO_BANK1_CONTROL + 0xD0)
#define GPIO_117 (GPIO_BANK1_CONTROL + 0xD4)
#define GPIO_118 (GPIO_BANK1_CONTROL + 0xD8)
#define GPIO_119 (GPIO_BANK1_CONTROL + 0xDC)
#define GPIO_120 (GPIO_BANK1_CONTROL + 0xE0)
#define GPIO_121 (GPIO_BANK1_CONTROL + 0xE4)
#define GPIO_122 (GPIO_BANK1_CONTROL + 0xE8)
#define GPIO_126 (GPIO_BANK1_CONTROL + 0xF8)
/* GPIO_128 - GPIO_183 */
#define GPIO_BANK2_CONTROL (AMD_SB_ACPI_MMIO_ADDR + 0x1700)
#define GPIO_129 (GPIO_BANK2_CONTROL + 0x04)
#define GPIO_130 (GPIO_BANK2_CONTROL + 0x08)
#define GPIO_131 (GPIO_BANK2_CONTROL + 0x0C)
#define GPIO_132 (GPIO_BANK2_CONTROL + 0x10)
#define GPIO_133 (GPIO_BANK2_CONTROL + 0x14)
#define GPIO_134 (GPIO_BANK2_CONTROL + 0x18)
#define GPIO_135 (GPIO_BANK2_CONTROL + 0x1C)
#define GPIO_136 (GPIO_BANK2_CONTROL + 0x20)
#define GPIO_137 (GPIO_BANK2_CONTROL + 0x24)
#define GPIO_138 (GPIO_BANK2_CONTROL + 0x28)
#define GPIO_139 (GPIO_BANK2_CONTROL + 0x2C)
#define GPIO_140 (GPIO_BANK2_CONTROL + 0x30)
#define GPIO_141 (GPIO_BANK2_CONTROL + 0x34)
#define GPIO_142 (GPIO_BANK2_CONTROL + 0x38)
#define GPIO_143 (GPIO_BANK2_CONTROL + 0x3C)
#define GPIO_144 (GPIO_BANK2_CONTROL + 0x40)
#define GPIO_145 (GPIO_BANK2_CONTROL + 0x44)
#define GPIO_146 (GPIO_BANK2_CONTROL + 0x48)
#define GPIO_147 (GPIO_BANK2_CONTROL + 0x4C)
#define GPIO_148 (GPIO_BANK2_CONTROL + 0x50)
typedef uint32_t gpio_t;
int gpio_get(gpio_t gpio_num);
#endif /* _STONEYRIDGE_GPIO_H_ */

View File

@ -0,0 +1,198 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 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 <arch/io.h>
#include <types.h>
#include <device/pci_ids.h>
#include <device/device.h>
#include "chip.h"
/* Offsets from ACPI_MMIO_BASE
* This is defined by AGESA, but we don't include AGESA headers to avoid
* polluting the namespace.
*/
#define PM_MMIO_BASE 0xfed80300
/* Power management index/data registers */
#define BIOSRAM_INDEX 0xcd4
#define BIOSRAM_DATA 0xcd5
#define PM_INDEX 0xcd6
#define PM_DATA 0xcd7
#define PM2_INDEX 0xcd0
#define PM2_DATA 0xcd1
#define PM_ACPI_MMIO_EN 0x24
#define PM_SERIRQ_CONF 0x54
#define PM_EVT_BLK 0x60
#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_PMIO_DEBUG 0xD2
#define PM_MANUAL_RESET 0xD3
#define PM_HUD_SD_FLASH_CTRL 0xE7
#define PM_YANG_SD_FLASH_CTRL 0xE8
#define PM_PCIB_CFG 0xEA
#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_CNT_BLK (STONEYRIDGE_ACPI_IO_BASE + 0x04) /* 2 bytes */
#define ACPI_PM_TMR_BLK (STONEYRIDGE_ACPI_IO_BASE + 0x18) /* 4 bytes */
#define ACPI_GPE0_BLK (STONEYRIDGE_ACPI_IO_BASE + 0x10) /* 8 bytes */
#define ACPI_CPU_CONTROL (STONEYRIDGE_ACPI_IO_BASE + 0x08) /* 6 bytes */
#define ACPI_SMI_CTL_PORT 0xb2
#define ACPI_SMI_CMD_CST_CONTROL 0xde
#define ACPI_SMI_CMD_PST_CONTROL 0xad
#define ACPI_SMI_CMD_DISABLE 0xbe
#define ACPI_SMI_CMD_ENABLE 0xef
#define ACPI_SMI_CMD_S4_REQ 0xc0
#define REV_STONEYRIDGE_A11 0x11
#define REV_STONEYRIDGE_A12 0x12
#define SPIROM_BASE_ADDRESS_REGISTER 0xA0
#define ROUTE_TPM_2_SPI BIT(3)
#define SPI_ROM_ENABLE 0x02
#define SPI_BASE_ADDRESS 0xFEC10000
#define LPC_IO_PORT_DECODE_ENABLE 0x44
#define DECODE_ENABLE_PARALLEL_PORT0 BIT(0)
#define DECODE_ENABLE_PARALLEL_PORT1 BIT(1)
#define DECODE_ENABLE_PARALLEL_PORT2 BIT(2)
#define DECODE_ENABLE_PARALLEL_PORT3 BIT(3)
#define DECODE_ENABLE_PARALLEL_PORT4 BIT(4)
#define DECODE_ENABLE_PARALLEL_PORT5 BIT(5)
#define DECODE_ENABLE_SERIAL_PORT0 BIT(6)
#define DECODE_ENABLE_SERIAL_PORT1 BIT(7)
#define DECODE_ENABLE_SERIAL_PORT2 BIT(8)
#define DECODE_ENABLE_SERIAL_PORT3 BIT(9)
#define DECODE_ENABLE_SERIAL_PORT4 BIT(10)
#define DECODE_ENABLE_SERIAL_PORT5 BIT(11)
#define DECODE_ENABLE_SERIAL_PORT6 BIT(12)
#define DECODE_ENABLE_SERIAL_PORT7 BIT(13)
#define DECODE_ENABLE_AUDIO_PORT0 BIT(14)
#define DECODE_ENABLE_AUDIO_PORT1 BIT(15)
#define DECODE_ENABLE_AUDIO_PORT2 BIT(16)
#define DECODE_ENABLE_AUDIO_PORT3 BIT(17)
#define DECODE_ENABLE_MIDI_PORT0 BIT(18)
#define DECODE_ENABLE_MIDI_PORT1 BIT(19)
#define DECODE_ENABLE_MIDI_PORT2 BIT(20)
#define DECODE_ENABLE_MIDI_PORT3 BIT(21)
#define DECODE_ENABLE_MSS_PORT0 BIT(22)
#define DECODE_ENABLE_MSS_PORT1 BIT(23)
#define DECODE_ENABLE_MSS_PORT2 BIT(24)
#define DECODE_ENABLE_MSS_PORT3 BIT(25)
#define DECODE_ENABLE_FDC_PORT0 BIT(26)
#define DECODE_ENABLE_FDC_PORT1 BIT(27)
#define DECODE_ENABLE_GAME_PORT BIT(28)
#define DECODE_ENABLE_KBC_PORT BIT(29)
#define DECODE_ENABLE_ACPIUC_PORT BIT(30)
#define DECODE_ENABLE_ADLIB_PORT BIT(31)
#define LPC_IO_OR_MEM_DECODE_ENABLE 0x48
#define LPC_WIDEIO2_ENABLE BIT(25)
#define LPC_WIDEIO1_ENABLE BIT(24)
#define LPC_WIDEIO0_ENABLE BIT(2)
#define LPC_WIDEIO_GENERIC_PORT 0x64
#define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74
#define LPC_ALT_WIDEIO2_ENABLE BIT(3)
#define LPC_ALT_WIDEIO1_ENABLE BIT(2)
#define LPC_ALT_WIDEIO0_ENABLE BIT(0)
#define LPC_WIDEIO2_GENERIC_PORT 0x90
#define SPI_CNTRL0 0x00
#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) )
/* Nominal and SPI_READ_MODE_FAST_HUDSON1 are the only valid choices for H1 */
#define SPI_READ_MODE_FAST_HUDSON1 ( BIT(18))
#define SPI_READ_MODE_FAST (BIT(30) | BIT(29) | BIT(18))
#define SPI_ARB_ENABLE BIT(19)
#define SPI_CNTRL1 0x0c
/* Use SPI_SPEED_16M-SPI_SPEED_66M below for hudson and bolton */
#define SPI_CNTRL1_SPEED_MASK (BIT(15) | BIT(14) | BIT(13) | BIT(12))
#define SPI_NORM_SPEED_SH 12
#define SPI_FAST_SPEED_SH 8
#define SPI100_ENABLE 0x20
#define SPI_USE_SPI100 BIT(0)
#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)
static inline int hudson_sata_enable(void)
{
/* True if IDE or AHCI. */
return (CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 2);
}
static inline int hudson_ide_enable(void)
{
/* True if IDE or LEGACY IDE. */
return (CONFIG_STONEYRIDGE_SATA_MODE == 0) || (CONFIG_STONEYRIDGE_SATA_MODE == 3);
}
void configure_hudson_uart(void);
void hudson_clk_output_48Mhz(void);
void hudson_disable_4dw_burst(void);
void hudson_enable(device_t dev);
void hudson_final(void *chip_info);
void hudson_init(void *chip_info);
void hudson_lpc_port80(void);
void hudson_lpc_decode(void);
void hudson_pci_port80(void);
void hudson_read_mode(u32 mode);
void hudson_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm);
void hudson_set_readspeed(u16 norm, u16 fast);
void hudson_tpm_decode_spi(void);
void lpc_wideio_512_window(uint16_t base);
void lpc_wideio_16_window(uint16_t base);
u8 pm_read8(u8 reg);
u16 pm_read16(u16 reg);
void pm_write8(u8 reg, u8 value);
void pm_write16(u8 reg, u16 value);
int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);
void s3_resume_init_data(void *FchParams);
int s3_save_nvram_early(u32 dword, int size, int nvram_pos);
#endif /* STONEYRIDGE_H */

View File

@ -0,0 +1,27 @@
/*
* 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.
*/
#ifndef STONEYRIDGE_IMC_H
#define STONEYRIDGE_IMC_H
#include <Porting.h>
#include <AGESA.h>
#include <FchCommonCfg.h>
void imc_reg_init(void);
void enable_imc_thermal_zone(void);
void oem_fan_control(FCH_DATA_BLOCK *FchParams);
#endif

View File

@ -0,0 +1,122 @@
/*
* 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_
#define BUS0 0
/* XHCI */
#define XHCI_DEV 0x10
#define XHCI_FUNC 0
#define XHCI_DEVID 0x7814
#define XHCI_DEVFN PCI_DEVFN(XHCI_DEV,XHCI_FUNC)
#define XHCI2_DEV 0x10
#define XHCI2_FUNC 1
#define XHCI2_DEVID 0x7814
#define XHCI2_DEVFN PCI_DEVFN(XHCI2_DEV,XHCI2_FUNC)
/* SATA */
#define SATA_DEV 0x11
#define SATA_FUNC 0
#define SATA_IDE_DEVID 0x7800
#define AHCI_DEVID_MS 0x7801
#define AHCI_DEVID_AMD 0x7804
#define SATA_DEVFN PCI_DEVFN(SATA_DEV,SATA_FUNC)
/* OHCI */
#define OHCI1_DEV 0x12
#define OHCI1_FUNC 0
#define OHCI2_DEV 0x13
#define OHCI2_FUNC 0
#define OHCI3_DEV 0x16
#define OHCI3_FUNC 0
#define OHCI4_DEV 0x14
#define OHCI4_FUNC 5
#define OHCI_DEVID 0x7807
#define OHCI1_DEVFN PCI_DEVFN(OHCI1_DEV,OHCI1_FUNC)
#define OHCI2_DEVFN PCI_DEVFN(OHCI2_DEV,OHCI2_FUNC)
#define OHCI3_DEVFN PCI_DEVFN(OHCI3_DEV,OHCI3_FUNC)
#define OHCI4_DEVFN PCI_DEVFN(OHCI4_DEV,OHCI4_FUNC)
/* EHCI */
#define EHCI1_DEV 0x12
#define EHCI1_FUNC 2
#define EHCI2_DEV 0x13
#define EHCI2_FUNC 2
#define EHCI3_DEV 0x16
#define EHCI3_FUNC 2
#define EHCI_DEVID 0x7808
#define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV,EHCI1_FUNC)
#define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV,EHCI2_FUNC)
#define EHCI3_DEVFN PCI_DEVFN(EHCI3_DEV,EHCI3_FUNC)
/* SMBUS */
#define SMBUS_DEV 0x14
#define SMBUS_FUNC 0
#define SMBUS_DEVID 0x780B
#define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV,SMBUS_FUNC)
/* IDE */
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_PI_BOLTON)
#define IDE_DEV 0x14
#define IDE_FUNC 1
#define IDE_DEVID 0x780C
#define IDE_DEVFN PCI_DEVFN(IDE_DEV,IDE_FUNC)
#endif
/* HD Audio */
#define HDA_DEV 0x14
#define HDA_FUNC 2
#define HDA_DEVID 0x780D
#define HDA_DEVFN PCI_DEVFN(HDA_DEV,HDA_FUNC)
/* LPC BUS */
#define PCU_DEV 0x14
#define LPC_FUNC 3
#define LPC_DEVID 0x780E
#define LPC_DEVFN PCI_DEVFN(LPC_DEV,LPC_FUNC)
/* PCI Ports */
#define SB_PCI_PORT_DEV 0x14
#define SB_PCI_PORT_FUNC 4
#define SB_PCI_PORT_DEVID 0x780F
#define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV,SB_PCI_PORT_FUNC)
/* SD Controller */
#define SD_DEV 0x14
#define SD_FUNC 7
#define SD_DEVID 0x7806
#define SD_DEVFN PCI_DEVFN(SD_DEV,SD_FUNC)
/* PCIe Ports */
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_PI_BOLTON)
#define SB_PCIE_DEV 0x15
#define SB_PCIE_PORT1_FUNC 0
#define SB_PCIE_PORT2_FUNC 1
#define SB_PCIE_PORT3_FUNC 2
#define SB_PCIE_PORT4_FUNC 3
#define SB_PCIE_PORT1_DEVID 0x7820
#define SB_PCIE_PORT2_DEVID 0x7821
#define SB_PCIE_PORT3_DEVID 0x7822
#define SB_PCIE_PORT4_DEVID 0x7823
#define SB_PCIE_PORT1_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT1_FUNC)
#define SB_PCIE_PORT2_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT2_FUNC)
#define SB_PCIE_PORT3_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT3_FUNC)
#define SB_PCIE_PORT4_DEVFN PCI_DEVFN(SB_PCIE_DEV,SB_PCIE_PORT4_FUNC)
#endif
#endif /* _PI_STONEYRIDGE_PCI_DEVS_H_ */

View File

@ -0,0 +1,70 @@
/*
* 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>
#define SMBHSTSTAT 0x0
#define SMBSLVSTAT 0x1
#define SMBHSTCTRL 0x2
#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 AX_INDXC 0
#define AX_INDXP 2
#define AXCFG 4
#define ABCFG 6
#define RC_INDXC 1
#define RC_INDXP 3
#define AB_INDX 0xCD8
#define AB_DATA (AB_INDX+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)
#define abcfg_reg(reg, mask, val) \
alink_ab_indx((ABCFG), (reg), (mask), (val))
#define axcfg_reg(reg, mask, val) \
alink_ab_indx((AXCFG), (reg), (mask), (val))
#define axindxc_reg(reg, mask, val) \
alink_ax_indx((AX_INDXC), (reg), (mask), (val))
#define axindxp_reg(reg, mask, val) \
alink_ax_indx((AX_INDXP), (reg), (mask), (val))
#define rcindxc_reg(reg, port, mask, val) \
alink_rc_indx((RC_INDXC), (reg), (port), (mask), (val))
#define rcindxp_reg(reg, port, mask, val) \
alink_rc_indx((RC_INDXP), (reg), (port), (mask), (val))
int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
void alink_rc_indx(u32 reg_space, u32 reg_addr, u32 port, u32 mask, u32 val);
void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val);
void alink_ax_indx(u32 space /*c or p? */ , u32 axindc, u32 mask, u32 val);
#endif /* STONEYRIDGE_SMBUS_H */

View File

@ -0,0 +1,65 @@
/*
* Utilities for SMI handlers and SMM setup
*
* Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
* Subject to the GNU GPL v2, or (at your option) any later version.
*/
#ifndef _SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H
#define _SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H
#include <arch/io.h>
/* ACPI_MMIO_BASE + 0x200 -- leave this string here so grep catches it.
* This is defined by AGESA, but we dpn't include AGESA headers to avoid
* polluting the namesace.
*/
#define SMI_BASE 0xfed80200
#define SMI_REG_SMITRIG0 0x98
#define SMITRG0_EOS (1 << 28)
#define SMITRG0_SMIENB (1 << 31)
#define SMI_REG_CONTROL0 0xa0
enum smi_mode {
SMI_MODE_DISABLE = 0,
SMI_MODE_SMI = 1,
SMI_MODE_NMI = 2,
SMI_MODE_IRQ13 = 3,
};
enum smi_lvl {
SMI_LVL_LOW = 0,
SMI_LVL_HIGH = 1,
};
static inline uint32_t smi_read32(uint8_t offset)
{
return read32((void *)(SMI_BASE + offset));
}
static inline void smi_write32(uint8_t offset, uint32_t value)
{
write32((void *)(SMI_BASE + offset), value);
}
static inline uint16_t smi_read16(uint8_t offset)
{
return read16((void *)(SMI_BASE + offset));
}
static inline void smi_write16(uint8_t offset, uint16_t value)
{
write16((void *)(SMI_BASE + offset), value);
}
void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level);
void hudson_disable_gevent_smi(uint8_t gevent);
void hudson_enable_acpi_cmd_smi(void);
#ifndef __SMM__
void hudson_enable_smi_generation(void);
#endif
#endif /* _SOUTHBRIDGE_AMD_PI_STONEYRIDGE_SMI_H */

View File

@ -0,0 +1,366 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 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.
*/
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pnp.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <pc80/mc146818rtc.h>
#include <pc80/isa-dma.h>
#include <arch/io.h>
#include <arch/ioapic.h>
#include <arch/acpi.h>
#include <pc80/i8254.h>
#include <pc80/i8259.h>
#include <soc/hudson.h>
#include <vboot/vbnv.h>
static void lpc_init(device_t dev)
{
u8 byte;
u32 dword;
device_t sm_dev;
/* Enable the LPC Controller */
sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
dword = pci_read_config32(sm_dev, 0x64);
dword |= 1 << 20;
pci_write_config32(sm_dev, 0x64, dword);
/* Initialize isa dma */
isa_dma_init();
/* Enable DMA transaction on the LPC bus */
byte = pci_read_config8(dev, 0x40);
byte |= (1 << 2);
pci_write_config8(dev, 0x40, byte);
/* Disable the timeout mechanism on LPC */
byte = pci_read_config8(dev, 0x48);
byte &= ~(1 << 7);
pci_write_config8(dev, 0x48, byte);
/* Disable LPC MSI Capability */
byte = pci_read_config8(dev, 0x78);
byte &= ~(1 << 1);
byte &= ~(1 << 0); /* Keep the old way. i.e., when bus master/DMA cycle is going
on on LPC, it holds PCI grant, so no LPC slave cycle can
interrupt and visit LPC. */
pci_write_config8(dev, 0x78, byte);
/* bit0: Enable prefetch a cacheline (64 bytes) when Host reads code from SPI ROM */
/* bit3: Fix SPI_CS# timing issue when running at 66M. TODO:A12. */
byte = pci_read_config8(dev, 0xBB);
byte |= 1 << 0 | 1 << 3;
pci_write_config8(dev, 0xBB, byte);
cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
* update CMOS unless it is invalid.
* 1 tells cmos_init to always initialize the CMOS.
*/
if (IS_ENABLED(CONFIG_VBOOT_VBNV_CMOS))
init_vbnv_cmos(0);
else
cmos_init(0);
/* Initialize i8259 pic */
setup_i8259 ();
/* Initialize i8254 timers */
setup_i8254 ();
/* Set up SERIRQ, enable continuous mode */
byte = (BIT(4) | BIT(7));
if (!IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE))
byte |= BIT(6);
pm_write8(PM_SERIRQ_CONF, byte);
}
static void hudson_lpc_read_resources(device_t dev)
{
struct resource *res;
/* Get the normal pci resources of this device */
pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
/* Add an extra subtractive resource for both memory and I/O. */
res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
res->base = 0;
res->size = 0x1000;
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
res->base = 0xff800000;
res->size = 0x00800000; /* 8 MB for flash */
res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
/* Add a memory resource for the SPI BAR. */
fixed_mem_resource(dev, 2, SPI_BASE_ADDRESS / 1024, 1, IORESOURCE_SUBTRACTIVE);
res = new_resource(dev, 3); /* IOAPIC */
res->base = IO_APIC_ADDR;
res->size = 0x00001000;
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
compact_resources(dev);
}
static void hudson_lpc_set_resources(struct device *dev)
{
struct resource *res;
u32 spi_enable_bits;
/* Special case. The SpiRomEnable and other enables should STAY set. */
res = find_resource(dev, 2);
spi_enable_bits = pci_read_config32(dev, SPIROM_BASE_ADDRESS_REGISTER);
spi_enable_bits &= 0xF;
pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, res->base | spi_enable_bits);
pci_dev_set_resources(dev);
}
/**
* @brief Enable resources for children devices
*
* @param dev the device whose children's resources are to be enabled
*
*/
static void hudson_lpc_enable_childrens_resources(device_t dev)
{
struct bus *link;
u32 reg, reg_x;
int var_num = 0;
u16 reg_var[3];
u16 reg_size[1] = {512};
u8 wiosize = pci_read_config8(dev, 0x74);
/* Be bit relaxed, tolerate that LPC region might be bigger than resource we try to fit,
* do it like this for all regions < 16 bytes. If there is a resource > 16 bytes
* it must be 512 bytes to be able to allocate the fresh LPC window.
*
* AGESA likes to enable already one LPC region in wide port base 0x64-0x65,
* using DFLT_SIO_PME_BASE_ADDRESS, 512 bytes size
* The code tries to check if resource can fit into this region
*/
reg = pci_read_config32(dev, 0x44);
reg_x = pci_read_config32(dev, 0x48);
/* check if ranges are free and not use them if entry is just already taken */
if (reg_x & (1 << 2))
var_num = 1;
/* just in case check if someone did not manually set other ranges too */
if (reg_x & (1 << 24))
var_num = 2;
if (reg_x & (1 << 25))
var_num = 3;
/* check AGESA region size */
if (wiosize & (1 << 0))
reg_size[0] = 16;
reg_var[2] = pci_read_config16(dev, 0x90);
reg_var[1] = pci_read_config16(dev, 0x66);
reg_var[0] = pci_read_config16(dev, 0x64);
for (link = dev->link_list; link; link = link->next) {
device_t child;
for (child = link->children; child;
child = child->sibling) {
if (child->enabled
&& (child->path.type == DEVICE_PATH_PNP)) {
struct resource *res;
for (res = child->resource_list; res; res = res->next) {
u32 base, end; /* don't need long long */
u32 rsize, set = 0, set_x = 0;
if (!(res->flags & IORESOURCE_IO))
continue;
base = res->base;
end = resource_end(res);
/* find a resource size */
printk(BIOS_DEBUG, "hudson lpc decode:%s, base=0x%08x, end=0x%08x\n",
dev_path(child), base, end);
switch (base) {
case 0x60: /* KB */
case 0x64: /* MS */
set |= (1 << 29);
rsize = 1;
break;
case 0x3f8: /* COM1 */
set |= (1 << 6);
rsize = 8;
break;
case 0x2f8: /* COM2 */
set |= (1 << 7);
rsize = 8;
break;
case 0x378: /* Parallel 1 */
set |= (1 << 0);
set |= (1 << 1); /* + 0x778 for ECP */
rsize = 8;
break;
case 0x3f0: /* FD0 */
set |= (1 << 26);
rsize = 8;
break;
case 0x220: /* 0x220 - 0x227 */
set |= (1 << 8);
rsize = 8;
break;
case 0x228: /* 0x228 - 0x22f */
set |= (1 << 9);
rsize = 8;
break;
case 0x238: /* 0x238 - 0x23f */
set |= (1 << 10);
rsize = 8;
break;
case 0x300: /* 0x300 -0x301 */
set |= (1 << 18);
rsize = 2;
break;
case 0x400:
set_x |= (1 << 16);
rsize = 0x40;
break;
case 0x480:
set_x |= (1 << 17);
rsize = 0x40;
break;
case 0x500:
set_x |= (1 << 18);
rsize = 0x40;
break;
case 0x580:
set_x |= (1 << 19);
rsize = 0x40;
break;
case 0x4700:
set_x |= (1 << 22);
rsize = 0xc;
break;
case 0xfd60:
set_x |= (1 << 23);
rsize = 16;
break;
default:
rsize = 0;
/* try AGESA allocated region in region 0 */
if ((var_num > 0) && ((base >=reg_var[0]) &&
((base + res->size) <= (reg_var[0] + reg_size[0]))))
rsize = reg_size[0];
}
/* check if region found and matches the enable */
if (res->size <= rsize) {
reg |= set;
reg_x |= set_x;
/* check if we can fit resource in variable range */
} else if ((var_num < 3) &&
((res->size <= 16) || (res->size == 512))) {
/* use variable ranges if pre-defined do not match */
switch (var_num) {
case 0:
reg_x |= (1 << 2);
if (res->size <= 16) {
wiosize |= (1 << 0);
}
break;
case 1:
reg_x |= (1 << 24);
if (res->size <= 16)
wiosize |= (1 << 2);
break;
case 2:
reg_x |= (1 << 25);
if (res->size <= 16)
wiosize |= (1 << 3);
break;
}
reg_var[var_num++] =
base & 0xffff;
} else {
printk(BIOS_ERR, "cannot fit LPC decode region:%s, base=0x%08x, end=0x%08x\n",
dev_path(child), base, end);
}
}
}
}
}
pci_write_config32(dev, 0x44, reg);
pci_write_config32(dev, 0x48, reg_x);
/* Set WideIO for as many IOs found (fall through is on purpose) */
switch (var_num) {
case 3:
pci_write_config16(dev, 0x90, reg_var[2]);
/* fall through */
case 2:
pci_write_config16(dev, 0x66, reg_var[1]);
/* fall through */
case 1:
pci_write_config16(dev, 0x64, reg_var[0]);
break;
}
pci_write_config8(dev, 0x74, wiosize);
}
static void hudson_lpc_enable_resources(device_t dev)
{
pci_dev_enable_resources(dev);
hudson_lpc_enable_childrens_resources(dev);
}
unsigned long acpi_fill_mcfg(unsigned long current)
{
/* Just a dummy */
return current;
}
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
};
static struct device_operations lpc_ops = {
.read_resources = hudson_lpc_read_resources,
.set_resources = hudson_lpc_set_resources,
.enable_resources = hudson_lpc_enable_resources,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.write_acpi_tables = acpi_write_hpet,
#endif
.init = lpc_init,
.scan_bus = scan_lpc_bus,
.ops_pci = &lops_pci,
};
static const unsigned short pci_device_ids[] = {
PCI_DEVICE_ID_AMD_SB900_LPC,
PCI_DEVICE_ID_AMD_CZ_LPC,
0
};
static const struct pci_driver lpc_driver __pci_driver = {
.ops = &lpc_ops,
.vendor = PCI_VENDOR_ID_AMD,
.devices = pci_device_ids,
};

View File

@ -0,0 +1,67 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 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.
*/
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <soc/hudson.h>
#include <amd_pci_util.h>
#include <bootstate.h>
static void pci_init(struct device *dev)
{
}
/*
* 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);
static struct pci_operations lops_pci = {
.set_subsystem = 0,
};
static struct device_operations pci_ops = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = pci_init,
.scan_bus = pci_scan_bridge,
.reset_bus = pci_bus_reset,
.ops_pci = &lops_pci,
};
static const struct pci_driver pci_driver __pci_driver = {
.ops = &pci_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_PCI,
};

View File

@ -0,0 +1,61 @@
/*
* 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 <soc/hudson.h>
static void pcie_init(struct device *dev)
{
}
static struct pci_operations lops_pci = {
.set_subsystem = 0,
};
static struct device_operations pci_ops = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = pcie_init,
.scan_bus = pci_scan_bridge,
.reset_bus = pci_bus_reset,
.ops_pci = &lops_pci,
};
static const struct pci_driver pciea_driver __pci_driver = {
.ops = &pci_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_PCIEA,
};
static const struct pci_driver pcieb_driver __pci_driver = {
.ops = &pci_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_PCIEB,
};
static const struct pci_driver pciec_driver __pci_driver = {
.ops = &pci_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_PCIEC,
};
static const struct pci_driver pcied_driver __pci_driver = {
.ops = &pci_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_SB900_PCIED,
};

View File

@ -0,0 +1,45 @@
/*
* 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 <arch/io.h>
#include <reset.h>
#define HT_INIT_CONTROL 0x6C
#define HTIC_BIOSR_Detect (1 << 5)
static void set_bios_reset(void)
{
u32 htic;
htic = pci_io_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
htic &= ~HTIC_BIOSR_Detect;
pci_io_write_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL, htic);
}
void do_hard_reset(void)
{
set_bios_reset();
/* Try rebooting through port 0xcf9 */
/*
* Actually it is not a real hard_reset
* --- it only reset coherent link table,
* but not reset link freq and width
*/
outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
}

View File

@ -0,0 +1,81 @@
/*
* 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 <delay.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include <soc/hudson.h>
static void sata_init(struct device *dev)
{
/**************************************
* Configure the SATA port multiplier *
**************************************/
#define BYTE_TO_DWORD_OFFSET(x) (x/4)
#define AHCI_BASE_ADDRESS_REG 0x24
#define MISC_CONTROL_REG 0x40
#define UNLOCK_BIT (1<<0)
#define SATA_CAPABILITIES_REG 0xFC
#define CFG_CAP_SPM (1<<12)
volatile u32 *ahci_ptr =
(u32*)(pci_read_config32(dev, AHCI_BASE_ADDRESS_REG) & 0xFFFFFF00);
u32 temp;
/* unlock the write-protect */
temp = pci_read_config32(dev, MISC_CONTROL_REG);
temp |= UNLOCK_BIT;
pci_write_config32(dev, MISC_CONTROL_REG, temp);
/* set the SATA AHCI mode to allow port expanders */
*(ahci_ptr + BYTE_TO_DWORD_OFFSET(SATA_CAPABILITIES_REG)) |= CFG_CAP_SPM;
/* lock the write-protect */
temp = pci_read_config32(dev, MISC_CONTROL_REG);
temp &= ~UNLOCK_BIT;
pci_write_config32(dev, MISC_CONTROL_REG, temp);
};
static struct pci_operations lops_pci = {
/* .set_subsystem = pci_dev_set_subsystem, */
};
static struct device_operations sata_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = sata_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
static const unsigned short pci_device_ids[] = {
PCI_DEVICE_ID_AMD_SB900_SATA,
PCI_DEVICE_ID_AMD_SB900_SATA_AHCI,
PCI_DEVICE_ID_AMD_CZ_SATA,
PCI_DEVICE_ID_AMD_CZ_SATA_AHCI,
0
};
static const struct pci_driver sata0_driver __pci_driver = {
.ops = &sata_ops,
.vendor = PCI_VENDOR_ID_AMD,
.devices = pci_device_ids,
};

View File

@ -0,0 +1,65 @@
/*
* 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.
*/
#include <device/device.h>
#include <delay.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include <soc/hudson.h>
static void sd_init(struct device *dev)
{
u32 stepping;
stepping = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xFC);
struct soc_amd_stoneyridge_config *sd_chip =
(struct soc_amd_stoneyridge_config *)(dev->chip_info);
if (sd_chip->sd_mode == 3) { /* SD 3.0 mode */
pci_write_config32(dev, 0xA4, 0x31FEC8B2);
pci_write_config32(dev, 0xA8, 0x00002503);
pci_write_config32(dev, 0xB0, 0x02180C19);
pci_write_config32(dev, 0xD0, 0x0000078B);
}
else { /* SD 2.0 mode */
if ((stepping & 0x0000000F) == 0) { /* Stepping A0 */
pci_write_config32(dev, 0xA4, 0x31DE32B2);
pci_write_config32(dev, 0xB0, 0x01180C19);
pci_write_config32(dev, 0xD0, 0x0000058B);
}
else { /* Stepping >= A1 */
pci_write_config32(dev, 0xA4, 0x31FE3FB2);
pci_write_config32(dev, 0xB0, 0x01180C19);
pci_write_config32(dev, 0xD0, 0x0000078B);
}
}
}
static struct device_operations sd_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = sd_init,
.scan_bus = 0,
};
static const struct pci_driver sd_driver __pci_driver = {
.ops = &sd_ops,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_YANGTZE_SD,
};

View File

@ -0,0 +1,135 @@
/*
* 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/smbus.h>
#include <pc80/mc146818rtc.h>
#include <arch/io.h>
#include <cpu/x86/lapic.h>
#include <arch/ioapic.h>
#include <stdlib.h>
#include <soc/hudson.h>
#include <soc/smbus.h>
#define NMI_OFF 0
#define MAINBOARD_POWER_OFF 0
#define MAINBOARD_POWER_ON 1
#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
#endif
/*
* HUDSON enables all USB controllers by default in SMBUS Control.
* HUDSON enables SATA by default in SMBUS Control.
*/
static void sm_init(device_t dev)
{
setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS);
}
static int lsmbus_recv_byte(device_t dev)
{
u32 device;
struct resource *res;
struct bus *pbus;
device = dev->path.i2c.device;
pbus = get_pbus_smbus(dev);
res = find_resource(pbus->dev, 0x90);
return do_smbus_recv_byte(res->base, device);
}
static int lsmbus_send_byte(device_t dev, u8 val)
{
u32 device;
struct resource *res;
struct bus *pbus;
device = dev->path.i2c.device;
pbus = get_pbus_smbus(dev);
res = find_resource(pbus->dev, 0x90);
return do_smbus_send_byte(res->base, device, val);
}
static int lsmbus_read_byte(device_t dev, u8 address)
{
u32 device;
struct resource *res;
struct bus *pbus;
device = dev->path.i2c.device;
pbus = get_pbus_smbus(dev);
res = find_resource(pbus->dev, 0x90);
return do_smbus_read_byte(res->base, device, address);
}
static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
{
u32 device;
struct resource *res;
struct bus *pbus;
device = dev->path.i2c.device;
pbus = get_pbus_smbus(dev);
res = find_resource(pbus->dev, 0x90);
return do_smbus_write_byte(res->base, 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 void hudson_sm_read_resources(device_t dev)
{
}
static void hudson_sm_set_resources(struct device *dev)
{
}
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
};
static struct device_operations smbus_ops = {
.read_resources = hudson_sm_read_resources,
.set_resources = hudson_sm_set_resources,
.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_SB900_SM,
};

View File

@ -0,0 +1,246 @@
/*
* 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_C_
#define _STONEYRIDGE_SMBUS_C_
#include <io.h>
#include <stdint.h>
#include <soc/smbus.h>
static int smbus_wait_until_ready(u32 smbus_io_base)
{
u32 loops;
loops = SMBUS_TIMEOUT;
do {
u8 val;
val = inb(smbus_io_base + SMBHSTSTAT);
val &= 0x1f;
if (val == 0) { /* ready now */
return 0;
}
outb(val, smbus_io_base + SMBHSTSTAT);
} while (--loops);
return -2; /* time out */
}
static int smbus_wait_until_done(u32 smbus_io_base)
{
u32 loops;
loops = SMBUS_TIMEOUT;
do {
u8 val;
val = inb(smbus_io_base + SMBHSTSTAT);
val &= 0x1f; /* mask off reserved bits */
if (val & 0x1c) {
return -5; /* error */
}
if (val == 0x02) {
outb(val, smbus_io_base + SMBHSTSTAT); /* clear status */
return 0;
}
} while (--loops);
return -3; /* timeout */
}
int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
{
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2; /* not ready */
}
/* set the device I'm talking too */
outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
byte = inb(smbus_io_base + SMBHSTCTRL);
byte &= 0xe3; /* Clear [4:2] */
byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
outb(byte, smbus_io_base + SMBHSTCTRL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3; /* timeout or error */
}
/* read results of transaction */
byte = inb(smbus_io_base + SMBHSTCMD);
return byte;
}
int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
{
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2; /* not ready */
}
/* set the command... */
outb(val, smbus_io_base + SMBHSTCMD);
/* set the device I'm talking too */
outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
byte = inb(smbus_io_base + SMBHSTCTRL);
byte &= 0xe3; /* Clear [4:2] */
byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
outb(byte, smbus_io_base + SMBHSTCTRL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3; /* timeout or error */
}
return 0;
}
int do_smbus_read_byte(u32 smbus_io_base, u32 device,
u32 address)
{
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2; /* not ready */
}
/* set the command/address... */
outb(address & 0xff, smbus_io_base + SMBHSTCMD);
/* set the device I'm talking too */
outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
byte = inb(smbus_io_base + SMBHSTCTRL);
byte &= 0xe3; /* Clear [4:2] */
byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
outb(byte, smbus_io_base + SMBHSTCTRL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3; /* timeout or error */
}
/* read results of transaction */
byte = inb(smbus_io_base + SMBHSTDAT0);
return byte;
}
int do_smbus_write_byte(u32 smbus_io_base, u32 device,
u32 address, u8 val)
{
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return -2; /* not ready */
}
/* set the command/address... */
outb(address & 0xff, smbus_io_base + SMBHSTCMD);
/* set the device I'm talking too */
outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
/* output value */
outb(val, smbus_io_base + SMBHSTDAT0);
byte = inb(smbus_io_base + SMBHSTCTRL);
byte &= 0xe3; /* Clear [4:2] */
byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
outb(byte, smbus_io_base + SMBHSTCTRL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return -3; /* timeout or error */
}
return 0;
}
void alink_ab_indx(u32 reg_space, u32 reg_addr,
u32 mask, u32 val)
{
u32 tmp;
outl((reg_space & 0x7) << 29 | reg_addr, AB_INDX);
tmp = inl(AB_DATA);
/* rpr 4.2
* For certain revisions of the chip, the ABCFG registers,
* with an address of 0x100NN (where 'N' is any hexadecimal
* number), require an extra programming step.*/
outl(0, AB_INDX);
tmp &= ~mask;
tmp |= val;
/* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | reg_addr); */
outl((reg_space & 0x7) << 29 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
outl(tmp, AB_DATA);
outl(0, AB_INDX);
}
void alink_rc_indx(u32 reg_space, u32 reg_addr, u32 port,
u32 mask, u32 val)
{
u32 tmp;
outl((reg_space & 0x7) << 29 | (port & 3) << 24 | reg_addr, AB_INDX);
tmp = inl(AB_DATA);
/* rpr 4.2
* For certain revisions of the chip, the ABCFG registers,
* with an address of 0x100NN (where 'N' is any hexadecimal
* number), require an extra programming step.*/
outl(0, AB_INDX);
tmp &= ~mask;
tmp |= val;
//printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | (port&3) << 24 | reg_addr);
outl((reg_space & 0x7) << 29 | (port & 3) << 24 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
outl(tmp, AB_DATA);
outl(0, AB_INDX);
}
/* space = 0: AX_INDXC, AX_DATAC
* space = 1: AX_INDXP, AX_DATAP
*/
void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
u32 mask, u32 val)
{
u32 tmp;
/* read axindc to tmp */
outl(space << 29 | space << 3 | 0x30, AB_INDX);
outl(axindc, AB_DATA);
outl(0, AB_INDX);
outl(space << 29 | space << 3 | 0x34, AB_INDX);
tmp = inl(AB_DATA);
outl(0, AB_INDX);
tmp &= ~mask;
tmp |= val;
/* write tmp */
outl(space << 29 | space << 3 | 0x30, AB_INDX);
outl(axindc, AB_DATA);
outl(0, AB_INDX);
outl(space << 29 | space << 3 | 0x34, AB_INDX);
outl(tmp, AB_DATA);
outl(0, AB_INDX);
}
#endif

View File

@ -0,0 +1,148 @@
/*
* 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 <device/pci_def.h>
#include <device/device.h>
/* warning: Porting.h includes an open #pragma pack(1) */
#include <Porting.h>
#include <AGESA.h>
#include <amdlib.h>
#include <northbridge/amd/pi/dimmSpd.h>
/*-----------------------------------------------------------------------------
*
* readSmbusByteData - read a single SPD byte from any offset
*/
static int readSmbusByteData (int iobase, int address, char *buffer, int offset)
{
unsigned int status;
UINT64 limit;
address |= 1; // set read bit
__outbyte (iobase + 0, 0xFF); // clear error status
__outbyte (iobase + 1, 0x1F); // clear error status
__outbyte (iobase + 3, offset); // offset in eeprom
__outbyte (iobase + 4, address); // slave address and read bit
__outbyte (iobase + 2, 0x48); // read byte command
// time limit to avoid hanging for unexpected error status (should never happen)
limit = __rdtsc () + 2000000000 / 10;
for (;;)
{
status = __inbyte (iobase);
if (__rdtsc () > limit) break;
if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
if ((status & 1) == 1) continue; // HostBusy set, keep waiting
break;
}
buffer [0] = __inbyte (iobase + 5);
if (status == 2) status = 0; // check for done with no errors
return status;
}
/*-----------------------------------------------------------------------------
*
* readSmbusByte - read a single SPD byte from the default offset
* this function is faster function readSmbusByteData
*/
static int readSmbusByte (int iobase, int address, char *buffer)
{
unsigned int status;
UINT64 limit;
__outbyte (iobase + 0, 0xFF); // clear error status
__outbyte (iobase + 2, 0x44); // read command
// time limit to avoid hanging for unexpected error status
limit = __rdtsc () + 2000000000 / 10;
for (;;)
{
status = __inbyte (iobase);
if (__rdtsc () > limit) break;
if ((status & 2) == 0) continue; // SMBusInterrupt not set, keep waiting
if ((status & 1) == 1) continue; // HostBusy set, keep waiting
break;
}
buffer [0] = __inbyte (iobase + 5);
if (status == 2) status = 0; // check for done with no errors
return status;
}
/*---------------------------------------------------------------------------
*
* 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 (int iobase, int SmbusSlaveAddress, char *buffer, int count)
{
int index, error;
printk(BIOS_SPEW, "-------------READING SPD-----------\n");
printk(BIOS_SPEW, "iobase: 0x%08X, SmbusSlave: 0x%08X, count: %d\n",
iobase, SmbusSlaveAddress, count);
/* read the first byte using offset zero */
error = readSmbusByteData (iobase, SmbusSlaveAddress, buffer, 0);
if (error) {
printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
return error;
}
/* read the remaining bytes using auto-increment for speed */
for (index = 1; index < count; index++)
{
error = readSmbusByte (iobase, SmbusSlaveAddress, &buffer [index]);
if (error) {
printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n");
return error;
}
}
printk(BIOS_SPEW, "\n");
printk(BIOS_SPEW, "-------------FINISHED READING SPD-----------\n");
return 0;
}
static void writePmReg (int reg, int data)
{
__outbyte (0xCD6, reg);
__outbyte (0xCD7, data);
}
static void setupFch (int ioBase)
{
writePmReg (0x2D, ioBase >> 8);
writePmReg (0x2C, ioBase | 1);
__outbyte (ioBase + 0x0E, 66000000 / 400000 / 4); // set SMBus clock to 400 KHz
}
int hudson_readSpd(int spdAddress, char *buf, size_t len)
{
int ioBase = 0xB00;
setupFch (ioBase);
return readspd (ioBase, spdAddress, buf, len);
}

View File

@ -0,0 +1,26 @@
/*
* Utilities for SMM setup
*
* Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
* Subject to the GNU GPL v2, or (at your option) any later version.
*/
#include <console/console.h>
#include <cpu/cpu.h>
#include <soc/smi.h>
void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
{
printk(BIOS_DEBUG, "smm_setup_structures STUB!!!\n");
}
/** Set the EOS bit and enable SMI generation from southbridge */
void hudson_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);
}

View File

@ -0,0 +1,78 @@
/*
* SMM utilities used in both SMM and normal mode
*
* Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
* Subject to the GNU GPL v2, or (at your option) any later version.
*/
#include <console/console.h>
#include <soc/smi.h>
#define STONEYRIDGE_SMI_ACPI_COMMAND 75
static void configure_smi(uint8_t smi_num, uint8_t mode)
{
uint8_t reg32_offset, bit_offset;
uint32_t reg32;
/* SMI sources range from [0:149] */
if (smi_num > 149) {
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_LVL_LOW or SMI_LVL_HIGH
*/
void hudson_configure_gevent_smi(uint8_t gevent, uint8_t mode, uint8_t level)
{
uint32_t reg32;
/* 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, 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);
}
/** Disable events from given GEVENT pin */
void hudson_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);
}
/** Enable SMIs on writes to ACPI SMI command port */
void hudson_enable_acpi_cmd_smi(void)
{
configure_smi(STONEYRIDGE_SMI_ACPI_COMMAND, SMI_MODE_SMI);
}

View File

@ -0,0 +1,136 @@
/*
* SMI handler for Hudson southbridges
*
* Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
* Subject to the GNU GPL v2, or (at your option) any later version.
*/
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <delay.h>
#include <soc/hudson.h>
#include <soc/smi.h>
#define SMI_0x88_ACPI_COMMAND (1 << 11)
enum smi_source {
SMI_SOURCE_SCI = (1 << 0),
SMI_SOURCE_GPE = (1 << 1),
SMI_SOURCE_0x84 = (1 << 2),
SMI_SOURCE_0x88 = (1 << 3),
SMI_SOURCE_IRQ_TRAP = (1 << 4),
SMI_SOURCE_0x90 = (1 << 5)
};
static void hudson_apmc_smi_handler(void)
{
u32 reg32;
const uint8_t cmd = inb(ACPI_SMI_CTL_PORT);
switch (cmd) {
case ACPI_SMI_CMD_ENABLE:
reg32 = inl(ACPI_PM1_CNT_BLK);
reg32 |= (1 << 0); /* SCI_EN */
outl(reg32, ACPI_PM1_CNT_BLK);
break;
case ACPI_SMI_CMD_DISABLE:
reg32 = inl(ACPI_PM1_CNT_BLK);
reg32 &= ~(1 << 0); /* clear SCI_EN */
outl(ACPI_PM1_CNT_BLK, reg32);
break;
}
mainboard_smi_apmc(cmd);
}
int southbridge_io_trap_handler(int smif)
{
return 0;
}
static void process_smi_sci(void)
{
const uint32_t status = smi_read32(0x10);
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x10, status);
}
static void process_gpe_smi(void)
{
const uint32_t status = smi_read32(0x80);
const uint32_t gevent_mask = (1 << 24) - 1;
/* Only Bits [23:0] indicate GEVENT SMIs. */
if (status & gevent_mask) {
/* A GEVENT SMI occurred */
mainboard_smi_gpi(status & gevent_mask);
}
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x80, status);
}
static void process_smi_0x84(void)
{
const uint32_t status = smi_read32(0x84);
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x84, status);
}
static void process_smi_0x88(void)
{
const uint32_t status = smi_read32(0x88);
if (status & SMI_0x88_ACPI_COMMAND) {
/* Command received via ACPI SMI command port */
hudson_apmc_smi_handler();
}
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x88, status);
}
static void process_smi_0x8c(void)
{
const uint32_t status = smi_read32(0x8c);
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x8c, status);
}
static void process_smi_0x90(void)
{
const uint32_t status = smi_read32(0x90);
/* Clear events to prevent re-entering SMI if event isn't handled */
smi_write32(0x90, status);
}
void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
{
const uint16_t smi_src = smi_read16(0x94);
if (smi_src & SMI_SOURCE_SCI)
process_smi_sci();
if (smi_src & SMI_SOURCE_GPE)
process_gpe_smi();
if (smi_src & SMI_SOURCE_0x84)
process_smi_0x84();
if (smi_src & SMI_SOURCE_0x88)
process_smi_0x88();
if (smi_src & SMI_SOURCE_IRQ_TRAP)
process_smi_0x8c();
if (smi_src & SMI_SOURCE_0x90)
process_smi_0x90();
}
void southbridge_smi_set_eos(void)
{
uint32_t reg = smi_read32(SMI_REG_SMITRIG0);
reg |= SMITRG0_EOS;
smi_write32(SMI_REG_SMITRIG0, reg);
}

View File

@ -0,0 +1,26 @@
/*
* 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>
uintptr_t uart_platform_base(int idx)
{
return (uintptr_t)(0xFEDC6000 + 0x2000 * (idx & 1));
}
unsigned int uart_platform_refclk(void)
{
return 48000000;
}

View File

@ -0,0 +1,56 @@
/*
* 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 <arch/io.h>
#include <soc/hudson.h>
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
};
static void usb_init(struct device *dev)
{
}
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 = usb_init,
.scan_bus = 0,
.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,
};

View File

@ -61,7 +61,12 @@ AGESA_INC += -I$(AGESA_ROOT)/Proc/IDS
endif
AGESA_INC += -I$(src)/northbridge/amd/pi
ifeq ($(CONFIG_SOC_AMD_STONEYRIDGE),y)
AGESA_INC += -I$(src)/soc/amd/stoneyridge/include
else
AGESA_INC += -I$(src)/southbridge/amd/pi/hudson
endif
AGESA_INC += -I$(src)/arch/x86/include
AGESA_INC += -I$(src)/include
@ -115,7 +120,7 @@ agesa_raw_files += $(wildcard $(AGESA_ROOT)/Proc/Fch/Kern/KernImc/*.[cS])
agesa_raw_files += $(wildcard $(AGESA_ROOT)/Proc/Fch/Common/*.[cS])
agesa_raw_files += $(wildcard $(AGESA_ROOT)/Proc/Psp/PspBaseLib/*.[cS])
endif
ifeq ($(CONFIG_HUDSON_IMC_FWM),y)
ifeq ($(CONFIG_HUDSON_IMC_FWM)$(CONFIG_STONEYRIDGE_IMC_FWM),y)
agesa_raw_files += $(wildcard $(src)/vendorcode/amd/pi/Lib/imc/*.c)
endif