Stage 1 mostly works. Stage 2 needs lots of twiddling.

cpu setup is nonexistent. No car either. Work remains ...

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@1000 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2008-11-12 04:10:45 +00:00
commit a505ea5006
11 changed files with 26 additions and 182 deletions

View file

@ -235,6 +235,8 @@
#define PCI_VENDOR_ID_CIRRUS 0x1013
#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8 /* Used by QEMU */
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_DEVICE_ID_NVIDIA_MCP55_LPC 0x0360
#define PCI_DEVICE_ID_NVIDIA_MCP55_SLAVE 0x0361

View file

@ -31,7 +31,7 @@ u8 rawpnp_read_config(u16 port, u8 reg);
void rawpnp_set_logical_device(u16 port, u8 ldn);
void rawpnp_set_enable(u16 port, int enable);
void rawpnp_set_iobase(u16 port, u8 index, u16 iobase);
void rawpnp_set_irq(u16 port, unsigned index, unsigned irq);
/* Primitive pnp resource manipulation */
void pnp_write_config(struct device * dev, u8 reg, u8 value);
u8 pnp_read_config(struct device * dev, u8 reg);

View file

@ -123,14 +123,14 @@ static void early_superio_config_w83627thg(void)
rawpnp_set_logical_device(port, ldn);
rawpnp_set_enable(port, 0);
rawpnp_set_iobase(port, PNP_IDX_IO0, 0x3f8);
rawpnp_set_irq(port, PNP_IDX_IRQ0, 4);
rawpnp_write_config(port, PNP_IDX_IRQ0, 4);
rawpnp_set_enable(port, 1);
ldn = W83627THG_SP2;
rawpnp_set_logical_device(port, ldn);
rawpnp_set_enable(port, 0);
rawpnp_set_iobase(port, PNP_IDX_IO0, 0x2f8);
rawpnp_set_irq(port, PNP_IDX_IRQ0, 3);
rawpnp_write_config(port, PNP_IDX_IRQ0, 3);
// rawpnp_write_config(dev, 0xf1, 4); // IRMODE0
rawpnp_set_enable(port, 1);
@ -176,14 +176,14 @@ static void early_superio_config_w83627thg(void)
rawpnp_set_logical_device(port, ldn); // Set COM3 to sane non-conflicting values
rawpnp_set_enable(port, 0);
rawpnp_set_iobase(port, PNP_IDX_IO0, 0x3e8);
rawpnp_set_irq(port, PNP_IDX_IRQ0, 11);
rawpnp_write_config(port, PNP_IDX_IRQ0, 11);
rawpnp_set_enable(port, 1);
ldn = W83627THG_SP2;
rawpnp_set_logical_device(port, ldn); // Set COM4 to sane non-conflicting values
rawpnp_set_enable(port, 0);
rawpnp_set_iobase(port, PNP_IDX_IO0, 0x2e8);
rawpnp_set_irq(port, PNP_IDX_IRQ0, 10);
rawpnp_write_config(port, PNP_IDX_IRQ0, 10);
rawpnp_set_enable(port, 1);
ldn = W83627THG_FDC;

View file

