AGESA F15 wrapper for Hudson.

Hudson code has been integrated from CIMx to AGESA. This patch is about the wrapper.

Change-Id: I63d951982140b82a3a77a97eb3d55fc75fc0caa3
Signed-off-by: Zheng Bao <zheng.bao@amd.com>
Signed-off-by: zbao <fishbaozi@gmail.com>
Reviewed-on: http://review.coreboot.org/1157
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
This commit is contained in:
zbao 2012-07-13 18:47:03 +08:00 committed by Patrick Georgi
parent 22b7a55a4d
commit 246e84bc0d
27 changed files with 2332 additions and 1 deletions

View File

@ -12,4 +12,5 @@ source src/southbridge/amd/rs780/Kconfig
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/sr5650/Kconfig

View File

@ -14,6 +14,7 @@ subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CS5536) += cs5536
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB700) += cimx
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += cimx
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += cimx
subdirs-$(CONFIG_SOUTHBRIDGE_AMD_AGESA_HUDSON) += agesa
ifeq ($(CONFIG_HAVE_ACPI_RESUME), y)
ifeq ($(CONFIG_CPU_AMD_AGESA), y)
@ -21,7 +22,7 @@ ifeq ($(CONFIG_CPU_AMD_AGESA), y)
$(obj)/s3.rom:
echo " S3 NVRAM 0xffff0000 (S3 storage area)"
# force C locale, so cygwin awk doesn't try to interpret the 0xff below as UTF-8 (or worse)
LC_ALL=C awk 'BEGIN {for (i=0; i<20480; i++) {printf "%c", 255}}' > $@.tmp
LC_ALL=C awk 'BEGIN {for (i=0; i<32768; i++) {printf "%c", 255}}' > $@.tmp
mv $@.tmp $@
cbfs-files-y += s3nv

View File

@ -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/agesa/hudson/Kconfig

View File

@ -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_AGESA_HUDSON) += hudson

View File

