Bring 8111 over to v3.

Rename files and functions as needed. 

There is regularity to the naming. Stage1 stuff is called stage1_*. The rest is not. 
Most .c files have a corresponding .dts. The code is simpler and smaller and has less
duplication. 

Most (all) romcc artifacts removed. 

I've made a lot of effort to get copyright headers done correctly, using 'svn log'. 

next are the 8132, 8151, and serengeti, then comes simnow. 
 
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>


git-svn-id: svn://coreboot.org/repository/coreboot-v3@767 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2008-08-15 19:08:44 +00:00
commit 60a9026573
27 changed files with 1916 additions and 0 deletions

View file

@ -0,0 +1,40 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007 coresystems GmbH
## (Written by Stefan Reinauer <stepan@coresystems.de> for 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; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
ifeq ($(CONFIG_SOUTHBRIDGE_AMD_AMD8111),y)
STAGE2_CHIPSET_SRC += $(src)/southbridge/amd/amd8111/amd8111.c
STAGE2_CHIPSET_SRC += \
$(src)/southbridge/amd/amd8111/ac97.c \
$(src)/southbridge/amd/amd8111/acpi.c \
$(src)/southbridge/amd/amd8111/ide.c \
$(src)/southbridge/amd/amd8111/lpc.c \
$(src)/southbridge/amd/amd8111/nic.c \
$(src)/southbridge/amd/amd8111/pci.c \
$(src)/southbridge/amd/amd8111/smbus.c \
$(src)/southbridge/amd/amd8111/usb.c \
$(src)/southbridge/amd/amd8111/usb2.c
STAGE0_CHIPSET_OBJ += $(obj)/southbridge/amd/amd8111/stage1.o
endif

View file

@ -0,0 +1,64 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2003 Linux NetworX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 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 "amd8111.h"
static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x2c,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations ac97audio = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = 0x746D}}},
.constructor = default_device_constructor,
.phase3_scan = 0,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = NULL,
.ops_pci = &lops_pci,
};
struct device_operations ac97modem = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = 0x746E}}},
.constructor = default_device_constructor,
.phase3_scan = 0,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = NULL,
.ops_pci = &lops_pci,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "ac97modem";
/* configuration variables go here */
};

View file

@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "ac97modem";
/* configuration variables go here */
};

View file