@ -89,6 +89,7 @@
void dump_spd_registers(u16 start, u16 end, int inc)
{
int smbus_read_byte(u16 device, u16 address);
u16 device;
device = start;
while(device <= end) {

View file

@ -32,11 +32,13 @@ STAGE2_CHIPSET_SRC += \
$(src)/southbridge/intel/i82801gx/pcie.c \
$(src)/southbridge/intel/i82801gx/sata.c \
$(src)/southbridge/intel/i82801gx/smbus.c \
$(src)/southbridge/intel/i82801gx/libsmbus.c \
$(src)/southbridge/intel/i82801gx/usb_ehci.c \
$(src)/southbridge/intel/i82801gx/usb.c \
$(src)/southbridge/intel/i82801gx/watchdog.c
STAGE0_CHIPSET_SRC += \
$(src)/southbridge/intel/i82801gx/stage1_smbus.c
$(src)/southbridge/intel/i82801gx/stage1_smbus.c \
$(src)/southbridge/intel/i82801gx/libsmbus.c \
endif

View file

@ -21,9 +21,7 @@
#ifndef SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
#define SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H
#include "chip.h"
extern void i82801gx_enable(device_t dev);
/* warning: included in stage1 and stage2 */
#define PCI_DMA_CFG 0x90
#define SERIRQ_CNTL 0x64
#define GEN_CNTL 0xd0

View file

@ -18,170 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <device/smbus_def.h>
static void smbus_delay(void)
{
inb(0x80);
}
static int smbus_wait_until_ready(void)
{
unsigned loops = SMBUS_TIMEOUT;
unsigned char byte;
do {
smbus_delay();
if (--loops == 0)
break;
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
} while (byte & 1);
return loops ? 0 : -1;
}
static int smbus_wait_until_done(void)
{
unsigned loops = SMBUS_TIMEOUT;
unsigned char byte;
do {
smbus_delay();
if (--loops == 0)
break;
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
} while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
return loops ? 0 : -1;
}
static int smbus_wait_until_blk_done(void)
{
unsigned loops = SMBUS_TIMEOUT;
unsigned char byte;
do {
smbus_delay();
if (--loops == 0)
break;
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
} while ((byte & (1 << 7)) == 0);
return loops ? 0 : -1;
}
static int do_smbus_read_byte(unsigned device, unsigned address)
{
unsigned char global_status_register;
unsigned char byte;
if (smbus_wait_until_ready() < 0) {
return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
}
/* Setup transaction */
/* Disable interrupts */
outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
/* Set the device I'm talking to */
outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
/* Set the command/address... */
outb(address & 0xff, SMBUS_IO_BASE + SMBHSTCMD);
/* Set up for a byte data read */
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2),
(SMBUS_IO_BASE + SMBHSTCTL));
/* Clear any lingering errors, so the transaction will run */
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
/* Clear the data byte... */
outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
/* Start the command */
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
SMBUS_IO_BASE + SMBHSTCTL);
/* Poll for transaction completion */
if (smbus_wait_until_done() < 0) {
return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
}
global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
/* Ignore the "In Use" status... */
global_status_register &= ~(3 << 5);
/* Read results of transaction */
byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
if (global_status_register != (1 << 1)) {
return SMBUS_ERROR;
}
return byte;
}
/* This function is neither used nor tested by me (Corey Osgood), the author
(Yinghai) probably tested/used it on i82801er */
static int do_smbus_write_block(unsigned device, unsigned length, unsigned cmd,
unsigned data1, unsigned data2)
{
unsigned char byte;
unsigned char stat;
int i;
#if CONFIG_USE_PRINTK_IN_CAR
printk_err("Untested smbus_write_block called\r\n");
#else
print_err("Untested smbus_write_block called\r\n");
#endif
/* Clear the PM timeout flags, SECOND_TO_STS */
outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
if (smbus_wait_until_ready() < 0) {
return -2;
}
/* Setup transaction */
/* Obtain ownership */
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
for (stat = 0; (stat & 0x40) == 0;) {
stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
}
/* Clear the done bit */
outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
/* Disable interrupts */
outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
/* Set the device I'm talking too */
outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
/* Set the command address */
outb(cmd & 0xff, SMBUS_IO_BASE + SMBHSTCMD);
/* Set the block length */
outb(length & 0xff, SMBUS_IO_BASE + SMBHSTDAT0);
/* Try sending out the first byte of data here */
byte = (data1 >> (0)) & 0x0ff;
outb(byte, SMBUS_IO_BASE + SMBBLKDAT);
/* Issue a block write command */
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x5 << 2) | 0x40,
SMBUS_IO_BASE + SMBHSTCTL);
for (i = 0; i < length; i++) {
/* Poll for transaction completion */
if (smbus_wait_until_blk_done() < 0) {
return -3;
}
/* Load the next byte */
if (i > 3)
byte = (data2 >> (i % 4)) & 0x0ff;
else
byte = (data1 >> (i)) & 0x0ff;
outb(byte, SMBUS_IO_BASE + SMBBLKDAT);
/* Clear the done bit */
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
SMBUS_IO_BASE + SMBHSTSTAT);
}
#if CONFIG_USE_PRINTK_IN_CAR
printk_debug("SMBUS Block complete\r\n");
#else
print_debug("SMBUS Block complete\r\n");
#endif
return 0;
}
void smbus_delay(void);
int smbus_wait_until_ready(void);
int smbus_wait_until_done(void);
int smbus_wait_until_blk_done(void);
int do_smbus_read_byte(unsigned device, unsigned address);

View file

@ -29,7 +29,7 @@
#include <config.h>
#include "i82801gx.h"
typedef struct southbridge_intel_i82801gx_config config_t;
typedef struct southbridge_intel_i82801gx_ide_dts_config config_t;
static void ide_init(struct device *dev)
{
@ -58,7 +58,7 @@ static void ide_init(struct device *dev)
ideTimingConfig |= (3 << 8); // RCT = 1 clock
ideTimingConfig |= (1 << 1); // IE0
ideTimingConfig |= (1 << 0); // TIME0
printk_debug("IDE0 ");
printk(BIOS_DEBUG, "IDE0 ");
}
pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
@ -72,7 +72,7 @@ static void ide_init(struct device *dev)
ideTimingConfig |= (3 << 8); // RCT = 1 clock
ideTimingConfig |= (1 << 1); // IE0
ideTimingConfig |= (1 << 0); // TIME0
printk_debug("IDE1 ");
printk(BIOS_DEBUG, "IDE1 ");
}
pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
@ -87,7 +87,7 @@ static void ide_init(struct device *dev)
/* Interrupt Pin is set by D31IP.PIP */
pci_write_config32(dev, INTR_LN, 0xff); /* Int 15 */
}
void i82801gx_enable(struct device * dev);
struct device_operations i82801gx_ide = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_INTEL,

View file

@ -29,7 +29,6 @@
#include <config.h>
#include <io.h>
#include "i82801gx.h"
#include "i82801gx_smbus.h"
static void enable_smbus(void)
{
@ -58,11 +57,13 @@ static void enable_smbus(void)
/* Clear any lingering errors, so transactions can run. */
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
print_debug("SMBus controller enabled.\r\n");
printk(BIOS_DEBUG, "SMBus controller enabled.\r\n");
}
/* some prototypes are hand-declared since the include files are still a little too stage-2 oriented */
int smbus_read_byte(u16 device, u16 address)
{
int do_smbus_read_byte(unsigned device, unsigned address);
return do_smbus_read_byte(device, address);
}

View file

@ -72,6 +72,7 @@ static struct pci_operations lops_pci = {
};
/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
void i82801gx_enable(struct device * dev);
struct device_operations i82801gx_usb_ehci = {
.id = {.type = DEVICE_ID_PCI,
{.pci = {.vendor = PCI_VENDOR_ID_INTEL,

View file

@ -23,6 +23,7 @@
#include <console.h>
#include <device/pci.h>
#include <msr.h>
#include <io.h>
#include <legacy.h>
#include <device/pci_ids.h>
#include <statictree.h>