diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-10-21 18:22:32 +0300 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-11-20 19:03:26 +0100 |
commit | e8b4da2f6f8b6fc38db82b1a2e1b9b9340ecfc53 (patch) | |
tree | cd666b7de5e9509ee8d20627dc7cb3f961426476 /src/southbridge | |
parent | e4c17ce8036ae247f5e73c37789a9181e7cbd3c7 (diff) |
AMD: Isolate AGESA and PI build environments for southbridge
To backport features introduced with recent Chromebooks and/or Intel
boards in general, heavy work on the AMD AGESA platform infrastructure
is required. With the AGESA PI available in binary form only, community
members have little means to verify, debug and develop for the said
platforms.
Thus it makes sense to fork the existing agesawrapper interfaces, to give
AMD PI platforms a clean and independent sandbox. New directory layout
reflects the separation already taken place under 3rdparty/ and vendorcode/.
Change-Id: Ia730f0e45e7c1bdfc0c91e95eb6729a77773e2b9
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/7388
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Reviewed-by: Bruce Griffith <Bruce.Griffith@se-eng.com>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/southbridge')
41 files changed, 4435 insertions, 2 deletions
diff --git a/src/southbridge/amd/Kconfig b/src/southbridge/amd/Kconfig index 867afcaf8b..d6c7ca294e 100644 --- a/src/southbridge/amd/Kconfig +++ b/src/southbridge/amd/Kconfig @@ -13,4 +13,5 @@ source src/southbridge/amd/sb700/Kconfig source src/southbridge/amd/sb800/Kconfig source src/southbridge/amd/cimx/Kconfig source src/southbridge/amd/agesa/Kconfig +source src/southbridge/amd/pi/Kconfig source src/southbridge/amd/sr5650/Kconfig diff --git a/src/southbridge/amd/Makefile.inc b/src/southbridge/amd/Makefile.inc index 0e3f78536a..56c66bd7fc 100644 --- a/src/southbridge/amd/Makefile.inc +++ b/src/southbridge/amd/Makefile.inc @@ -16,11 +16,11 @@ subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += cimx subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += cimx subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += agesa subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE) += agesa -subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_AVALON) += agesa +subdirs-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += pi ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB700) += amd_pci_util.c ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += amd_pci_util.c ramstage-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += amd_pci_util.c ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += amd_pci_util.c ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE) += amd_pci_util.c -ramstage-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_AVALON) += amd_pci_util.c +ramstage-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += amd_pci_util.c diff --git a/src/southbridge/amd/pi/Kconfig b/src/southbridge/amd/pi/Kconfig new file mode 100644 index 0000000000..a0438c87f3 --- /dev/null +++ b/src/southbridge/amd/pi/Kconfig @@ -0,0 +1,20 @@ +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +source src/southbridge/amd/pi/avalon/Kconfig diff --git a/src/southbridge/amd/pi/Makefile.inc b/src/southbridge/amd/pi/Makefile.inc new file mode 100644 index 0000000000..b7bcc7a450 --- /dev/null +++ b/src/southbridge/amd/pi/Makefile.inc @@ -0,0 +1,19 @@ +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +subdirs-$(CONFIG_SOUTHBRIDGE_AMD_PI_AVALON) += avalon diff --git a/src/southbridge/amd/pi/avalon/Kconfig b/src/southbridge/amd/pi/avalon/Kconfig new file mode 100644 index 0000000000..f9c39a7899 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/Kconfig @@ -0,0 +1,219 @@ +## +## 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. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config SOUTHBRIDGE_AMD_PI_AVALON + bool + select IOAPIC + select HAVE_USBDEBUG_OPTIONS + select HAVE_HARD_RESET + +if SOUTHBRIDGE_AMD_PI_AVALON + +config BOOTBLOCK_SOUTHBRIDGE_INIT + string + default "southbridge/amd/pi/avalon/bootblock.c" + +config SOUTHBRIDGE_AMD_HUDSON_SKIP_ISA_DMA_INIT + bool + default n + +config EHCI_BAR + hex + default 0xfef00000 + +config HUDSON_XHCI_ENABLE + bool "Enable Hudson 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 HUDSON_XHCI_FWM + bool "Add xhci firmware" + default y + help + Add Hudson 2/3/4 XHCI Firmware to support the onboard USB 3.0 + +config HUDSON_DISABLE_IMC + bool + default n + +config HUDSON_IMC_FWM + bool "Add IMC firmware" + depends on !HUDSON_DISABLE_IMC + default y + help + Add Hudson 2/3/4 IMC Firmware to support the onboard fan control + +config HUDSON_GEC_FWM + bool + default n + help + Add Hudson 2/3/4 GEC Firmware to support the onboard gigabit Ethernet MAC. + Must be connected to a Broadcom B50610 or B50610M PHY on the motherboard. + +config HUDSON_PSP + bool + default y if CPU_AMD_PI_00730F01 + +config HUDSON_XHCI_FWM_FILE + string "XHCI firmware path and filename" + default "3rdparty/southbridge/amd/avalon/xhci.bin" if SOUTHBRIDGE_AMD_PI_AVALON + depends on HUDSON_XHCI_FWM + +config HUDSON_IMC_FWM_FILE + string "IMC firmware path and filename" + default "3rdparty/southbridge/amd/avalon/imc.bin" if SOUTHBRIDGE_AMD_PI_AVALON + depends on HUDSON_IMC_FWM + +config HUDSON_GEC_FWM_FILE + string "GEC firmware path and filename" + depends on HUDSON_GEC_FWM + +config HUDSON_FWM + bool + default y if HUDSON_XHCI_FWM || HUDSON_IMC_FWM || HUDSON_GEC_FWM || HUDSON_PSP + default n + +if HUDSON_FWM + +config HUDSON_FWM_POSITION + hex "Hudson Firmware ROM Position" + default 0xFFF20000 if BOARD_ROMSIZE_KB_1024 + default 0xFFE20000 if BOARD_ROMSIZE_KB_2048 + default 0xFFC20000 if BOARD_ROMSIZE_KB_4096 + default 0xFF820000 if BOARD_ROMSIZE_KB_8192 + default 0xFF020000 if BOARD_ROMSIZE_KB_16384 + help + Hudson requires the firmware MUST be located at + a specific address (ROM start address + 0x20000), otherwise + xhci host Controller can not find or load the xhci firmware. + + The firmware start address is dependent on the ROM chip size. + The default offset is 0x20000 from the ROM start address, namely + 0xFFF20000 if flash chip size is 1M + 0xFFE20000 if flash chip size is 2M + 0xFFC20000 if flash chip size is 4M + 0xFF820000 if flash chip size is 8M + 0xFF020000 if flash chip size is 16M +endif # HUDSON_FWM + +config AMD_PUBKEY_FILE + depends on HUDSON_PSP + string "AMD public Key" + default "3rdparty/southbridge/amd/avalon/PSP/AmdPubKey.bin" if CPU_AMD_PI_00730F01 + +config HUDSON_SATA_MODE + int "SATA Mode" + default 0 + range 0 6 + help + Select the mode in which SATA should be driven. NATIVE AHCI, or RAID. + The default is NATIVE. + 0: NATIVE mode does not require a ROM. + 1: RAID mode must have the two ROM files. + 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 HUDSON_SATA_MODE = 0 + +comment "RAID" + depends on HUDSON_SATA_MODE = 1 + +comment "AHCI" + depends on HUDSON_SATA_MODE = 2 + +comment "LEGACY IDE" + depends on HUDSON_SATA_MODE = 3 + +comment "IDE to AHCI" + depends on HUDSON_SATA_MODE = 4 + +comment "AHCI7804" + depends on HUDSON_SATA_MODE = 5 + +comment "IDE to AHCI7804" + depends on HUDSON_SATA_MODE = 6 + +if HUDSON_SATA_MODE = 2 || HUDSON_SATA_MODE = 5 + +config AHCI_ROM_ID + string "AHCI device PCI IDs" + default "1022,7801" if HUDSON_SATA_MODE = 2 + default "1022,7804" if HUDSON_SATA_MODE = 5 + +config HUDSON_AHCI_ROM + bool "Add a AHCI ROM" + +config AHCI_ROM_FILE + string "AHCI ROM path and filename" + depends on HUDSON_AHCI_ROM + default "src/southbridge/amd/agesa/hudson/ahci.bin" + +endif + +if HUDSON_SATA_MODE = 1 + +config RAID_ROM_ID + string "RAID device PCI IDs" + default "1022,7802" + help + 1022,7802 for SATA NON-RAID5 module, 1022,7803 for SATA RAID5 mode + +config RAID_ROM_FILE + string "RAID ROM path and filename" + default "src/southbridge/amd/agesa/hudson/raid.bin" + +config RAID_MISC_ROM_FILE + string "RAID Misc ROM path and filename" + default "src/southbridge/amd/agesa/hudson/misc.bin" + +config RAID_MISC_ROM_POSITION + hex "RAID Misc ROM Position" + default 0xFFF00000 + help + The RAID ROM requires that the MISC ROM is located between the range + 0xFFF0_0000 to 0xFFF0_FFFF. Also, it must 1K bytes aligned. + The CONFIG_ROM_SIZE must be larger than 0x100000. + +endif + +config HUDSON_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 AZ_PIN + hex + default 0xaa + help + bit 1,0 - pin 0 + bit 3,2 - pin 1 + bit 5,4 - pin 2 + bit 7,6 - pin 3 +endif diff --git a/src/southbridge/amd/pi/avalon/Makefile.inc b/src/southbridge/amd/pi/avalon/Makefile.inc new file mode 100644 index 0000000000..3a3a52716f --- /dev/null +++ b/src/southbridge/amd/pi/avalon/Makefile.inc @@ -0,0 +1,301 @@ +#***************************************************************************** +# +# Copyright (c) 2012, 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. +# +#***************************************************************************** + +INCLUDES += -Isrc/southbridge/amd/agesa/hudson + +romstage-y += smbus.c smbus_spd.c +ramstage-y += hudson.c +ramstage-y += usb.c +ramstage-y += lpc.c +ramstage-y += sm.c +ramstage-y += ide.c +ramstage-y += sata.c +ramstage-y += hda.c +ramstage-y += pci.c +ramstage-y += pcie.c +ramstage-y += sd.c + +ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c +ramstage-y += reset.c +romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c +ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c +romstage-y += early_setup.c + +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c smi_util.c +ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smi_util.c + +# ROMSIG At ROMBASE + 0x20000: +# +-----------+---------------+----------------+------------+ +# |0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM | +# +-----------+---------------+----------------+------------+ +# |PSPDIR ADDR| +# +-----------+ +# +# EC ROM should be 64K aligned. + +# HVB(Hardware Validated Boot) or Bypass +CONFIG_HVB=Bypass + +HUDSON_FWM_POSITION=$(shell printf %u $(CONFIG_HUDSON_FWM_POSITION)) + +#assume the cbfs header is less than 128 bytes. +ROMSIG_SIZE=16 +ifeq ($(CONFIG_HUDSON_XHCI_FWM), y) +HUDSON_XHCI_POSITION=$(call int-add,$(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) 128) +XHCI_FWM_SIZE=$(call file-size,$(CONFIG_HUDSON_XHCI_FWM_FILE)) +else +HUDSON_XHCI_POSITION=0 +XHCI_FWM_SIZE=0 +endif + +ifeq ($(CONFIG_HUDSON_GEC_FWM), y) +HUDSON_GEC_POSITION=$(call int-add,$(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) 128 \ + $(XHCI_FWM_SIZE) 128) +GEC_FWM_SIZE=$(call file-size,$(CONFIG_HUDSON_GEC_FWM_FILE)) +else +HUDSON_GEC_POSITION=0 +GEC_FWM_SIZE=0 +endif + +ifeq ($(CONFIG_HUDSON_IMC_FWM), y) +HUDSON_IMC_POSITION=$(call int-align,\ + $(call int-add,\ + $(HUDSON_FWM_POSITION) $(ROMSIG_SIZE) 128 $(XHCI_FWM_SIZE)\ + 128 $(GEC_FWM_SIZE) 128),\ + 65536) +else +HUDSON_IMC_POSITION=0 +endif + +HUDSON_PSP_DIRECTORY_POSITION=0 +ifeq ($(CONFIG_CPU_AMD_PI_00730F01), y) +HUDSON_PSP_DIRECTORY_POSITION=$(call int-add,$(HUDSON_FWM_POSITION) 262144) +endif + +$(obj)/coreboot_hudson_romsig.bin: $(call strip_quotes, $(CONFIG_HUDSON_XHCI_FWM_FILE)) \ + $(call strip_quotes, $(CONFIG_HUDSON_IMC_FWM_FILE)) \ + $(call strip_quotes, $(CONFIG_HUDSON_GEC_FWM_FILE)) \ + $(obj)/config.h + echo " Hudson FW $@" + for fwm in 1437226410 \ + $(HUDSON_IMC_POSITION) \ + $(HUDSON_GEC_POSITION) \ + $(HUDSON_XHCI_POSITION) \ + $(HUDSON_PSP_DIRECTORY_POSITION); do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done > $@ + +ifeq ($(CONFIG_HUDSON_FWM), y) +cbfs-files-y += hudson/fwm +hudson/fwm-file := $(obj)/coreboot_hudson_romsig.bin +hudson/fwm-position := $(HUDSON_FWM_POSITION) +hudson/fwm-type := raw +endif + +ifeq ($(CONFIG_HUDSON_XHCI_FWM), y) +cbfs-files-y += hudson/xhci +hudson/xhci-file := $(call strip_quotes, $(CONFIG_HUDSON_XHCI_FWM_FILE)) +hudson/xhci-position := $(HUDSON_XHCI_POSITION) +hudson/xhci-type := raw +hudson/xhci-required := Hudson XHCI firmware (available in coreboot/3rdparty if enabled) +endif + +ifeq ($(CONFIG_HUDSON_IMC_FWM), y) +cbfs-files-y += hudson/imc +hudson/imc-file := $(call strip_quotes, $(CONFIG_HUDSON_IMC_FWM_FILE)) +hudson/imc-position := $(HUDSON_IMC_POSITION) +hudson/imc-type := raw +hudson/imc-required := Hudson IMC Firmware (available in coreboot/3rdparty if enabled) +endif + +ifeq ($(CONFIG_HUDSON_GEC_FWM), y) +cbfs-files-y += hudson/gec +hudson/gec-file := $(call strip_quotes, $(CONFIG_HUDSON_GEC_FWM_FILE)) +hudson/gec-position := $(HUDSON_GEC_POSITION) +hudson/gec-type := raw +hudson/gec-required := Hudson Gigabit Ethernet Controller Firmware (Contact your AMD representative) +endif + +ifdef CONFIG_HUDSON_AHCI_ROM +stripped_ahci_rom_id = $(call strip_quotes,$(CONFIG_AHCI_ROM_ID)) +cbfs-files-y += pci$(stripped_ahci_rom_id).rom +pci$(stripped_ahci_rom_id).rom-file := $(call strip_quotes,$(CONFIG_AHCI_ROM_FILE)) +pci$(stripped_ahci_rom_id).rom-type := optionrom +pci$(stripped_ahci_rom_id).rom-required := Hudson AHCI Option ROM (Contact your AMD representative) +endif + +ifeq ($(CONFIG_HUDSON_PSP), y) + +# 0 +# catenate the pubkey and pspdir together to save some space. +AMDPUBKEY_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x100) #$(shell printf %u 0xFFb00100) +AMDPUBKEY_SIZE=$(call file-size,$(CONFIG_AMD_PUBKEY_FILE)) + +ifeq ($(CONFIG_CPU_AMD_PI_00730F01), y) +FIRMWARE_LOCATE=$(dir $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE))) +FIRMWARE_TYPE= +endif +# 1 +CONFIG_PSPBTLDR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspBootLoader$(FIRMWARE_TYPE).$(CONFIG_HVB).sbin +PSPBTLDR_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x1000) #$(shell printf %u 0xFFb10000) +PSPBTLDR_SIZE=$(call file-size,$(CONFIG_PSPBTLDR_FILE)) +cbfs-files-y += hudson/pspbtldr +hudson/pspbtldr-file := $(CONFIG_PSPBTLDR_FILE) +hudson/pspbtldr-position := $(PSPBTLDR_POS) +hudson/pspbtldr-type := raw + +#8 +CONFIG_SMUFWM_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuFirmware$(FIRMWARE_TYPE).sbin +SMUFWM_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0xb000) #$(shell printf %u 0xFFb20000) +SMUFWM_SIZE=$(call file-size,$(CONFIG_SMUFWM_FILE)) +cbfs-files-y += hudson/smufwm +hudson/smufwm-file := $(CONFIG_SMUFWM_FILE) +hudson/smufwm-position := $(SMUFWM_POS) +hudson/smufwm-type := raw + +#3 +CONFIG_PSPRCVR_FILE=$(top)/$(FIRMWARE_LOCATE)/PspRecovery$(FIRMWARE_TYPE).sbin +PSPRCVR_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x30000) #$(shell printf %u 0xFFBb0000) +PSPRCVR_SIZE=$(call file-size,$(CONFIG_PSPRCVR_FILE)) +cbfs-files-y += hudson/psprcvr +hudson/psprcvr-file := $(CONFIG_PSPRCVR_FILE) +hudson/psprcvr-position := $(PSPRCVR_POS) +hudson/psprcvr-type := raw + +# 5 +CONFIG_PUBSIGNEDKEY_FILE=$(top)/$(FIRMWARE_LOCATE)/RtmPubSigned$(FIRMWARE_TYPE).key +PUBSIGNEDKEY_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x400) #$(shell printf %u 0xFFb00400) +PUBSIGNEDKEY_SIZE=$(call file-size,$(CONFIG_PUBSIGNEDKEY_FILE)) +cbfs-files-y += hudson/pubsignedkey +hudson/pubsignedkey-file := $(CONFIG_PUBSIGNEDKEY_FILE) +hudson/pubsignedkey-position := $(PUBSIGNEDKEY_POS) +hudson/pubsignedkey-type := raw + +# 2 +CONFIG_PSPSCUREOS_FILE=$(top)/$(FIRMWARE_LOCATE)/PspSecureOs$(FIRMWARE_TYPE).sbin +PSPSECUREOS_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x3A000) #$(shell printf %u 0xFFbc0000) +PSPSECUREOS_SIZE=$(call file-size,$(CONFIG_PSPSCUREOS_FILE)) +cbfs-files-y += hudson/pspsecureos +hudson/pspsecureos-file := $(CONFIG_PSPSCUREOS_FILE) +hudson/pspsecureos-position := $(PSPSECUREOS_POS) +hudson/pspsecureos-type := raw + +# 4 +CONFIG_PSPNVRAM_FILE=$(top)/$(FIRMWARE_LOCATE)/PspNvram$(FIRMWARE_TYPE).bin +PSPNVRAM_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x64000) #$(shell printf %u 0xFFbf0000) +PSPNVRAM_SIZE=$(call file-size,$(CONFIG_PSPNVRAM_FILE)) +cbfs-files-y += hudson/pspnvram +hudson/pspnvram-file := $(CONFIG_PSPNVRAM_FILE) +hudson/pspnvram-position := $(PSPNVRAM_POS) +hudson/pspnvram-type := raw + +ifeq ($(CONFIG_HVB), HVB) +# 6 +RTM_FILE=$(objcbfs)/bootblock.bin #The file size need to be 256 bytes aligned. +RTM_SIZE=$(call file-size,$(RTM_FILE)) +RTM_POS=$(call int-add,4294967296 -$(RTM_SIZE)) + +# 7 +RTMSIGN_FILE=$(obj)/bootblock_sig.bin +RTMSIGN_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x800) #$(shell printf %u 0xFFb00800) +RTMSIGN_SIZE=256 #it should be hardcoded to 256, otherwise circular dependency comes up.$(call file-size,$(RTMSIGN_FILE)) +cbfs-files-y += hudson/rtmsign +hudson/rtmsign-file := $(RTMSIGN_FILE) +hudson/rtmsign-position := $(RTMSIGN_POS) +hudson/rtmsign-type := raw +endif + +CONFIG_SMUSCS_FILE=$(top)/$(FIRMWARE_LOCATE)/SmuScs$(FIRMWARE_TYPE).bin +SMUSCS_POS=$(call int-add,$(HUDSON_PSP_DIRECTORY_POSITION) 0x6d000) #$(shell printf %u 0xFFC00000) +SMUSCS_SIZE=$(call file-size,$(CONFIG_SMUSCS_FILE)) +cbfs-files-y += hudson/smuscs +hudson/smuscs-file := $(CONFIG_SMUSCS_FILE) +hudson/smuscs-position := $(SMUSCS_POS) +hudson/smuscs-type := raw + +define output_hex +echo $(1) | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}' +endef + +$(obj)/coreboot_psp_directory.bin: $(obj)/config.h $(FLETCHER) $(RTM_FILE) + echo " PSPDir $@" + for fwm in 0 $(AMDPUBKEY_SIZE) $(AMDPUBKEY_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done > $@_tail.tmp + for fwm in 1 $(PSPBTLDR_SIZE) $(PSPBTLDR_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 8 $(SMUFWM_SIZE) $(SMUFWM_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 3 $(PSPRCVR_SIZE) $(PSPRCVR_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 5 $(PUBSIGNEDKEY_SIZE) $(PUBSIGNEDKEY_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp +ifeq ($(CONFIG_HVB), HVB) + for fwm in 6 $(RTM_SIZE) $(RTM_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 7 $(RTMSIGN_SIZE) $(RTMSIGN_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp +endif + for fwm in 2 $(PSPSECUREOS_SIZE) $(PSPSECUREOS_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 4 $(PSPNVRAM_SIZE) $(PSPNVRAM_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 95 $(SMUSCS_SIZE) $(SMUSCS_POS) 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 11 4294967295 0 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done >> $@_tail.tmp + for fwm in 1347637284 0 `ls -l $@_tail.tmp | awk '{printf("%d", $$5/16);}'` 0; do \ + echo $$fwm | LC_ALL=C awk '{printf ("%c%c%c%c", $$1 % 256, int($$1/256) % 256, int($$1/65536) % 256, int($$1/16777216));}'; \ + done > $@_head.tmp + cat $@_head.tmp $@_tail.tmp > $@.tmp + $(FLETCHER) < $@.tmp > $@ + rm $@_head.tmp $@_tail.tmp $@.tmp + +$(obj)/coreboot_psp_directory_combine_pubkey.bin: $(obj)/coreboot_psp_directory.bin + cat $(obj)/coreboot_psp_directory.bin > $@ + ls -l $(obj)/coreboot_psp_directory.bin | LC_ALL=C awk '{for (i=0; i<256-$$5; i++) {printf "%c", 255}}' >> $@ + cat $(top)/$(FIRMWARE_LOCATE)/AmdPubKey$(FIRMWARE_TYPE).bin >> $@ + +cbfs-files-y += hudson/pspdir +hudson/pspdir-file := $(obj)/coreboot_psp_directory_combine_pubkey.bin +hudson/pspdir-position := $(HUDSON_PSP_DIRECTORY_POSITION) +hudson/pspdir-type := raw + +endif diff --git a/src/southbridge/amd/pi/avalon/acpi/audio.asl b/src/southbridge/amd/pi/avalon/acpi/audio.asl new file mode 100644 index 0000000000..2c25ab5bd0 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/audio.asl @@ -0,0 +1,57 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +Device(AZHD) { /* 0:14.2 - HD Audio */ + Name(_ADR, 0x00140002) + OperationRegion(AZPD, PCI_Config, 0x00, 0x100) + Field(AZPD, AnyAcc, NoLock, Preserve) { + offset (0x42), + NSDI, 1, + NSDO, 1, + NSEN, 1, + offset (0x44), + IPCR, 4, + offset (0x54), + PWST, 2, + , 6, + PMEB, 1, + , 6, + PMST, 1, + offset (0x62), + MMCR, 1, + offset (0x64), + MMLA, 32, + offset (0x68), + MMHA, 32, + offset (0x6C), + MMDT, 16, + } + + Method (_INI, 0, NotSerialized) + { + If (LEqual (OSVR, 0x03)) + { + Store (Zero, NSEN) + Store (One, NSDO) + Store (One, NSDI) + } + } +} /* end AZHD */ diff --git a/src/southbridge/amd/pi/avalon/acpi/fch.asl b/src/southbridge/amd/pi/avalon/acpi/fch.asl new file mode 100644 index 0000000000..f2764aaa08 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/fch.asl @@ -0,0 +1,188 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* 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) + #include "acpi/sata.asl" +} /* end STCR */ + +/* 0:14.0 - SMBUS */ +Device(SBUS) { + Name(_ADR, 0x00140000) +} /* end SBUS */ + +#include "usb.asl" + +/* 0:14.2 - HD Audio */ +#include "audio.asl" + +/* 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() + + /* TODO: It is unstable. */ + //#include "acpi/AmdImc.asl" /* Hudson IMC function */ + //ITZE() /* enable IMC Fan Control*/ +} /* End Method(_SB._INI) */ + +Method(OSFL, 0){ + + if(LNotEqual(OSVR, Ones)) {Return(OSVR)} /* OS version was already detected */ + + if(CondRefOf(\_OSI,Local1)) + { + 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) +} diff --git a/src/southbridge/amd/pi/avalon/acpi/lpc.asl b/src/southbridge/amd/pi/avalon/acpi/lpc.asl new file mode 100644 index 0000000000..3383ac8cdd --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/lpc.asl @@ -0,0 +1,108 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* 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) */ + #include "acpi/superio.asl" +} /* end LIBR */ diff --git a/src/southbridge/amd/pi/avalon/acpi/pci_int.asl b/src/southbridge/amd/pi/avalon/acpi/pci_int.asl new file mode 100644 index 0000000000..384ed6128e --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/pci_int.asl @@ -0,0 +1,473 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + /* PCIe Configuration Space for CONFIG_MMCONF_BUS_NUMBER busses */ + OperationRegion(PCFG, SystemMemory, PCBA, PCLN) /* Each bus consumes 1MB */ + Field(PCFG, ByteAcc, NoLock, Preserve) { + /* Byte offsets are computed using the following technique: + * ((bus number + 1) * ((device number * 8) * 4096)) + register offset + * The 8 comes from 8 functions per device, and 4096 bytes per function config space + */ + Offset(0x00088024), /* Byte offset to SATA register 24h - Bus 0, Device 17, Function 0 */ + STB5, 32, + Offset(0x00098042), /* Byte offset to OHCI0 register 42h - Bus 0, Device 19, Function 0 */ + PT0D, 1, + PT1D, 1, + PT2D, 1, + PT3D, 1, + PT4D, 1, + PT5D, 1, + PT6D, 1, + PT7D, 1, + PT8D, 1, + PT9D, 1, + Offset(0x000A0004), /* Byte offset to SMBUS register 4h - Bus 0, Device 20, Function 0 */ + SBIE, 1, + SBME, 1, + Offset(0x000A0008), /* Byte offset to SMBUS register 8h - Bus 0, Device 20, Function 0 */ + SBRI, 8, + Offset(0x000A0014), /* Byte offset to SMBUS register 14h - Bus 0, Device 20, Function 0 */ + SBB1, 32, + Offset(0x000A0078), /* Byte offset to SMBUS register 78h - Bus 0, Device 20, Function 0 */ + ,14, + P92E, 1, /* Port92 decode enable */ + } + + OperationRegion(SB5, SystemMemory, STB5, 0x1000) + Field(SB5, AnyAcc, NoLock, Preserve){ + /* Port 0 */ + Offset(0x120), /* Port 0 Task file status */ + P0ER, 1, + , 2, + P0DQ, 1, + , 3, + P0BY, 1, + Offset(0x128), /* Port 0 Serial ATA status */ + P0DD, 4, + , 4, + P0IS, 4, + Offset(0x12C), /* Port 0 Serial ATA control */ + P0DI, 4, + Offset(0x130), /* Port 0 Serial ATA error */ + , 16, + P0PR, 1, + + /* Port 1 */ + offset(0x1A0), /* Port 1 Task file status */ + P1ER, 1, + , 2, + P1DQ, 1, + , 3, + P1BY, 1, + Offset(0x1A8), /* Port 1 Serial ATA status */ + P1DD, 4, + , 4, + P1IS, 4, + Offset(0x1AC), /* Port 1 Serial ATA control */ + P1DI, 4, + Offset(0x1B0), /* Port 1 Serial ATA error */ + , 16, + P1PR, 1, + + /* Port 2 */ + Offset(0x220), /* Port 2 Task file status */ + P2ER, 1, + , 2, + P2DQ, 1, + , 3, + P2BY, 1, + Offset(0x228), /* Port 2 Serial ATA status */ + P2DD, 4, + , 4, + P2IS, 4, + Offset(0x22C), /* Port 2 Serial ATA control */ + P2DI, 4, + Offset(0x230), /* Port 2 Serial ATA error */ + , 16, + P2PR, 1, + + /* Port 3 */ + Offset(0x2A0), /* Port 3 Task file status */ + P3ER, 1, + , 2, + P3DQ, 1, + , 3, + P3BY, 1, + Offset(0x2A8), /* Port 3 Serial ATA status */ + P3DD, 4, + , 4, + P3IS, 4, + Offset(0x2AC), /* Port 3 Serial ATA control */ + P3DI, 4, + Offset(0x2B0), /* Port 3 Serial ATA error */ + , 16, + P3PR, 1, + } + + Method(_PIC, 0x01, NotSerialized) + { + If (Arg0) + { + \_SB.CIRQ() + } + Store(Arg0, PMOD) + } + + Method(CIRQ, 0x00, NotSerialized){ + } + + Name(IRQB, ResourceTemplate(){ + IRQ(Level,ActiveLow,Shared){15} + }) + + Name(IRQP, ResourceTemplate(){ + IRQ(Level,ActiveLow,Exclusive){3, 4, 5, 7, 10, 11, 12, 15} + }) + + Name(PITF, ResourceTemplate(){ + IRQ(Level,ActiveLow,Exclusive){9} + }) + + Device(INTA) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 1) + + Method(_STA, 0) { + if (PIRA) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTA._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKA\\_DIS\n") */ + } /* End Method(_SB.INTA._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKA\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTA._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKA\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRA, IRQN) + Return(IRQB) + } /* Method(_SB.INTA._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKA\\_SRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRA) + } /* End Method(_SB.INTA._SRS) */ + } /* End Device(INTA) */ + + Device(INTB) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 2) + + Method(_STA, 0) { + if (PIRB) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTB._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKB\\_DIS\n") */ + } /* End Method(_SB.INTB._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKB\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTB._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKB\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRB, IRQN) + Return(IRQB) + } /* Method(_SB.INTB._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKB\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRB) + } /* End Method(_SB.INTB._SRS) */ + } /* End Device(INTB) */ + + Device(INTC) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 3) + + Method(_STA, 0) { + if (PIRC) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTC._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKC\\_DIS\n") */ + } /* End Method(_SB.INTC._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKC\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTC._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKC\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRC, IRQN) + Return(IRQB) + } /* Method(_SB.INTC._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKC\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRC) + } /* End Method(_SB.INTC._SRS) */ + } /* End Device(INTC) */ + + Device(INTD) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 4) + + Method(_STA, 0) { + if (PIRD) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTD._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKD\\_DIS\n") */ + } /* End Method(_SB.INTD._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKD\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTD._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKD\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRD, IRQN) + Return(IRQB) + } /* Method(_SB.INTD._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKD\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRD) + } /* End Method(_SB.INTD._SRS) */ + } /* End Device(INTD) */ + + Device(INTE) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 5) + + Method(_STA, 0) { + if (PIRE) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTE._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKE\\_DIS\n") */ + } /* End Method(_SB.INTE._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKE\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTE._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKE\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRE, IRQN) + Return(IRQB) + } /* Method(_SB.INTE._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKE\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRE) + } /* End Method(_SB.INTE._SRS) */ + } /* End Device(INTE) */ + + Device(INTF) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 6) + + Method(_STA, 0) { + if (PIRF) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTF._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKF\\_DIS\n") */ + } /* End Method(_SB.INTF._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKF\\_PRS\n") */ + Return(PITF) + } /* Method(_SB.INTF._PRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKF\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRF, IRQN) + Return(IRQB) + } /* Method(_SB.INTF._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKF\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRF) + } /* End Method(_SB.INTF._SRS) */ + } /* End Device(INTF) */ + + Device(INTG) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 7) + + Method(_STA, 0) { + if (PIRG) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTG._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKG\\_DIS\n") */ + } /* End Method(_SB.INTG._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKG\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTG._CRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKG\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRG, IRQN) + Return(IRQB) + } /* Method(_SB.INTG._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKG\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRG) + } /* End Method(_SB.INTG._SRS) */ + } /* End Device(INTG) */ + + Device(INTH) { + Name(_HID, EISAID("PNP0C0F")) + Name(_UID, 8) + + Method(_STA, 0) { + if (PIRH) { + Return(0x0B) /* sata is invisible */ + } else { + Return(0x09) /* sata is disabled */ + } + } /* End Method(_SB.INTH._STA) */ + + Method(_DIS ,0) { + /* DBGO("\\_SB\\LNKH\\_DIS\n") */ + } /* End Method(_SB.INTH._DIS) */ + + Method(_PRS ,0) { + /* DBGO("\\_SB\\LNKH\\_PRS\n") */ + Return(IRQP) + } /* Method(_SB.INTH._CRS) */ + + Method(_CRS ,0) { + /* DBGO("\\_SB\\LNKH\\_CRS\n") */ + CreateWordField(IRQB, 0x1, IRQN) + ShiftLeft(1, PIRH, IRQN) + Return(IRQB) + } /* Method(_SB.INTH._CRS) */ + + Method(_SRS, 1) { + /* DBGO("\\_SB\\LNKH\\_CRS\n") */ + CreateWordField(ARG0, 1, IRQM) + + /* Use lowest available IRQ */ + FindSetRightBit(IRQM, Local0) + if (Local0) { + Decrement(Local0) + } + Store(Local0, PIRH) + } /* End Method(_SB.INTH._SRS) */ + } /* End Device(INTH) */ diff --git a/src/southbridge/amd/pi/avalon/acpi/pcie.asl b/src/southbridge/amd/pi/avalon/acpi/pcie.asl new file mode 100644 index 0000000000..f130fb45d2 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/pcie.asl @@ -0,0 +1,95 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + /* 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(0xEE), + UPWS, 3, + } diff --git a/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl b/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl new file mode 100644 index 0000000000..f8d0bb0855 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/sleepstates.asl @@ -0,0 +1,40 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* 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 (LAnd(SSFG, 0x04)) { + Name(\_S3, Package () {0x03, 0x03, 0x00, 0x00} ) /* (S3) - Suspend to RAM */ +} +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 */ diff --git a/src/southbridge/amd/pi/avalon/acpi/smbus.asl b/src/southbridge/amd/pi/avalon/acpi/smbus.asl new file mode 100644 index 0000000000..11aff4a04d --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/smbus.asl @@ -0,0 +1,20 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* SMBus Support */ diff --git a/src/southbridge/amd/pi/avalon/acpi/usb.asl b/src/southbridge/amd/pi/avalon/acpi/usb.asl new file mode 100644 index 0000000000..fd0ba6419d --- /dev/null +++ b/src/southbridge/amd/pi/avalon/acpi/usb.asl @@ -0,0 +1,78 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* 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 */ + +#if !CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE +/* 0:14.5 - OHCI */ +Device(UEH1) { + Name(_ADR, 0x00140005) + Name(_PRW, Package() {0x0B, 3}) +} /* end UEH1 */ +#endif + +/* 0:10.0 - XHCI 0*/ +Device(XHC0) { + Name(_ADR, 0x00100000) + Name(_PRW, Package() {0x0B, 4}) +} /* end XHC0 */ + +#if !CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE +/* 0:10.1 - XHCI 1*/ +Device(XHC1) { + Name(_ADR, 0x00100001) + Name(_PRW, Package() {0x0B, 4}) +} /* end XHC1 */ +#endif diff --git a/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h b/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h new file mode 100644 index 0000000000..e6bd2da4f5 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/amd_pci_int_defs.h @@ -0,0 +1,72 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 FCH_INT_TABLE_SIZE 0x63 + +#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 INTA */ +#define PIRQ_SIRQC 0x0E /* Serial IRQ INTA */ +#define PIRQ_SIRQD 0x0F /* Serial IRQ INTA */ +#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 PIRQ_GPIO 0x62 /* GPIO Controller Interrupt */ + +#endif /* AMD_PCI_INT_DEFS_H */ diff --git a/src/southbridge/amd/pi/avalon/amd_pci_int_types.h b/src/southbridge/amd/pi/avalon/amd_pci_int_types.h new file mode 100644 index 0000000000..d0fe9c8094 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/amd_pci_int_types.h @@ -0,0 +1,33 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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", + [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", + [0x40] = "RSVD\t", "SATA\t", + [0x60] = "RSVD\t", "RSVD\t", "GPIO\t", +}; + +#endif /* AMD_PCI_INT_TYPES_H */ diff --git a/src/southbridge/amd/pi/avalon/bootblock.c b/src/southbridge/amd/pi/avalon/bootblock.c new file mode 100644 index 0000000000..3cdba8b907 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/bootblock.c @@ -0,0 +1,67 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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_read_config8(dev, 0x48); + reg8 |= (1 << 3) | (1 << 4); + pci_write_config8(dev, 0x48, reg8); + + /* LPC ROM address range 1: */ + /* Enable LPC ROM range mirroring start at 0x000e(0000). */ + pci_write_config16(dev, 0x68, 0x000e); + /* Enable LPC ROM range mirroring end at 0x000f(ffff). */ + pci_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_write_config16(dev, 0x6c, 0x10000 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6)); + /* Enable LPC ROM range end at 0xffff(ffff). */ + pci_write_config16(dev, 0x6e, 0xffff); +} + +static void bootblock_southbridge_init(void) +{ + hudson_enable_rom(); +} diff --git a/src/southbridge/amd/pi/avalon/chip.h b/src/southbridge/amd/pi/avalon/chip.h new file mode 100644 index 0000000000..40b2480df2 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/chip.h @@ -0,0 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVALON_CHIP_H +#define AVALON_CHIP_H + +struct southbridge_amd_pi_avalon_config +{ + #if 1 + u32 ide0_enable : 1; + u32 sata0_enable : 1; + u32 boot_switch_sata_ide : 1; + u32 hda_viddid; + u8 gpp_configuration; + u8 sd_mode; + #endif +}; + +#endif /* AVALON_CHIP_H */ diff --git a/src/southbridge/amd/pi/avalon/early_setup.c b/src/southbridge/amd/pi/avalon/early_setup.c new file mode 100644 index 0000000000..039df20c43 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/early_setup.c @@ -0,0 +1,156 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _HUDSON_EARLY_SETUP_C_ +#define _HUDSON_EARLY_SETUP_C_ + +#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 "hudson.h" + +void hudson_pci_port80(void) +{ + u8 byte; + device_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; + device_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); +} + +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; +} + +#if CONFIG_HAVE_ACPI_RESUME +int acpi_get_sleep_type(void) +{ + u16 tmp = inw(ACPI_PM1_CNT_BLK); + tmp = ((tmp & (7 << 10)) >> 10); + /* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */ + return (int)tmp; +} +#endif + +#if CONFIG_HAVE_ACPI_RESUME +int acpi_is_wakeup_early(void) +{ + return (acpi_get_sleep_type() == 3); +} +#endif + +unsigned long get_top_of_ram(void) +{ + uint32_t xdata = 0; + int xnvram_pos = 0xf8, xi; + for (xi = 0; xi<4; xi++) { + outb(xnvram_pos, BIOSRAM_INDEX); + xdata &= ~(0xff << (xi * 8)); + xdata |= inb(BIOSRAM_DATA) << (xi *8); + xnvram_pos++; + } + return (unsigned long) xdata; +} + +#endif diff --git a/src/southbridge/amd/pi/avalon/enable_usbdebug.c b/src/southbridge/amd/pi/avalon/enable_usbdebug.c new file mode 100644 index 0000000000..258267ed04 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/enable_usbdebug.c @@ -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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// 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 "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, 2); + else if (hcd_idx==2) + return PCI_DEV(0, 0x13, 2); + else + return PCI_DEV(0, 0x12, 2); +} + +void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port) +{ + u32 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); +} diff --git a/src/southbridge/amd/pi/avalon/fadt.c b/src/southbridge/amd/pi/avalon/fadt.c new file mode 100644 index 0000000000..f86016ab8b --- /dev/null +++ b/src/southbridge/amd/pi/avalon/fadt.c @@ -0,0 +1,211 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * 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 "hudson.h" +#include "smi.h" + +#if CONFIG_HUDSON_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", HUDSON_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)); +} diff --git a/src/southbridge/amd/pi/avalon/hda.c b/src/southbridge/amd/pi/avalon/hda.c new file mode 100644 index 0000000000..2e648b7c6f --- /dev/null +++ b/src/southbridge/amd/pi/avalon/hda.c @@ -0,0 +1,51 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "hudson.h" + + +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, + .device = PCI_DEVICE_ID_ATI_SB900_HDA, +}; diff --git a/src/southbridge/amd/pi/avalon/hudson.c b/src/southbridge/amd/pi/avalon/hudson.c new file mode 100644 index 0000000000..84eaf30f8c --- /dev/null +++ b/src/southbridge/amd/pi/avalon/hudson.c @@ -0,0 +1,173 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "hudson.h" +#include "smbus.h" +#include "smi.h" + +/* Offsets from ACPI_MMIO_BASE + * This is defined by AGESA, but we don't include AGESA headers to avoid + * polluting the namesace. + */ +#define PM_MMIO_BASE 0xfed80300 + + +#if CONFIG_HAVE_ACPI_RESUME +int acpi_get_sleep_type(void) +{ + u16 tmp = inw(ACPI_PM1_CNT_BLK); + tmp = ((tmp & (7 << 10)) >> 10); + /* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */ + return (int)tmp; +} +#endif + +void backup_top_of_ram(uint64_t ramtop) +{ + u32 dword = (u32) ramtop; + int nvram_pos = 0xf8, i; /* temp */ + /* printk(BIOS_DEBUG, "dword=%x\n", dword); */ + for (i = 0; i<4; i++) { + /* printk(BIOS_DEBUG, "nvram_pos=%x, dword>>(8*i)=%x\n", nvram_pos, (dword >>(8 * i)) & 0xff); */ + outb(nvram_pos, BIOSRAM_INDEX); + outb((dword >>(8 * i)) & 0xff , BIOSRAM_DATA); + nvram_pos++; + } +} + +void pm_write8(u8 reg, u8 value) +{ + write8(PM_MMIO_BASE + reg, value); +} + +u8 pm_read8(u8 reg) +{ + return read8(PM_MMIO_BASE + reg); +} + +void pm_write16(u8 reg, u16 value) +{ + write16(PM_MMIO_BASE + reg, value); +} + +u16 pm_read16(u16 reg) +{ + return read16(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(0xe7); + reg8 &= ~(1 << 0); + pm_write8(0xe7, reg8); + } + else if (sd_device_id == PCI_DEVICE_ID_AMD_YANGTZE_SD) { + reg8 = pm_read8(0xe8); + reg8 &= ~(1 << 0); + pm_write8(0xe8, reg8); + } + /* remove device 0:14.7 from PCI space */ + reg8 = pm_read8(0xd3); + reg8 &= ~(1 << 6); + pm_write8(0xd3, reg8); + } + break; + default: + break; + } +} + +#if CONFIG_HAVE_ACPI_RESUME +unsigned long get_top_of_ram(void) +{ + uint32_t xdata = 0; + int xnvram_pos = 0xf8, xi; + if (acpi_get_sleep_type() != 3) + return 0; + for (xi = 0; xi<4; xi++) { + outb(xnvram_pos, BIOSRAM_INDEX); + xdata &= ~(0xff << (xi * 8)); + xdata |= inb(BIOSRAM_DATA) << (xi *8); + xnvram_pos++; + } + return (unsigned long) xdata; +} +#endif + +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(0x60, ACPI_PM_EVT_BLK); + pm_write16(0x62, ACPI_PM1_CNT_BLK); + pm_write16(0x64, ACPI_PM_TMR_BLK); + pm_write16(0x68, ACPI_GPE0_BLK); + /* CpuControl is in \_PR.CPU0, 6 bytes */ + pm_write16(0x66, ACPI_CPU_CONTROL); + + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) { + pm_write16(0x6a, ACPI_SMI_CTL_PORT); + hudson_enable_acpi_cmd_smi(); + } else { + pm_write16(0x6a, 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(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2); +} + +static void hudson_init(void *chip_info) +{ + hudson_init_acpi_ports(); +} + +static void hudson_final(void *chip_info) +{ +} + +struct chip_operations southbridge_amd_pi_avalon_ops = { + CHIP_NAME("ATI HUDSON") + .enable_dev = hudson_enable, + .init = hudson_init, + .final = hudson_final +}; diff --git a/src/southbridge/amd/pi/avalon/hudson.h b/src/southbridge/amd/pi/avalon/hudson.h new file mode 100644 index 0000000000..90c3205ed1 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/hudson.h @@ -0,0 +1,92 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef HUDSON_H +#define HUDSON_H + +#include <device/pci_ids.h> +#include <device/device.h> +#include "chip.h" + +/* 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 HUDSON_ACPI_IO_BASE 0x800 + +#define ACPI_PM_EVT_BLK (HUDSON_ACPI_IO_BASE + 0x00) /* 4 bytes */ +#define ACPI_PM1_CNT_BLK (HUDSON_ACPI_IO_BASE + 0x04) /* 2 bytes */ +#define ACPI_PM_TMR_BLK (HUDSON_ACPI_IO_BASE + 0x18) /* 4 bytes */ +#define ACPI_GPE0_BLK (HUDSON_ACPI_IO_BASE + 0x10) /* 8 bytes */ +#define ACPI_CPU_CONTROL (HUDSON_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_HUDSON_A11 0x11 +#define REV_HUDSON_A12 0x12 + +#define SPIROM_BASE_ADDRESS_REGISTER 0xA0 +#define SPI_ROM_ENABLE 0x02 +#define SPI_BASE_ADDRESS 0xFEC10000 + +static inline int hudson_sata_enable(void) +{ + /* True if IDE or AHCI. */ + return (CONFIG_HUDSON_SATA_MODE == 0) || (CONFIG_HUDSON_SATA_MODE == 2); +} + +static inline int hudson_ide_enable(void) +{ + /* True if IDE or LEGACY IDE. */ + return (CONFIG_HUDSON_SATA_MODE == 0) || (CONFIG_HUDSON_SATA_MODE == 3); +} + +#ifndef __SMM__ + +void pm_write8(u8 reg, u8 value); +u8 pm_read8(u8 reg); +void pm_write16(u8 reg, u16 value); +u16 pm_read16(u16 reg); + +#ifdef __PRE_RAM__ +void hudson_lpc_port80(void); +void hudson_pci_port80(void); +void hudson_clk_output_48Mhz(void); + +int s3_save_nvram_early(u32 dword, int size, int nvram_pos); +int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos); + +#else +void hudson_enable(device_t dev); +void s3_resume_init_data(void *FchParams); + +#endif /* __PRE_RAM__ */ +#endif /* __SMM__ */ + +#endif /* HUDSON_H */ diff --git a/src/southbridge/amd/pi/avalon/ide.c b/src/southbridge/amd/pi/avalon/ide.c new file mode 100644 index 0000000000..cd80f99ff4 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/ide.c @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "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_ATI_SB900_IDE, +}; diff --git a/src/southbridge/amd/pi/avalon/lpc.c b/src/southbridge/amd/pi/avalon/lpc.c new file mode 100644 index 0000000000..1f60bc4ed9 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/lpc.c @@ -0,0 +1,332 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "hudson.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(RTC_HAS_ALTCENTURY); + + /* 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. + */ + cmos_init(0); +} + +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; + + /* Special case. SPI Base Address. The SpiRomEnable should STAY set. */ + res = find_resource(dev, 2); + pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, res->base | SPI_ROM_ENABLE); + + pci_dev_set_resources(dev); +} + +/** + * @brief Enable resources for children devices + * + * @param dev the device whos 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); +} + +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, + .init = lpc_init, + .scan_bus = scan_static_bus, + .ops_pci = &lops_pci, +}; +static const struct pci_driver lpc_driver __pci_driver = { + .ops = &lpc_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_LPC, +}; diff --git a/src/southbridge/amd/pi/avalon/pci.c b/src/southbridge/amd/pi/avalon/pci.c new file mode 100644 index 0000000000..e8836e4c7d --- /dev/null +++ b/src/southbridge/amd/pi/avalon/pci.c @@ -0,0 +1,74 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "hudson.h" +#include <southbridge/amd/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_ENTRIES(pci_irq_update) = { + 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_ATI_SB900_PCI, +}; diff --git a/src/southbridge/amd/pi/avalon/pci_devs.h b/src/southbridge/amd/pi/avalon/pci_devs.h new file mode 100644 index 0000000000..2af1659ebd --- /dev/null +++ b/src/southbridge/amd/pi/avalon/pci_devs.h @@ -0,0 +1,96 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _PI_HUDSON_PCI_DEVS_H_ +#define _PI_HUDSON_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) + +/* 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 0x22 +#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) + +/* 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) + +#endif /* _PI_HUDSON_PCI_DEVS_H_ */ diff --git a/src/southbridge/amd/pi/avalon/pcie.c b/src/southbridge/amd/pi/avalon/pcie.c new file mode 100644 index 0000000000..ec686fc2cf --- /dev/null +++ b/src/southbridge/amd/pi/avalon/pcie.c @@ -0,0 +1,65 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "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_ATI_SB900_PCIEA, +}; + +static const struct pci_driver pcieb_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_PCIEB, +}; +static const struct pci_driver pciec_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_PCIEC, +}; +static const struct pci_driver pcied_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_PCIED, +}; diff --git a/src/southbridge/amd/pi/avalon/reset.c b/src/southbridge/amd/pi/avalon/reset.c new file mode 100644 index 0000000000..79fd79e210 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/reset.c @@ -0,0 +1,35 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// Use simple device model for this file even in ramstage +#define __SIMPLE_DEVICE__ + +#include <arch/io.h> +#include <reset.h> + +#include <northbridge/amd/amdk8/reset_test.c> + +void 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); +} diff --git a/src/southbridge/amd/pi/avalon/sata.c b/src/southbridge/amd/pi/avalon/sata.c new file mode 100644 index 0000000000..7499370dc5 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/sata.c @@ -0,0 +1,85 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "hudson.h" + + +static void sata_init(struct device *dev) +{ +#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE) + /************************************** + * 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); +#endif +}; + +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 struct pci_driver sata0_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_SATA, +}; + +static const struct pci_driver sata0_driver_ahci __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_SATA_AHCI, +}; diff --git a/src/southbridge/amd/pi/avalon/sd.c b/src/southbridge/amd/pi/avalon/sd.c new file mode 100644 index 0000000000..4367f7aa6a --- /dev/null +++ b/src/southbridge/amd/pi/avalon/sd.c @@ -0,0 +1,69 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "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 southbridge_amd_pi_avalon_config *sd_chip = + (struct southbridge_amd_pi_avalon_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, +}; diff --git a/src/southbridge/amd/pi/avalon/sm.c b/src/southbridge/amd/pi/avalon/sm.c new file mode 100644 index 0000000000..d6ca215a6a --- /dev/null +++ b/src/southbridge/amd/pi/avalon/sm.c @@ -0,0 +1,174 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "hudson.h" +#include "smbus.c" + +#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 + +#define BIT0 (1 << 0) +#define BIT1 (1 << 1) +#define BIT2 (1 << 2) +#define BIT3 (1 << 3) +#define BIT4 (1 << 4) +#define BIT5 (1 << 5) +#define BIT6 (1 << 6) +#define BIT7 (1 << 7) + +#define BIT8 (1 << 8 ) +#define BIT9 (1 << 9 ) +#define BIT10 (1 << 10) +#define BIT11 (1 << 11) +#define BIT12 (1 << 12) +#define BIT13 (1 << 13) +#define BIT14 (1 << 14) +#define BIT15 (1 << 15) + +#define BIT16 (1 << 16) +#define BIT17 (1 << 17) +#define BIT18 (1 << 18) +#define BIT19 (1 << 19) +#define BIT20 (1 << 20) +#define BIT21 (1 << 21) +#define BIT22 (1 << 22) +#define BIT23 (1 << 23) +#define BIT24 (1 << 24) +#define BIT25 (1 << 25) +#define BIT26 (1 << 26) +#define BIT27 (1 << 27) +#define BIT28 (1 << 28) +#define BIT29 (1 << 29) +#define BIT30 (1 << 30) +#define BIT31 (1 << 31) + +/* +* 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(IO_APIC_ADDR, 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_static_bus, + .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_ATI_SB900_SM, +}; diff --git a/src/southbridge/amd/pi/avalon/smbus.c b/src/southbridge/amd/pi/avalon/smbus.c new file mode 100644 index 0000000000..519c85dc2b --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smbus.c @@ -0,0 +1,250 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _HUDSON_SMBUS_C_ +#define _HUDSON_SMBUS_C_ + +#include <io.h> +#include <stdint.h> +#include "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 diff --git a/src/southbridge/amd/pi/avalon/smbus.h b/src/southbridge/amd/pi/avalon/smbus.h new file mode 100644 index 0000000000..53cc0e6c44 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smbus.h @@ -0,0 +1,76 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef HUDSON_SMBUS_H +#define HUDSON_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 diff --git a/src/southbridge/amd/pi/avalon/smbus_spd.c b/src/southbridge/amd/pi/avalon/smbus_spd.c new file mode 100644 index 0000000000..9dfd0b5f97 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smbus_spd.c @@ -0,0 +1,152 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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); +} diff --git a/src/southbridge/amd/pi/avalon/smi.c b/src/southbridge/amd/pi/avalon/smi.c new file mode 100644 index 0000000000..1d58afe3f8 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smi.c @@ -0,0 +1,25 @@ +/* + * 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 "smi.h" + +#include <console/console.h> +#include <cpu/cpu.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); +} diff --git a/src/southbridge/amd/pi/avalon/smi.h b/src/southbridge/amd/pi/avalon/smi.h new file mode 100644 index 0000000000..de987a9274 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smi.h @@ -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_HUDSON_SMI_H +#define _SOUTHBRIDGE_AMD_PI_HUDSON_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(SMI_BASE + offset); +} + +static inline void smi_write32(uint8_t offset, uint32_t value) +{ + write32(SMI_BASE + offset, value); +} + +static inline uint16_t smi_read16(uint8_t offset) +{ + return read16(SMI_BASE + offset); +} + +static inline void smi_write16(uint8_t offset, uint16_t value) +{ + write16(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_HUDSON_SMI_H */ diff --git a/src/southbridge/amd/pi/avalon/smi_util.c b/src/southbridge/amd/pi/avalon/smi_util.c new file mode 100644 index 0000000000..6076cd43b3 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smi_util.c @@ -0,0 +1,79 @@ +/* + * 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 "smi.h" + +#include <console/console.h> + +#define HUDSON_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(HUDSON_SMI_ACPI_COMMAND, SMI_MODE_SMI); +} diff --git a/src/southbridge/amd/pi/avalon/smihandler.c b/src/southbridge/amd/pi/avalon/smihandler.c new file mode 100644 index 0000000000..e762d0bb96 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/smihandler.c @@ -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 "hudson.h" +#include "smi.h" + +#include <console/console.h> +#include <cpu/x86/smm.h> +#include <delay.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; + } + + if (mainboard_smi_apmc) + 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 occured */ + if (mainboard_smi_gpi) + 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); +} diff --git a/src/southbridge/amd/pi/avalon/usb.c b/src/southbridge/amd/pi/avalon/usb.c new file mode 100644 index 0000000000..36eff6e820 --- /dev/null +++ b/src/southbridge/amd/pi/avalon/usb.c @@ -0,0 +1,100 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#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 "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 struct pci_driver usb_0_driver __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_USB_18_0, +}; +static const struct pci_driver usb_1_driver __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_USB_18_2, +}; + +/* the pci id of usb ctrl 0 and 1 are the same. */ +/* + * static const struct pci_driver usb_3_driver __pci_driver = { + * .ops = &usb_ops, + * .vendor = PCI_VENDOR_ID_AMD, + * .device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_0, + * }; + * static const struct pci_driver usb_4_driver __pci_driver = { + * .ops = &usb_ops, + * .vendor = PCI_VENDOR_ID_AMD, + * .device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_1, + * }; + */ + +static const struct pci_driver usb_4_driver __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_SB900_USB_20_5, +}; + +/* +static struct device_operations usb_ops2 = { + .read_resources = pci_ehci_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = usb_init2, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; +*/ +/* +static const struct pci_driver usb_5_driver __pci_driver = { + .ops = &usb_ops2, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_ATI_HUDSON_USB_18_2, +}; +*/ +/* + * static const struct pci_driver usb_5_driver __pci_driver = { + * .ops = &usb_ops2, + * .vendor = PCI_VENDOR_ID_AMD, + * .device = PCI_DEVICE_ID_ATI_HUDSON_USB_19_2, + * }; + */ |