@ -0,0 +1,238 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2003 Linux NetworX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <console/console.h>
#include <device/device.h>
#include <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>#include "amd8111.h"
#include "amd8111_smbus.h"
#define PREVIOUS_POWER_STATE 0x43
#define MAINBOARD_POWER_OFF 0
#define MAINBOARD_POWER_ON 1
#define SLOW_CPU_OFF 0
#define SLOW_CPU__ON 1
#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
#endif
static int lsmbus_recv_byte(struct device * dev)
{
unsigned device;
struct resource *res;
device = dev->path.i2c.device;
res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
return do_smbus_recv_byte(res->base, device);
}
static int lsmbus_send_byte(struct device * dev, u8 val)
{
unsigned device;
struct resource *res;
device = dev->path.i2c.device;
res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
return do_smbus_send_byte(res->base, device, val);
}
static int lsmbus_read_byte(struct device * dev, u8 address)
{
unsigned device;
struct resource *res;
device = dev->path.i2c.device;
res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
return do_smbus_read_byte(res->base, device, address);
}
static int lsmbus_write_byte(struct device * dev, u8 address, u8 val)
{
unsigned device;
struct resource *res;
device = dev->path.i2c.device;
res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
return do_smbus_write_byte(res->base, device, address, val);
}
#ifdef CONFIG_ACPI_TABLE
unsigned pm_base;
#endif
static void acpi_init(struct device *dev)
{
u8 byte;
u16 word;
u16 pm10_bar;
u32 dword;
int on;
#if 0
printk(BIOS_DEBUG, "ACPI: disabling NMI watchdog.. ");
byte = pci_read_config8(dev, 0x49);
pci_write_config8(dev, 0x49, byte | (1<<2));
byte = pci_read_config8(dev, 0x41);
pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<2));
/* added from sourceforge */
byte = pci_read_config8(dev, 0x48);
pci_write_config8(dev, 0x48, byte | (1<<3));
printk(BIOS_DEBUG, "done.\n");
printk(BIOS_DEBUG, "ACPI: Routing IRQ 12 to PS2 port.. ");
word = pci_read_config16(dev, 0x46);
pci_write_config16(dev, 0x46, word | (1<<9));
printk(BIOS_DEBUG, "done.\n");
#endif
/* To enable the register 0xcf9 in the IO space
* bit [D5] is set in the amd8111 configuration register.
* The config. reg. is devBx41. Register 0xcf9 allows
* hard reset capability to the system. For the ACPI
* reset.reg values in fadt.c to work this register
* must be enabled.
*/
byte = pci_read_config8(dev, 0x41);
pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<5));
/* power on after power fail */
on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
get_option(&on, "power_on_after_fail");
byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
byte &= ~0x40;
if (!on) {
byte |= 0x40;
}
pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
printk_info("set power %s after power fail\n", on?"on":"off");
/* switch serial irq logic from quiet mode to continuous
* mode for Winbond W83627HF Rev. 17
*/
byte = pci_read_config8(dev, 0x4a);
pci_write_config8(dev, 0x4a, byte | (1<<6));
/* Throttle the CPU speed down for testing */
on = SLOW_CPU_OFF;
get_option(&on, "slow_cpu");
if(on) {
pm10_bar = (pci_read_config16(dev, 0x58)&0xff00);
outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
dword = inl(pm10_bar + 0x10);
on = 8-on;
printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
(on*12)+(on>>1),(on&1)*5);
}
#ifdef CONFIG_ACPI_TABLE
pm_base = pci_read_config16(dev, 0x58) & 0xff00;
printk(BIOS_DEBUG, "pm_base: 0x%04x\n",pm_base);
#endif
}
static void acpi_read_resources(struct device * dev)
{
struct resource *resource;
/* Handle the generic bars */
pci_dev_read_resources(dev);
/* Add the ACPI/SMBUS bar */
resource = new_resource(dev, 0x58);
resource->base = 0;
resource->size = 256;
resource->align = log2(256);
resource->gran = log2(256);
resource->limit = 65536;
resource->flags = IORESOURCE_IO;
resource->index = 0x58;
}
static void acpi_enable_resources(struct device * dev)
{
u8 byte;
/* Enable the generic pci resources */
pci_dev_enable_resources(dev);
/* Enable the ACPI/SMBUS Bar */
byte = pci_read_config8(dev, 0x41);
byte |= (1 << 7);
pci_write_config8(dev, 0x41, byte);
/* Set the class code */
pci_write_config32(dev, 0x60, 0x06800000);
}
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x7c,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct smbus_bus_operations lops_smbus_bus = {
.recv_byte = lsmbus_recv_byte,
.send_byte = lsmbus_send_byte,
.read_byte = lsmbus_read_byte,
.write_byte = lsmbus_write_byte,
};
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations ac97audio = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_ACPI}}},
.constructor = default_device_constructor,
.phase3_scan = scan_static_bus,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = acpi_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = acpi_enable_resources,
.phase6_init = acpi_init,
.ops_pci = &lops_pci,
.ops_smbus_bus = &lops_smbus_bus,
};

View file

@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "ac97modem";
/* configuration variables go here */
};

View file