@ -0,0 +1,208 @@
##
## 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_AGESA_HUDSON
bool
select IOAPIC
select HAVE_USBDEBUG
select TINY_BOOTBLOCK
config BOOTBLOCK_SOUTHBRIDGE_INIT
string
default "southbridge/amd/agesa/hudson/bootblock.c"
depends on SOUTHBRIDGE_AMD_AGESA_HUDSON
config SOUTHBRIDGE_AMD_HUDSON_SKIP_ISA_DMA_INIT
bool
default n
depends on SOUTHBRIDGE_AMD_AGESA_HUDSON
config EHCI_BAR
hex
default 0xfef00000 if SOUTHBRIDGE_AMD_AGESA_HUDSON
config EHCI_DEBUG_OFFSET
hex
default 0xe0 if SOUTHBRIDGE_AMD_AGESA_HUDSON
if SOUTHBRIDGE_AMD_AGESA_HUDSON
config HUDSON_XHCI_FWM
bool "Add xhci firmware"
default y
help
Add Hudson 2/3/4 XHCI Firmware to support the onboard usb3.0
Please contact AMD to obtain the related firmware
config HUDSON_IMC_FWM
bool "Add imc firmware"
default y
help
Add Hudson 2/3/4 IMC Firmware to support the onboard fan control
Please contact AMD to obtain the related firmware
config HUDSON_GEC_FWM
bool "Add gec firmware"
default n
help
Add Hudson 2/3/4 GEC Firmware
Please contact AMD to obtain the related firmware
config HUDSON_XHCI_FWM_FILE
string "XHCI firmware path and filename"
default "3rdparty/amd/hudson/xhci.bin"
depends on HUDSON_XHCI_FWM
config HUDSON_IMC_FWM_FILE
string "IMC firmware path and filename"
default "3rdparty/amd/hudson/imc.bin"
depends on HUDSON_IMC_FWM
config HUDSON_GEC_FWM_FILE
string "GEC firmware path and filename"
default "src/southbridge/amd/agesa/hudson/gec.bin"
depends on HUDSON_GEC_FWM
config HUDSON_FWM
bool
default y if HUDSON_XHCI_FWM || HUDSON_IMC_FWM || HUDSON_GEC_FWM
default n if !HUDSON_XHCI_FWM && !HUDSON_IMC_FWM && !HUDSON_GEC_FWM
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 to 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
choice
prompt "SATA Mode"
default HUDSON_SATA_IDE
help
Select the mode in which SATA should be driven. NATIVE AHCI, or RAID.
The default is NATIVE.
config HUDSON_SATA_IDE
bool "NATIVE"
help
NATIVE is the default mode and does not require a ROM.
config HUDSON_SATA_RAID
bool "RAID"
help
HUDSON RAID mode must have the two required ROM files.
config HUDSON_SATA_AHCI
bool "AHCI"
help
AHCI may work with or without AHCI ROM. It depends on the payload support.
For example, seabios does not require the AHCI ROM.
config HUDSON_SATA_LEGACY_IDE
bool "LEGACY IDE"
help
TODO
config HUDSON_SATA_IDE2AHCI
bool "IDE to AHCI"
help
TODO
config HUDSON_SATA_AHCI7804
bool "AHCI7804"
help
AHCI ROM Required, and AMD driver required in the OS.
config HUDSON_SATA_IDE2AHCI7804
bool "IDE to AHCI7804"
help
AHCI ROM Required, and AMD driver required in the OS.
endchoice
config HUDSON_SATA_MODE
hex
depends on (HUDSON_SATA_IDE || HUDSON_SATA_RAID || HUDSON_SATA_AHCI)
default "0x0" if HUDSON_SATA_IDE
default "0x1" if HUDSON_SATA_RAID
default "0x2" if HUDSON_SATA_AHCI
default "0x3" if HUDSON_SATA_LEGACY_IDE
default "0x4" if HUDSON_SATA_IDE2AHCI
default "0x5" if HUDSON_SATA_AHCI7804
default "0x6" if HUDSON_SATA_IDE2AHCI7804
if HUDSON_SATA_AHCI || HUDSON_SATA_AHCI7804
config AHCI_ROM_ID
string "AHCI device PCI IDs"
default "1022,7801" if HUDSON_SATA_AHCI
default "1022,7804" if HUDSON_SATA_AHCI7804
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_RAID
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"
depends on HUDSON_SATA_RAID
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"
depends on HUDSON_SATA_RAID
config RAID_MISC_ROM_POSITION
hex "RAID Misc ROM Position"
default 0xFFF00000
depends on HUDSON_SATA_RAID
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 larger than 0x100000.
endif
endif

View File

@ -0,0 +1,34 @@
driver-y += hudson.c
driver-y += usb.c
driver-y += lpc.c
driver-y += sm.c
driver-y += ide.c
driver-y += sata.c
driver-y += hda.c
driver-y += pci.c
driver-y += pcie.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
ramstage-y += reset.c
romstage-y += enable_usbdebug.c
romstage-y += early_setup.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += spi.c
$(obj)/hudson.bin:
python $(src)/southbridge/amd/agesa/hudson/hudson_fwm.py $(CONFIG_HUDSON_FWM_POSITION) $@ $(CONFIG_HUDSON_XHCI_FWM_FILE) $(CONFIG_HUDSON_IMC_FWM_FILE) ""
ifeq ($(CONFIG_HUDSON_FWM), y)
cbfs-files-y += hudson/fwm
hudson/fwm-file := $(obj)/hudson.bin
hudson/fwm-position := $(CONFIG_HUDSON_FWM_POSITION)
hudson/fwm-type := raw
endif
#ifeq ($(CONFIG_HUDSON_SATA_AHCI), y)
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
#endif
endif

View File