@ -0,0 +1,106 @@
/*
* AMD 8111 "southbridge"
* This file is part of the coreboot project.
* Copyright (C) 2004-2005 Linux Networx
* (Written by Eric Biederman <ebiederman@lnxi.com> and Jason Schildt for Linux Networx)
* Copyright (C) 2005-7 YingHai Lu
* Copyright (C) 2005 Ollie Lo
* Copyright (C) 2005-2007 Stefan Reinauer <stepan@openbios.org>
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
void amd8111_enable(struct device * dev)
{
struct device * lpc_dev;
struct device * bus_dev;
unsigned index;
unsigned reg_old, reg;
/* See if we are behind the amd8111 pci bridge */
bus_dev = dev->bus->dev;
if ((bus_dev->vendor == PCI_VENDOR_ID_AMD) &&
(bus_dev->device == PCI_DEVICE_ID_AMD_8111_PCI))
{
unsigned devfn;
devfn = bus_dev->path.pci.devfn + (1 << 3);
lpc_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
index = ((dev->path.u.pci.devfn & ~7) >> 3) + 8;
if (dev->path.u.pci.devfn == 2) { /* EHCI */
index = 16;
}
} else {
unsigned devfn;
devfn = (dev->path.u.pci.devfn) & ~7;
lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
index = dev->path.u.pci.devfn & 7;
}
if ((!lpc_dev) || (index >= 17)) {
return;
}
if ((lpc_dev->vendor != PCI_VENDOR_ID_AMD) ||
(lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA))
{
u32 id;
id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8111_ISA << 16))) {
return;
}
}
if (index < 16) {
reg = reg_old = pci_read_config16(lpc_dev, 0x48);
reg &= ~(1 << index);
if (dev->enabled) {
reg |= (1 << index);
}
if (reg != reg_old) {
pci_write_config16(lpc_dev, 0x48, reg);
}
}
else if (index == 16) {
reg = reg_old = pci_read_config8(lpc_dev, 0x47);
reg &= ~(1 << 7);
if (!dev->enabled) {
reg |= (1 << 7);
}
if (reg != reg_old) {
pci_write_config8(lpc_dev, 0x47, reg);
}
}
}
struct device_operations mcp55_ide = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_PCI}}},
.constructor = default_device_constructor,
.phase3_scan = 0,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase6_init = NULL,
.ops_pci = &pci_dev_ops_pci,
};

View file

@ -0,0 +1,6 @@
#ifndef AMD8111_H
#define AMD8111_H
void amd8111_enable(device_t dev);
#endif /* AMD8111_H */

View file

@ -0,0 +1,17 @@
#include <device/smbus_def.h>
#define SMBGSTATUS 0xe0
#define SMBGCTL 0xe2
#define SMBHSTADDR 0xe4
#define SMBHSTDAT 0xe6
#define SMBHSTCMD 0xe8
#define SMBHSTFIFO 0xe9
#define SMBUS_TIMEOUT (100*1000*10)
#define SMBUS_STATUS_MASK 0xfbff
static inline void smbus_delay(void)
{
outb(0x80, 0x80);
}

View file

@ -0,0 +1,87 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2003 Linux NetworX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#nclude "amd8111.h"
static void ide_init(struct device *dev)
{
struct southbridge_amd_amd8111_ide_config *conf;
/* Enable ide devices so the linux ide driver will work */
u16 word;
u8 byte;
conf = dev->chip_info;
word = pci_read_config16(dev, 0x40);
/* Ensure prefetch is disabled */
word &= ~((1 << 15) | (1 << 13));
if (conf->ide1_enable) {
/* Enable secondary ide interface */
word |= (1<<0);
printk(BIOS_DEBUG, "IDE1 ");
}
if (conf->ide0_enable) {
/* Enable primary ide interface */
word |= (1<<1);
printk(BIOS_DEBUG, "IDE0 ");
}
word |= (1<<12);
word |= (1<<14);
pci_write_config16(dev, 0x40, word);
byte = 0x20 ; // Latency: 64-->32
pci_write_config8(dev, 0xd, byte);
word = 0x0f;
pci_write_config16(dev, 0x42, word);
}
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x70,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations mcp55_ide = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_IDE}}},
.constructor = default_device_constructor,
.phase3_scan = 0,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = ide_init,
.ops_pci = &lops_pci
};

View file

@ -0,0 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_ide";
ide0_enable = "0";
ide1_enable = "1";
};

View file

@ -0,0 +1,220 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2003 Linux NetworX, SuSE Linux AG
* Copyright (C) 2006 AMD
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
#define NMI_OFF 0
struct ioapicreg {
unsigned int reg;
unsigned int value_low, value_high;
};
static struct ioapicreg ioapicregvalues[] = {
#define ALL (0xff << 24)
#define NONE (0)
#define DISABLED (1 << 16)
#define ENABLED (0 << 16)
#define TRIGGER_EDGE (0 << 15)
#define TRIGGER_LEVEL (1 << 15)
#define POLARITY_HIGH (0 << 13)
#define POLARITY_LOW (1 << 13)
#define PHYSICAL_DEST (0 << 11)
#define LOGICAL_DEST (1 << 11)
#define ExtINT (7 << 8)
#define NMI (4 << 8)
#define SMI (2 << 8)
#define INT (1 << 8)
/* IO-APIC virtual wire mode configuration */
/* mask, trigger, polarity, destination, delivery, vector */
{ 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE},
{ 1, DISABLED, NONE},
{ 2, DISABLED, NONE},
{ 3, DISABLED, NONE},
{ 4, DISABLED, NONE},
{ 5, DISABLED, NONE},
{ 6, DISABLED, NONE},
{ 7, DISABLED, NONE},
{ 8, DISABLED, NONE},
{ 9, DISABLED, NONE},
{ 10, DISABLED, NONE},
{ 11, DISABLED, NONE},
{ 12, DISABLED, NONE},
{ 13, DISABLED, NONE},
{ 14, DISABLED, NONE},
{ 15, DISABLED, NONE},
{ 16, DISABLED, NONE},
{ 17, DISABLED, NONE},
{ 18, DISABLED, NONE},
{ 19, DISABLED, NONE},
{ 20, DISABLED, NONE},
{ 21, DISABLED, NONE},
{ 22, DISABLED, NONE},
{ 23, DISABLED, NONE},
/* Be careful and don't write past the end... */
};
static void setup_ioapic(void)
{
int i;
unsigned long value_low, value_high;
unsigned long ioapic_base = 0xfec00000;
volatile unsigned long *l;
struct ioapicreg *a = ioapicregvalues;
unsigned long bsp_apicid = lapicid();
l = (unsigned long *) ioapic_base;
ioapicregvalues[0].value_high = bsp_apicid<<(56-32);
printk(BIOS_DEBUG, "amd8111: ioapic bsp_apicid = %02x\n", bsp_apicid);
for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]);
i++, a++) {
l[0] = (a->reg * 2) + 0x10;
l[4] = a->value_low;
value_low = l[4];
l[0] = (a->reg *2) + 0x11;
l[4] = a->value_high;
value_high = l[4];
if ((i==0) && (value_low == 0xffffffff)) {
printk_warning("IO APIC not responding.\n");
return;
}
printk(BIOS_SPEW, "for IRQ, reg 0x%08x value 0x%08x 0x%08x\n",
a->reg, a->value_low, a->value_high);
}
}
static void enable_hpet(struct device *dev)
{
unsigned long hpet_address;
pci_write_config32(dev,0xa0, 0xfed00001);
hpet_address = pci_read_config32(dev,0xa0)& 0xfffffffe;
printk(BIOS_DEBUG, "enabling HPET @0x%x\n", hpet_address);
}
static void lpc_init(struct device *dev)
{
u8 byte;
int nmi_option;
/* IO APIC initialization */
byte = pci_read_config8(dev, 0x4B);
byte |= 1;
pci_write_config8(dev, 0x4B, byte);
setup_ioapic();
/* posted memory write enable */
byte = pci_read_config8(dev, 0x46);
pci_write_config8(dev, 0x46, byte | (1<<0));
/* Enable 5Mib Rom window */
byte = pci_read_config8(dev, 0x43);
byte |= 0xc0;
pci_write_config8(dev, 0x43, byte);
/* Enable Port 92 fast reset */
byte = pci_read_config8(dev, 0x41);
byte |= (1 << 5);
pci_write_config8(dev, 0x41, byte);
/* Enable Error reporting */
/* Set up sync flood detected */
byte = pci_read_config8(dev, 0x47);
byte |= (1 << 1);
pci_write_config8(dev, 0x47, byte);
/* Set up NMI on errors */
byte = pci_read_config8(dev, 0x40);
byte |= (1 << 1); /* clear PW2LPC error */
byte |= (1 << 6); /* clear LPCERR */
pci_write_config8(dev, 0x40, byte);
nmi_option = NMI_OFF;
get_option(&nmi_option, "nmi");
if (nmi_option) {
byte |= (1 << 7); /* set NMI */
pci_write_config8(dev, 0x40, byte);
}
/* Initialize the real time clock */
rtc_init(0);
/* Initialize isa dma */
isa_dma_init();
/* Initialize the High Precision Event Timers */
enable_hpet(dev);
}
static void amd8111_lpc_read_resources(struct device * dev)
{
struct resource *res;
/* Get the normal pci resources of this device */
pci_dev_read_resources(dev);
/* Add an extra subtractive resource for both memory and I/O */
res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
}
static void amd8111_lpc_enable_resources(struct device * dev)
{
pci_dev_enable_resources(dev);
enable_childrens_resources(dev);
}
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x70,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations amd8111_lpc = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_ISA}}},
.constructor = default_device_constructor,
.phase3_scan = scan_static_bus,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = amd8111_lpc_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = amd8111_lpc_enable_resources,
.phase6_init = lpc_init,
.ops_pci = &lops_pci,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_lpc";
};