@ -0,0 +1,68 @@
/*
* 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 <arch/romcc_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;
device_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();
}

View File

@ -0,0 +1,36 @@
/*
* 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_CHIP_H
#define HUDSON_CHIP_H
struct southbridge_amd_agesa_hudson_config
{
#if 1
u32 ide0_enable : 1;
u32 sata0_enable : 1;
u32 boot_switch_sata_ide : 1;
u32 hda_viddid;
u8 gpp_configuration;
#endif
};
struct chip_operations;
extern struct chip_operations southbridge_amd_agesa_hudson_ops;
#endif /* HUDSON_CHIP_H */

View File

@ -0,0 +1,112 @@
/*
* 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> /* inl, outl */
#include <arch/romcc_io.h> /* device_t */
#include <arch/acpi.h>
#include <console/console.h>
#include <reset.h>
#include <arch/cpu.h>
#include <cbmem.h>
#include "hudson.h"
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);//pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
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 == 1
int acpi_get_sleep_type(void)
{
u16 tmp = inw(PM1_CNT_BLK_ADDRESS);
tmp = ((tmp & (7 << 10)) >> 10);
/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
return (int)tmp;
}
#endif
#if CONFIG_HAVE_ACPI_RESUME == 1
int acpi_is_wakeup_early(void)
{
return (acpi_get_sleep_type() == 3);
}
#endif
struct cbmem_entry *get_cbmem_toc(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 (struct cbmem_entry *) xdata;
}
#endif

View File