View file

@ -0,0 +1,107 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2003 Linux Networx
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
#define CMD3 0x54
typedef enum {
VAL3 = (1 << 31), /* VAL bit for byte 3 */
VAL2 = (1 << 23), /* VAL bit for byte 2 */
VAL1 = (1 << 15), /* VAL bit for byte 1 */
VAL0 = (1 << 7), /* VAL bit for byte 0 */
}VAL_BITS;
typedef enum {
/* VAL3 */
ASF_INIT_DONE_ALIAS = (1 << 29),
/* VAL2 */
JUMBO = (1 << 21),
VSIZE = (1 << 20),
VLONLY = (1 << 19),
VL_TAG_DEL = (1 << 18),
/* VAL1 */
EN_PMGR = (1 << 14),
INTLEVEL = (1 << 13),
FORCE_FULL_DUPLEX = (1 << 12),
FORCE_LINK_STATUS = (1 << 11),
APEP = (1 << 10),
MPPLBA = (1 << 9),
/* VAL0 */
RESET_PHY_PULSE = (1 << 2),
RESET_PHY = (1 << 1),
PHY_RST_POL = (1 << 0),
}CMD3_BITS;
static void nic_init(struct device *dev)
{
struct southbridge_amd_amd8111_nic_config *conf;
struct resource *resource;
unsigned long mmio;
conf = dev->device_configuration;
resource = find_resource(dev, PCI_BASE_ADDRESS_0);
mmio = resource->base;
/* Hard Reset PHY */
printk(BIOS_DEBUG, "Reseting PHY... ");
if (conf->phy_lowreset) {
writel(VAL0 | PHY_RST_POL | RESET_PHY , (void *)(mmio + CMD3));
} else {
writel(VAL0 | RESET_PHY, (void *)(mmio + CMD3));
}
mdelay(15);
writel(RESET_PHY, (void *)(mmio + CMD3));
printk(BIOS_DEBUG, "Done\n");
}
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0xc8,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations amd8111_nic = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_NIC}}},
.constructor = default_device_constructor,
.phase3_scan = 0,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = nic_init,
.ops_pci = &lops_pci,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_nic";
};

View file