@ -0,0 +1,52 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 Advanced Micro Devices, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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 <arch/romcc_io.h>
#include <usbdebug.h>
#include <device/pci_def.h>
#include "hudson.h"
#ifndef HUDSON_DEVN_BASE
#define HUDSON_DEVN_BASE 0
#endif
#define EHCI_EOR (CONFIG_EHCI_BAR + 0x20)
#define DEBUGPORT_MISC_CONTROL (EHCI_EOR + 0x80)
void set_debug_port(unsigned int port)
{
u32 reg32;
/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
reg32 = read32(DEBUGPORT_MISC_CONTROL);
reg32 &= ~(0xf << 28);
reg32 |= (port << 28);
reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
write32(DEBUGPORT_MISC_CONTROL, reg32);
}
void enable_usbdebug(unsigned int port)
{
pci_write_config32(PCI_DEV(0, HUDSON_DEVN_BASE + 0x13, 5),
EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
pci_write_config8(PCI_DEV(0, HUDSON_DEVN_BASE + 0x13, 5), 0x04, 0x2); /* mem space enabe */
set_debug_port(port);
}

View File

@ -0,0 +1,186 @@
/*
* 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"
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 = 244;
header->revision = 3;
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, "COREBOOT", 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->asl_compiler_revision = 0;
fadt->firmware_ctrl = (u32) facs;
fadt->dsdt = (u32) dsdt;
/* 3=Workstation,4=Enterprise Server, 7=Performance Server */
fadt->preferred_pm_profile = 0x03;
fadt->sci_int = 9;
/* disable system management mode by setting to 0: */
fadt->smi_cmd = 0;
fadt->acpi_enable = 0xf0;
fadt->acpi_disable = 0xf1;
fadt->s4bios_req = 0x0;
fadt->pstate_cnt = 0xe2;
pm_iowrite(0x60, ACPI_PM_EVT_BLK & 0xFF);
pm_iowrite(0x61, ACPI_PM_EVT_BLK >> 8);
pm_iowrite(0x62, ACPI_PM1_CNT_BLK & 0xFF);
pm_iowrite(0x63, ACPI_PM1_CNT_BLK >> 8);
pm_iowrite(0x64, ACPI_PM_TMR_BLK & 0xFF);
pm_iowrite(0x65, ACPI_PM_TMR_BLK >> 8);
pm_iowrite(0x68, ACPI_GPE0_BLK & 0xFF);
pm_iowrite(0x69, ACPI_GPE0_BLK >> 8);
/* CpuControl is in \_PR.CPU0, 6 bytes */
pm_iowrite(0x66, ACPI_CPU_CONTROL & 0xFF);
pm_iowrite(0x67, ACPI_CPU_CONTROL >> 8);
pm_iowrite(0x6A, 0); /* AcpiSmiCmdLo */
pm_iowrite(0x6B, 0); /* AcpiSmiCmdHi */
pm_iowrite(0x6C, ACPI_PMA_CNT_BLK & 0xFF);
pm_iowrite(0x6D, ACPI_PMA_CNT_BLK >> 8);
pm_iowrite(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2); /* AcpiDecodeEnable, When set, SB uses
* the contents of the PM registers at
* index 60-6B to decode ACPI I/O address.
* AcpiSmiEn & SmiCmdEn*/
/* RTC_En_En, TMR_En_En, GBL_EN_EN */
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 = ACPI_PMA_CNT_BLK;
fadt->pm_tmr_blk = ACPI_PM_TMR_BLK;
fadt->gpe0_blk = ACPI_GPE0_BLK;
fadt->gpe1_blk = 0x0000; /* we dont have gpe1 block, do we? */
fadt->pm1_evt_len = 4;
fadt->pm1_cnt_len = 2;
fadt->pm2_cnt_len = 1;
fadt->pm_tmr_len = 4;
fadt->gpe0_blk_len = 8;
fadt->gpe1_blk_len = 0;
fadt->gpe1_base = 0;
fadt->cst_cnt = 0xe3;
fadt->p_lvl2_lat = 101;
fadt->p_lvl3_lat = 1001;
fadt->flush_size = 0;
fadt->flush_stride = 0;
fadt->duty_offset = 1;
fadt->duty_width = 3;
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 alrm work */
fadt->iapc_boot_arch = 0x3; /* See table 5-11 */
fadt->flags = 0x0001c1a5 | 1 << 10;/* 0x25; */
fadt->res2 = 0;
fadt->reset_reg.space_id = 1;
fadt->reset_reg.bit_width = 8;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.resv = 0;
fadt->reset_reg.addrl = 0xcf9;
fadt->reset_reg.addrh = 0x0;
fadt->reset_value = 6;
fadt->x_firmware_ctl_l = (u32) facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (u32) dsdt;
fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = 1;
fadt->x_pm1a_evt_blk.bit_width = 32;
fadt->x_pm1a_evt_blk.bit_offset = 0;
fadt->x_pm1a_evt_blk.resv = 0;
fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK;
fadt->x_pm1a_evt_blk.addrh = 0x0;
fadt->x_pm1b_evt_blk.space_id = 1;
fadt->x_pm1b_evt_blk.bit_width = 4;
fadt->x_pm1b_evt_blk.bit_offset = 0;
fadt->x_pm1b_evt_blk.resv = 0;
fadt->x_pm1b_evt_blk.addrl = 0x0;
fadt->x_pm1b_evt_blk.addrh = 0x0;
fadt->x_pm1a_cnt_blk.space_id = 1;
fadt->x_pm1a_cnt_blk.bit_width = 16;
fadt->x_pm1a_cnt_blk.bit_offset = 0;
fadt->x_pm1a_cnt_blk.resv = 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 = 1;
fadt->x_pm1b_cnt_blk.bit_width = 2;
fadt->x_pm1b_cnt_blk.bit_offset = 0;
fadt->x_pm1b_cnt_blk.resv = 0;
fadt->x_pm1b_cnt_blk.addrl = 0x0;
fadt->x_pm1b_cnt_blk.addrh = 0x0;
fadt->x_pm2_cnt_blk.space_id = 1;
fadt->x_pm2_cnt_blk.bit_width = 0;
fadt->x_pm2_cnt_blk.bit_offset = 0;
fadt->x_pm2_cnt_blk.resv = 0;
fadt->x_pm2_cnt_blk.addrl = ACPI_PMA_CNT_BLK;
fadt->x_pm2_cnt_blk.addrh = 0x0;
fadt->x_pm_tmr_blk.space_id = 1;
fadt->x_pm_tmr_blk.bit_width = 32;
fadt->x_pm_tmr_blk.bit_offset = 0;
fadt->x_pm_tmr_blk.resv = 0;
fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK;
fadt->x_pm_tmr_blk.addrh = 0x0;
fadt->x_gpe0_blk.space_id = 1;
fadt->x_gpe0_blk.bit_width = 32;
fadt->x_gpe0_blk.bit_offset = 0;
fadt->x_gpe0_blk.resv = 0;
fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK;
fadt->x_gpe0_blk.addrh = 0x0;
fadt->x_gpe1_blk.space_id = 1;
fadt->x_gpe1_blk.bit_width = 0;
fadt->x_gpe1_blk.bit_offset = 0;
fadt->x_gpe1_blk.resv = 0;
fadt->x_gpe1_blk.addrl = 0;
fadt->x_gpe1_blk.addrh = 0x0;
header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t));
}

View File

@ -0,0 +1,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,
};

View File

@ -0,0 +1,122 @@
/*
* 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"
#if CONFIG_HAVE_ACPI_RESUME == 1
int acpi_get_sleep_type(void)
{
u16 tmp = inw(PM1_CNT_BLK_ADDRESS);
tmp = ((tmp & (7 << 10)) >> 10);
/* printk(BIOS_DEBUG, "SLP_TYP type was %x\n", tmp); */
return (int)tmp;
}
#endif
void set_cbmem_toc(struct cbmem_entry *toc)
{
u32 dword = (u32) toc;
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 set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val)
{
u32 reg_old, reg;
reg = reg_old = pci_read_config32(sm_dev, reg_pos);
reg &= ~mask;
reg |= val;
if (reg != reg_old) {
pci_write_config32(sm_dev, reg_pos, reg);
}
}
static void pmio_write_index(u16 port_base, u8 reg, u8 value)
{
outb(reg, port_base);
outb(value, port_base + 1);
}
static u8 pmio_read_index(u16 port_base, u8 reg)
{
outb(reg, port_base);
return inb(port_base + 1);
}
void pm_iowrite(u8 reg, u8 value)
{
pmio_write_index(PM_INDEX, reg, value);
}
u8 pm_ioread(u8 reg)
{
return pmio_read_index(PM_INDEX, reg);
}
void pm2_iowrite(u8 reg, u8 value)
{
pmio_write_index(PM2_INDEX, reg, value);
}
u8 pm2_ioread(u8 reg)
{
return pmio_read_index(PM2_INDEX, reg);
}
void hudson_enable(device_t dev)
{
printk(BIOS_DEBUG, "sb800_enable()\n");
}
struct cbmem_entry *get_cbmem_toc(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 (struct cbmem_entry *) xdata;
}
struct chip_operations southbridge_amd_agesa_hudson_ops = {
CHIP_NAME("ATI HUDSON")
.enable_dev = hudson_enable,
};

View File

@ -0,0 +1,75 @@
/*
* 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_H
#define HUDSON_H
#include <device/pci_ids.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_PMA_CNT_BLK (HUDSON_ACPI_IO_BASE + 0x0F) /* 1 byte, TODO: Is it 0xFE00? */
#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 */
void pm_iowrite(u8 reg, u8 value);
u8 pm_ioread(u8 reg);
void pm2_iowrite(u8 reg, u8 value);
u8 pm2_ioread(u8 reg);
void set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val);
#define REV_HUDSON_A11 0x11
#define REV_HUDSON_A12 0x12
#define PM1_EVT_BLK_ADDRESS 0x800 // AcpiPm1EvtBlkAddr;
#define PM1_CNT_BLK_ADDRESS 0x804 // AcpiPm1CntBlkAddr;
#define PM1_TMR_BLK_ADDRESS 0x808 // AcpiPmTmrBlkAddr;
#define CPU_CNT_BLK_ADDRESS 0x810 // CpuControlBlkAddr;
#define GPE0_BLK_ADDRESS 0x820 // AcpiGpe0BlkAddr;
#define SMI_CMD_PORT 0xB0 // SmiCmdPortAddr;
#define ACPI_PMA_CNT_BLK_ADDRESS 0xFE00 // AcpiPmaCntBlkAddr;
#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);
int acpi_is_wakeup_early(void);
#else
void hudson_enable(device_t dev);
void __attribute__((weak)) hudson_setup_sata_phys(struct device *dev);
#endif
#endif /* HUDSON_H */