@ -0,0 +1,83 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2003 Linux Networx
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
static void pci_init(struct device *dev)
{
/* Enable pci error detecting */
u32 dword;
/* System error enable */
dword = pci_read_config32(dev, 0x04);
dword |= (1<<8); /* System error enable */
dword |= (7<<28); /* Clear possible errors */
pci_write_config32(dev, 0x04, dword);
/* System,Parity,timer,and abort error enable */
dword = pci_read_config32(dev, 0x3c);
dword |= (1<<16); /* Parity */
dword |= (1<<17); /* System */
dword |= (1<<21); /* Master abort */
// dword &= ~(1<<21); /* Master abort */
// dword |= (1<<27); /* Discard timer */
dword &= ~(1<<27); /* Discard timer */
dword |= (1<<26); /* DTSTAT error clear */
pci_write_config32(dev, 0x3c, dword);
/* CRC flood enable */
dword = pci_read_config32(dev, 0xc4);
dword |= (1<<1); /* CRC Flood enable */
dword |= (1<<8); /* Clear any CRC errors */
dword |= (1<<4); /* Clear any LKFAIL errors */
pci_write_config32(dev, 0xc4, dword);
/* Clear possible errors */
dword = pci_read_config32(dev, 0x1c);
dword |= (1<<27); /* STA */
dword |= (1<<28); /* RTA */
dword |= (1<<29); /* RMA */
dword |= (1<<30); /* RSE */
dword |= (1<<31); /* DPE */
dword |= (1<<24); /* MDPE */
pci_write_config32(dev, 0x1c, dword);
}
struct device_operations amd8111_pci = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_PCI}}},
.constructor = default_device_constructor,
.phase3_scan = pci_scan_bridge,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_bus_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_bus_enable_resources,
.phase6_init = pci_init,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_pci";
};

View file

@ -0,0 +1,64 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2004 Linux Networx
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#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 <arch/io.h>
#include "amd8111.h"
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x44,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct smbus_bus_operations lops_smbus_bus = {
/* I haven't seen the 2.0 SMBUS controller used yet. */
};
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations amd8111_smbus = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_SMB}}},
.constructor = default_device_constructor,
.phase3_scan = scan_static_bus,
.phase4_enable_disable = amd8111_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = NULL,
.ops_pci = &lops_pci
.ops_smbus_bus = &lops_smbus_bus,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_smbus";
};

View file

@ -0,0 +1,146 @@
/*
* AMD 8111 "southbridge"
* This file is part of the coreboot project.
* Copyright (C) 2005-7 YingHai Lu
* Copyright (C) 2005 Marc Jones, AMD
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
/* by yhlu 2005.10 */
/**
* Get the device fn for the 8111.
* @param bus the bus on which to search
* @return The device number, in the range 0-31
*/
static u32 get_sbdn(unsigned bus)
{
u32 dev;
/* Find the device.
* There can only be one 8111 on a hypertransport chain/bus.
*/
pci_conf1_find_on_bus(bus, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_PCI, &dev);
/* this makes no sense. At all. I wonder if this is an ancient bug. >> 15? */
#warning shift right 15? makes no sense.
return (dev>>15) & 0x1f;
}
/**
* Get the device fn for the 8111.
* @param bus the bus on which to search
* @return The device number, in the range 0-31
*/
static void enable_cf9_x(unsigned sbbusn, unsigned sbdn)
{
u32 dev;
u8 byte;
dev = PCI_BDF(sbbusn, sbdn+1, 3); //ACPI
/* enable cf9 */
byte = pci_conf1_read_config8(dev, 0x41);
byte |= (1<<6) | (1<<5);
pci_conf1+write_config8(dev, 0x41, byte);
}
/**
* Enable "cf9". cf9 is a commonly used 8-bit IO address for reset, overlapping the 32-bit cf8 config address.
*/
static void enable_cf9(void)
{
u32 sblk = get_sblk();
u32 sbbusn = get_sbbusn(sblk);
u32 sbdn = get_sbdn(sbbusn);
enable_cf9_x(sbbusn, sbdn);
}
/**
* Perform a hard reset. Set the "bios reset" indicator to be used by subsequent coreboot to know we
* came out of a coreboot-initiated reset.
* @return Never returns.
*/
static void hard_reset(void)
{
set_bios_reset();
/* reset */
enable_cf9();
outb(0x0e, 0x0cf9); // make sure cf9 is enabled
}
/**
* Enable a FID change on the southbridge.
* @param sbbusn south bridge bus number
* @param sbdn southbridge device numer
*/
static void enable_fid_change_on_sb(u16 sbbusn, u16 sbdn)
{
u32 dev;
dev = PCI_BDF(sbbusn, sbdn+1, 3); // ACPI
pci_conf1_write_config8(dev, 0x74, 4);
/* set VFSMAF ( VID/FID System Management Action Field) to 2 */
pci_conf1_write_config32(dev, 0x70, 2<<12);
}
/**
* Initiate a soft reset given a bus and device number. Indicate via set_bios_reset that we did so.
* @param sbbusn south bridge bus number
* @param sbdn southbridge device numer
* @return never
*/
static void soft_reset_x(unsigned sbbusn, unsigned sbdn)
{
u32 dev;
dev = PCI_BDF(sbbusn, sbdn+1, 0); //ISA
/* Reset */
set_bios_reset();
pci_conf1_write_config8(dev, 0x47, 1);
}
/**
* Initiate a soft reset by finding the southbridge and calling soft_reset_x
* @return never
*/
static void soft_reset(void)
{
unsigned sblk = get_sblk();
unsigned sbbusn = get_sbbusn(sblk);
unsigned sbdn = get_sbdn(sbbusn);
return soft_reset_x(sbbusn, sbdn);
}