View File

@ -0,0 +1,64 @@
import sys, os, re
import struct
from Queue import Queue
def main(start_addr, file_name, xhci_name, imc_name, gec_name):
fwm_sig = 0x55AA55AA # Hudson-2/3/4 firmware signature
fwm_header_len = 0x10 # 55AA55AA, imc_off, gec_off, xhci_off
if not os.path.exists(xhci_name):
print "XHCI firmware %s does not exist\n" % xhci_name
sys.exit(1)
if not os.path.exists(imc_name):
print "IMC firmware %s does not exist\n" % imc_name
sys.exit(1)
f = open(file_name, "w")
print "write to file " + file_name
imc_offset = 0x10000 # 64K Bytes offset, hardcoded
imc_addr = start_addr + imc_offset; #startaddr + 0x10000
gec_offset = 0 #TODO
gec_addr = 0 #TODO
xhci_addr = start_addr + fwm_header_len #ROMSIG take 0x10 bytes
format="I" # one unsigned integer
data=struct.pack(format, fwm_sig)
f.write(data)
data=struct.pack(format, imc_addr)
f.write(data)
data=struct.pack(format, gec_addr)
f.write(data)
data=struct.pack(format, xhci_addr)
f.write(data)
fwm_content = open(xhci_name).read()
f.write(fwm_content)
imc_content = open(imc_name).read()
f.seek(0)
f.seek(imc_offset)
f.write(imc_content)
# if os.path.exists(gec_name):
# gec_conent = open(gec_name).read()
# f.seek(0)
# f.seek(gec_offset)
# f.write(gec_content)
f.close()
print "done\n"
if __name__ == '__main__':
if (len(sys.argv) < 6):
print "\nUsage: %s <rom_addr> <rom_file> <xhci_rom> <imc_rom> <gec_rom>\n" % sys.argv[0]
print "Example: %s 0xFFF20000 hudson.bin xhci.bin imc.bin gec.bin\n" % sys.argv[0]
sys.exit(1)
rom_addr = int(sys.argv[1], 16)
rom_file = sys.argv[2]
xhci_file = sys.argv[3]
imc_file = sys.argv[4]
gec_file = sys.argv[5]
print "%x %s %s %s %s" % (rom_addr, rom_file, xhci_file, imc_file, gec_file)
main(rom_addr, rom_file, xhci_file, imc_file, gec_file)

View File

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

View File

@ -0,0 +1,148 @@
/*
* 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/pnp.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <pc80/mc146818rtc.h>
#include <pc80/isa-dma.h>
#include <bitops.h>
#include <arch/io.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);
}
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 */
pci_get_resource(dev, 0xA0); /* SPI ROM base address */
/* 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;
//res = new_resource(dev, 3); /* IOAPIC */
//res->base = 0xfec00000;
//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;
pci_dev_set_resources(dev);
/* Specical case. SPI Base Address. The SpiRomEnable should be set. */
res = find_resource(dev, 0xA0);
pci_write_config32(dev, 0xA0, res->base | 1 << 1);
}
/**
* @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)
{
printk(BIOS_DEBUG, "hudson_lpc_enable_childrens_resources\n");
}
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,
};

View File

@ -0,0 +1,49 @@
/*
* 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 pci_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 = 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,
};

View File

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

View File

@ -0,0 +1,33 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 Advanced Micro Devices, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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 <reset.h>
#include <arch/io.h>
#include <arch/romcc_io.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);
}

View File

@ -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 <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)
{
}
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,
};

View File

@ -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 <bitops.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)
{
}
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,
};

View File

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

View File

@ -0,0 +1,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 SB800_SMBUS_H
#define SB800_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

View File

@ -0,0 +1,218 @@
/*
* 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 <console/console.h>
#include <arch/io.h>
#include <device/device.h>
#include "spi.h"
void execute_command(volatile u8 * spi_address)
{
*(spi_address + 2) |= 1;
}
void wait4command_complete(volatile u8 * spi_address)
{
// while (*(spi_address + 2) & 1)
while ((*(spi_address + 2) & 1) && (*(spi_address + 3) & 0x80))
printk(BIOS_DEBUG, "wait4CommandComplete\n");
}
void reset_internal_fifo_pointer(volatile u8 * spi_address)
{
u8 val;
do {
*(spi_address + 2) |= 0x10;
val = *(spi_address + 0xd);
} while (val & 0x7);
}
u8 read_spi_status(volatile u8 * spi_address)
{
u8 val;
*spi_address = 0x05;
*(spi_address + 1) = 0x21;
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = 0x0; /* dummy */
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
reset_internal_fifo_pointer(spi_address);
val = *(spi_address + 0xC);
val = *(spi_address + 0xC);
val = *(spi_address + 0xC);
return val;
}
void wait4flashpart_ready(volatile u8 * spi_address)
{
while (read_spi_status(spi_address) & 1) ;
}
void write_spi_status(volatile u8 * spi_address, u8 status)
{
*spi_address = 0x50; /* EWSR */
*(spi_address + 1) = 0; /* RxByte=TxByte=0 */
execute_command(spi_address);
wait4command_complete(spi_address);
*spi_address = 0x01; /* WRSR */
*(spi_address + 1) = 0x01;
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = status;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
read_spi_status(spi_address);
}
void read_spi_id(volatile u8 * spi_address)
{
u8 mid = 0, did = 0;
*spi_address = 0x90;
*(spi_address + 1) = 0x23; /* RxByte=2, TxByte=3 */
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = 0;
*(spi_address + 0xC) = 0;
*(spi_address + 0xC) = 0;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
reset_internal_fifo_pointer(spi_address);
mid = *(spi_address + 0xC);
printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
mid = *(spi_address + 0xC);
printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
mid = *(spi_address + 0xC);
printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
mid = *(spi_address + 0xC);
did = *(spi_address + 0xC);
printk(BIOS_DEBUG, "mid=%x, did=%x\n", mid, did);
}
void spi_write_enable(volatile u8 * spi_address)
{
*spi_address = 0x06; /* Write Enable */
*(spi_address + 1) = 0x0; /* RxByte=0, TxByte=0 */
execute_command(spi_address);
wait4command_complete(spi_address);
}
void spi_write_disable(volatile u8 * spi_address)
{
*spi_address = 0x04; /* Write Enable */
*(spi_address + 1) = 0x0; /* RxByte=0, TxByte=0 */
execute_command(spi_address);
wait4command_complete(spi_address);
}
void sector_erase_spi(volatile u8 * spi_address, u32 address)
{
spi_write_enable(spi_address);
*spi_address = 0x20;
*(spi_address + 1) = 0x03; /* RxByte=0, TxByte=3 */
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = (address >> 16) & 0xFF;
*(spi_address + 0xC) = (address >> 8) & 0xFF;
*(spi_address + 0xC) = (address >> 0) & 0xFF;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
}
void chip_erase_spi(volatile u8 * spi_address)
{
spi_write_enable(spi_address);
*spi_address = 0xC7;
*(spi_address + 1) = 0x00;
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
}
void byte_program(volatile u8 * spi_address, u32 address, u32 data)
{
spi_write_enable(spi_address);
*spi_address = 0x02;
*(spi_address + 1) = 0x0 << 4 | 4;
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = (address >> 16) & 0xFF;
*(spi_address + 0xC) = (address >> 8) & 0xFF;
*(spi_address + 0xC) = (address >> 0) & 0xFF;
*(spi_address + 0xC) = data & 0xFF;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
}
void dword_noneAAI_program(volatile u8 * spi_address, u32 address, u32 data)
{
u8 i;
/*
* printk(BIOS_SPEW, "%s: addr=%x, data=%x\n", __func__, address, data);
*/
for (i = 0; i < 4; i++) {
spi_write_enable(spi_address);
*spi_address = 0x02;
*(spi_address + 1) = 0x0 << 4 | 4;
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = (address >> 16) & 0xFF;
*(spi_address + 0xC) = (address >> 8) & 0xFF;
*(spi_address + 0xC) = (address >> 0) & 0xFF;
*(spi_address + 0xC) = data & 0xFF;
data >>= 8;
address++;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
}
}
void dword_program(volatile u8 * spi_address, u32 address, u32 data)
{
spi_write_enable(spi_address);
*spi_address = 0x02;
*(spi_address + 1) = 0x0 << 4 | 7;
reset_internal_fifo_pointer(spi_address);
*(spi_address + 0xC) = (address >> 16) & 0xFF;
*(spi_address + 0xC) = (address >> 8) & 0xFF;
*(spi_address + 0xC) = (address >> 0) & 0xFF;
*(spi_address + 0xC) = data & 0xFF;
*(spi_address + 0xC) = (data >> 8) & 0xFF;
*(spi_address + 0xC) = (data >> 16) & 0xFF;
*(spi_address + 0xC) = (data >> 24) & 0xFF;
reset_internal_fifo_pointer(spi_address);
execute_command(spi_address);
wait4command_complete(spi_address);
wait4flashpart_ready(spi_address);
}
void direct_byte_program(volatile u8 * spi_address, volatile u32 * address, u32 data)
{
spi_write_enable(spi_address);
*address = data;
wait4flashpart_ready(spi_address);
}