View file

@ -0,0 +1,48 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2003 Linux NetworX
* Copyright (C) 2004 Ollie Lo
* Copyright (C) 2006 YingHai Lu
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
/**
* Enable the 5 MB address space for the ROM
*/
static void amd8111_enable_rom(void)
{
u8 byte;
u32 dev;
/* Enable 5MB rom access at 0xFFB00000 - 0xFFFFFFFF */
/* Locate the amd8111 */
pci_locate_device_on_bus(0, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA, &dev);
/* Set the 5MB enable bits */
byte = pci_conf1_read_config8(dev, 0x43);
byte |= 0xC0;
pci_conf1_write_config8(dev, 0x43, byte);
}

View file

@ -0,0 +1,47 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2004 Stefan Reinauer <stepan@openbios.org>
* Copyright (C) 2005-7 YingHai Lu
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
void hard_reset(void)
{
u32 dev;
unsigned int bus;
unsigned int node = 0;
unsigned int link = get_sblk();
/* Find the device.
* There can only be one 8111 on a hypertransport chain/bus.
*/
bus = node_link_to_bus(node, link);
pci_locate_device_on_bus(0, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA, &dev);
/* Reset */
set_bios_reset();
pci_write_config8(dev, 0x47, 1);
}

View file

@ -0,0 +1,291 @@
/*
* AMD 8111 "southbridge"
* This file is part of the coreboot project.
* Copyright (C) 2004-2005 Linux Networx
* (Written by Eric Biederman <ebiederman@lnxi.com> and Jason Schildt for Linux Networx)
* Copyright (C) 2005-7 YingHai Lu
* Copyright (C) 2005 Ollie Lo
* Copyright (C) 2005-2007 Stefan Reinauer <stepan@openbios.org>
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#include "amd8111.h"
#include "amd8111_smbus.h"
#define SMBUS_IO_BASE 0x0f00
void enable_smbus(void)
{
u32 bdf;
u8 enable;
/* this 746b is the ACPI device. This is from original code. It's weird however. */
pci_locate_device_on_bus(0, PCI_VENDOR_ID_AMD, 0x746b, &dev);
if (dev == PCI_DEV_INVALID) {
die("SMBUS controller not found\r\n");
}
pci_conf1_write_config32(dev, 0x58, SMBUS_IO_BASE | 1);
enable = pci_conf1_read_config8(dev, 0x41);
pci_conf1_write_config8(dev, 0x41, enable | (1 << 7));
/* check that we can see the smbus controller I/O. */
if (inw(SMBUS_IO_BASE)==0xFF){
die("SMBUS controller I/O not found\n");
}
/* clear any lingering errors, so the transaction will run */
outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
printk(BIOS_SPEW, "SMBus controller enabled\r\n");
}
int smbus_wait_until_ready(u16 smbus_io_base)
{
unsigned long loops;
loops = SMBUS_TIMEOUT;
do {
u16 val;
smbus_delay();
val = inw(smbus_io_base + SMBGSTATUS);
if ((val & 0x800) == 0) {
break;
}
if(loops == (SMBUS_TIMEOUT / 2)) {
outw(inw(smbus_io_base + SMBGSTATUS),
smbus_io_base + SMBGSTATUS);
}
} while(--loops);
return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
int smbus_wait_until_done(u16 smbus_io_base)
{
unsigned long loops;
loops = SMBUS_TIMEOUT;
do {
u16 val;
smbus_delay();
val = inw(smbus_io_base + SMBGSTATUS);
if (((val & 0x8) == 0) | ((val & 0x0037) != 0)) {
break;
}
} while(--loops);
return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
int do_smbus_recv_byte(u16 smbus_io_base, u16 device)
{
u16 global_status_register;
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(0, smbus_io_base + SMBHSTCMD);
/* set up for a send byte */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* set the data word...*/
outw(0, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
/* read results of transaction */
byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
return SMBUS_ERROR;
}
return byte;
}
int do_smbus_send_byte(u16 smbus_io_base, u16 device, u16 value)
{
u16 global_status_register;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(0, smbus_io_base + SMBHSTCMD);
/* set up for a send byte */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* set the data word...*/
outw(value, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
return SMBUS_ERROR;
}
return 0;
}
int do_smbus_read_byte(u16 smbus_io_base, u16 device, u8 address)
{
u16 global_status_register;
u8 byte;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
/* set the command/address... */
outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
/* set up for a byte data read */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* clear the data word...*/
outw(0, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
/* read results of transaction */
byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
return SMBUS_ERROR;
}
return byte;
}
int do_smbus_write_byte(u16 smbus_io_base, u16 device, u8 address, u8 val)
{
u16 global_status_register;
if (smbus_wait_until_ready(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* setup transaction */
/* disable interrupts */
outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
/* set the device I'm talking too */
outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
/* set up for a byte data write */ /* FIXME */
outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
/* clear any lingering errors, so the transaction will run */
/* Do I need to write the bits to a 1 to clear an error? */
outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
/* write the data word...*/
outw(val, smbus_io_base + SMBHSTDAT);
/* start the command */
outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
/* poll for transaction completion */
if (smbus_wait_until_done(smbus_io_base) < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inw(smbus_io_base + SMBGSTATUS);
if ((global_status_register & SMBUS_STATUS_MASK) != (1 << 4)) {
return SMBUS_ERROR;
}
return 0;
}
int smbus_recv_byte(u16 device)
{
return do_smbus_recv_byte(SMBUS_IO_BASE, device);
}
int smbus_send_byte(u16 device, u8 val)
{
return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
}
int smbus_read_byte(u16 device, u16 address)
{
return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
}
int smbus_write_byte(u16 device, u16 address, u8 val)
{
return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
}

View file

@ -0,0 +1,60 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2004 Linux Networx
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#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 <arch/io.h>
#include "amd8111.h"
static void lpci_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
{
pci_write_config32(dev, 0x70,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
static struct pci_operations lops_pci = {
.set_subsystem = lpci_set_subsystem,
};
struct device_operations amd8111_usb = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_USB}}},
.constructor = default_device_constructor,
.phase3_scan = scan_static_bus,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = NULL,
.ops_pci = &lops_pci
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_usb";
};

View file

@ -0,0 +1,58 @@
/*
*
* This file is part of the coreboot project.
* Copyright (C) 2003 Tyan
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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 <types.h>
#include <lib.h>
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>
#include <config.h>
#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 <arch/io.h>
#include "amd8111.h"
static void amd8111_usb2_enable(struct device *dev)
{
// Due to buggy USB2 we force it to disable.
dev->enabled = 0;
amd8111_enable(dev);
printk(BIOS_DEBUG, "USB2 disabled.\n");
}
struct device_operations amd8111_usb2 = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8111_USB}}},
.constructor = default_device_constructor,
.phase3_scan = scan_static_bus,
.phase4_enable_disable = amd8111_usb2_enable,
.phase4_read_resources = pci_dev_read_resources,
.phase4_set_resources = pci_dev_set_resources,
.phase5_enable_resources = pci_dev_enable_resources,
.phase6_init = NULL,
};

View file

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
{
device_operations = "amd8111_usb";
};