View File

@ -0,0 +1,43 @@
/*
*****************************************************************************
*
* 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
* ***************************************************************************
*
*/
#ifndef _HUDSON_CIMX_SPI_H_
#define _HUDSON_CIMX_SPI_H_
void execute_command(volatile u8 * spi_address);
void wait4command_complete(volatile u8 * spi_address);
void reset_internal_fifo_pointer(volatile u8 * spi_address);
u8 read_spi_status(volatile u8 * spi_address);
void wait4flashpart_ready(volatile u8 * spi_address);
void write_spi_status(volatile u8 * spi_address, u8 status);
void read_spi_id(volatile u8 * spi_address);
void spi_write_enable(volatile u8 * spi_address);
void spi_write_disable(volatile u8 * spi_address);
void sector_erase_spi(volatile u8 * spi_address, u32 address);
void chip_erase_spi(volatile u8 * spi_address);
void byte_program(volatile u8 * spi_address, u32 address, u32 data);
void dword_noneAAI_program(volatile u8 * spi_address, u32 address, u32 data);
void dword_program(volatile u8 * spi_address, u32 address, u32 data);
void direct_byte_program(volatile u8 * spi_address, volatile u32 * address, u32 data);
#endif

View File

@ -0,0 +1,124 @@
/*
* 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 <usbdebug.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 void usb_set_resources(struct device *dev)
{
#if CONFIG_USBDEBUG
struct resource *res;
u32 base;
u32 old_debug;
old_debug = get_ehci_debug();
set_ehci_debug(0);
#endif
pci_dev_set_resources(dev);
#if CONFIG_USBDEBUG
res = find_resource(dev, 0x10);
set_ehci_debug(old_debug);
if (!res)
return;
base = res->base;
set_ehci_base(base);
report_resource_stored(dev, res, "");
#endif
}
static struct device_operations usb_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = usb_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_dev_read_resources,
.set_resources = usb_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,
* };
*/