add cs5536
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2265 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
05c0869fac
commit
5d69896c87
|
@ -0,0 +1,4 @@
|
|||
#config chip.h
|
||||
driver cs5536.o
|
||||
#driver cs5535_pci.o
|
||||
#driver cs5535_ide.o
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _SOUTHBRIDGE_AMD_CS5536
|
||||
#define _SOUTHBRIDGE_AMD_CS5536
|
||||
|
||||
extern struct chip_operations southbridge_amd_cs5536_ops;
|
||||
|
||||
struct southbridge_amd_cs5536_config {
|
||||
int none;
|
||||
};
|
||||
|
||||
#endif /* _SOUTHBRIDGE_AMD_CS5536 */
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
#include <arch/io.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <console/console.h>
|
||||
#include "cs5536.h"
|
||||
|
||||
static void southbridge_init(struct device *dev)
|
||||
{
|
||||
printk_err("cs5536: %s\n", __FUNCTION__);
|
||||
setup_i8259();
|
||||
}
|
||||
|
||||
static void southbridge_enable(struct device *dev)
|
||||
{
|
||||
printk_err("%s: dev is %p\n", __FUNCTION__, dev);
|
||||
}
|
||||
|
||||
static void cs5536_pci_dev_enable_resources(device_t dev)
|
||||
{
|
||||
printk_err("cs5536.c: %s()\n", __FUNCTION__);
|
||||
pci_dev_enable_resources(dev);
|
||||
enable_childrens_resources(dev);
|
||||
}
|
||||
|
||||
static struct device_operations southbridge_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = cs5536_pci_dev_enable_resources,
|
||||
.init = southbridge_init,
|
||||
.enable = southbridge_enable,
|
||||
.scan_bus = scan_static_bus,
|
||||
};
|
||||
|
||||
static struct pci_driver cs5535_pci_driver __pci_driver = {
|
||||
.ops = &southbridge_ops,
|
||||
.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_CS5536_ISA
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _CS5535_H
|
||||
#define _CS5535_H
|
||||
|
||||
#endif
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
*
|
||||
* cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
|
||||
*
|
||||
*
|
||||
* This file implements the initialization sequence documented in section 4.2 of
|
||||
* AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
|
||||
*
|
||||
*/
|
||||
|
||||
#define CS5536_GLINK_PORT_NUM 0x02 /* the geode link port number to the CS5536 */
|
||||
#define CS5536_DEV_NUM 0x0F /* default PCI device number for CS5536 */
|
||||
|
||||
/**
|
||||
* @brief Setup PCI IDSEL for CS5536
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static void cs5536_setup_extmsr(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
/* forward MSR access to CS5536_GLINK_PORT_NUM to CS5536_DEV_NUM */
|
||||
msr.hi = msr.lo = 0x00000000;
|
||||
if (CS5536_GLINK_PORT_NUM <= 4) {
|
||||
msr.lo = CS5536_DEV_NUM << ((CS5536_GLINK_PORT_NUM - 1) * 8);
|
||||
} else {
|
||||
msr.hi = CS5536_DEV_NUM << ((CS5536_GLINK_PORT_NUM - 5) * 8);
|
||||
}
|
||||
wrmsr(0x5000201e, msr);
|
||||
}
|
||||
|
||||
static void cs5536_setup_idsel(void)
|
||||
{
|
||||
/* write IDSEL to the write once register at address 0x0000 */
|
||||
outl(0x1 << (CS5536_DEV_NUM + 10), 0);
|
||||
}
|
||||
|
||||
static void cs5536_usb_swapsif(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
msr = rdmsr(0x51600005);
|
||||
//USB Serial short detect bit.
|
||||
if (msr.hi & 0x10) {
|
||||
/* We need to preserve bits 32,33,35 and not clear any BIST error, but clear the
|
||||
* SERSHRT error bit */
|
||||
msr.hi &= 0xFFFFFFFB;
|
||||
wrmsr(0x51600005, msr);
|
||||
}
|
||||
}
|
||||
|
||||
static int cs5536_setup_iobase(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
/* setup LBAR for SMBus controller */
|
||||
__builtin_wrmsr(0x5140000b, 0x00006000, 0x0000f001);
|
||||
/* setup LBAR for GPIO */
|
||||
__builtin_wrmsr(0x5140000c, 0x00006100, 0x0000f001);
|
||||
/* setup LBAR for MFGPT */
|
||||
__builtin_wrmsr(0x5140000d, 0x00006200, 0x0000f001);
|
||||
/* setup LBAR for ACPI */
|
||||
__builtin_wrmsr(0x5140000e, 0x00009c00, 0x0000f001);
|
||||
/* setup LBAR for PM Support */
|
||||
__builtin_wrmsr(0x5140000f, 0x00009d00, 0x0000f001);
|
||||
}
|
||||
|
||||
static void cs5536_setup_power_bottun(void)
|
||||
{
|
||||
/* not implemented yet */
|
||||
#if 0
|
||||
pwrBtn_setup:
|
||||
;
|
||||
; Power Button Setup
|
||||
;
|
||||
;mov eax, 0C0020000h ; 4 seconds + lock
|
||||
mov eax, 040020000h ; 4 seconds no lock
|
||||
mov dx, PMLogic_BASE + 40h
|
||||
out dx, eax
|
||||
|
||||
; setup GPIO24, it is the external signal for 5536 vsb_work_aux
|
||||
; which controls all voltage rails except Vstandby & Vmem.
|
||||
; We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
|
||||
; If GPIO24 is not enabled then soft-off will not work.
|
||||
mov dx, GPIOH_OUT_AUX1_SELECT
|
||||
mov eax, GPIOH_24_SET
|
||||
out dx, eax
|
||||
mov dx, GPIOH_OUTPUT_ENABLE
|
||||
out dx, eax
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cs5536_setup_gpio(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* setup GPIO pins 14/15 for SDA/SCL */
|
||||
val = (1<<14 | 1<<15);
|
||||
/* Output Enable */
|
||||
outl(0x3fffc000, 0x6100 + 0x04);
|
||||
//outl(val, 0x6100 + 0x04);
|
||||
/* Output AUX1 */
|
||||
outl(0x3fffc000, 0x6100 + 0x10);
|
||||
//outl(val, 0x6100 + 0x10);
|
||||
/* Input Enable */
|
||||
//outl(0x0f5af0a5, 0x6100 + 0x20);
|
||||
outl(0x3fffc000, 0x6100 + 0x20);
|
||||
//outl(val, 0x6100 + 0x20);
|
||||
/* Input AUX1 */
|
||||
//outl(0x3ffbc004, 0x6100 + 0x34);
|
||||
outl(0x3fffc000, 0x6100 + 0x34);
|
||||
//outl(val, 0x6100 + 0x34);
|
||||
}
|
||||
|
||||
static void cs5536_disable_internal_uart(void)
|
||||
{
|
||||
/* not implemented yet */
|
||||
#if 0
|
||||
; The UARTs default to enabled.
|
||||
; Disable and reset them and configure them later. (SIO init)
|
||||
mov ecx, MDD_UART1_CONF
|
||||
RDMSR
|
||||
mov eax, 1h ; reset
|
||||
WRMSR
|
||||
mov eax, 0h ; disabled
|
||||
WRMSR
|
||||
|
||||
mov ecx, MDD_UART2_CONF
|
||||
RDMSR
|
||||
mov eax, 1h ; reset
|
||||
WRMSR
|
||||
mov eax, 0h ; disabled
|
||||
WRMSR
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cs5536_setup_cis_mode(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
/* setup CPU interface serial to mode C on both sides */
|
||||
msr = __builtin_rdmsr(0x51000010);
|
||||
msr.lo &= ~0x18;
|
||||
msr.lo |= 0x10;
|
||||
__builtin_wrmsr(0x51000010, msr.lo, msr.hi);
|
||||
//Only do this if we are building for 5536
|
||||
__builtin_wrmsr(0x54002010, 0x00000002, 0x00000000);
|
||||
}
|
||||
|
||||
static void dummy(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int cs5536_early_setup(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
cs5536_setup_extmsr();
|
||||
|
||||
msr = rdmsr(GLCP_SYS_RSTPLL);
|
||||
if (msr.lo & (0x3f << 26)) {
|
||||
/* PLL is already set and we are reboot from PLL reset */
|
||||
print_debug("reboot from BIOS reset\n\r");
|
||||
return;
|
||||
}
|
||||
print_debug("Setup idsel\r\n");
|
||||
cs5536_setup_idsel();
|
||||
print_debug("Setup iobase\r\n");
|
||||
cs5536_usb_swapsif();
|
||||
cs5536_setup_iobase();
|
||||
print_debug("Setup gpio\r\n");
|
||||
cs5536_setup_gpio();
|
||||
print_debug("Setup cis_mode\r\n");
|
||||
cs5536_setup_cis_mode();
|
||||
print_debug("Setup smbus\r\n");
|
||||
cs5536_enable_smbus();
|
||||
dummy();
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include "cs5536_smbus.h"
|
||||
|
||||
#define SMBUS_IO_BASE 0x6000
|
||||
|
||||
/* initialization for SMBus Controller */
|
||||
static int cs5536_enable_smbus(void)
|
||||
{
|
||||
unsigned char val;
|
||||
|
||||
/* reset SMBUS controller */
|
||||
outb(0, SMBUS_IO_BASE + SMB_CTRL2);
|
||||
|
||||
/* Set SCL freq and enable SMB controller */
|
||||
val = inb(SMBUS_IO_BASE + SMB_CTRL2);
|
||||
val |= ((0x20 << 1) | SMB_CTRL2_ENABLE);
|
||||
outb(val, SMBUS_IO_BASE + SMB_CTRL2);
|
||||
|
||||
/* Setup SMBus host controller address to 0xEF */
|
||||
val = inb(SMBUS_IO_BASE + SMB_ADD);
|
||||
val |= (0xEF | SMB_ADD_SAEN);
|
||||
outb(val, SMBUS_IO_BASE + SMB_ADD);
|
||||
}
|
||||
|
||||
static int smbus_read_byte(unsigned device, unsigned address)
|
||||
{
|
||||
return do_smbus_read_byte(SMBUS_IO_BASE, device, address-1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int smbus_recv_byte(unsigned device)
|
||||
{
|
||||
return do_smbus_recv_byte(SMBUS_IO_BASE, device);
|
||||
}
|
||||
|
||||
static int smbus_send_byte(unsigned device, unsigned char val)
|
||||
{
|
||||
return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
|
||||
}
|
||||
|
||||
|
||||
static int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
|
||||
{
|
||||
return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include "cs5535.h"
|
||||
|
||||
static void ide_init(struct device *dev)
|
||||
{
|
||||
printk_spew("cs5535_ide: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void ide_enable(struct device *dev)
|
||||
{
|
||||
printk_spew("cs5535_ide: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
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,
|
||||
.enable = ide_enable,
|
||||
};
|
||||
|
||||
static struct pci_driver ide_driver __pci_driver = {
|
||||
.ops = &ide_ops,
|
||||
.vendor = PCI_VENDOR_ID_NS,
|
||||
.device = PCI_DEVICE_ID_NS_CS5535_IDE,
|
||||
};
|
|
@ -0,0 +1,180 @@
|
|||
//#include <device/smbus_def.h>
|
||||
#define SMBUS_ERROR -1
|
||||
#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
|
||||
#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
|
||||
|
||||
#define SMB_SDA 0x00
|
||||
#define SMB_STS 0x01
|
||||
#define SMB_CTRL_STS 0x02
|
||||
#define SMB_CTRL1 0x03
|
||||
#define SMB_ADD 0x04
|
||||
#define SMB_CTRL2 0x05
|
||||
#define SMB_CTRL3 0x06
|
||||
|
||||
#define SMB_STS_SLVSTP (0x01 << 7)
|
||||
#define SMB_STS_SDAST (0x01 << 6)
|
||||
#define SMB_STS_BER (0x01 << 5)
|
||||
#define SMB_STS_NEGACK (0x01 << 4)
|
||||
#define SMB_STS_STASTR (0x01 << 3)
|
||||
#define SMB_STS_NMATCH (0x01 << 2)
|
||||
#define SMB_STS_MASTER (0x01 << 1)
|
||||
#define SMB_STS_XMIT (0x01 << 0)
|
||||
|
||||
#define SMB_CSTS_TGSCL (0x01 << 5)
|
||||
#define SMB_CSTS_TSDA (0x01 << 4)
|
||||
#define SMB_CSTS_GCMTCH (0x01 << 3)
|
||||
#define SMB_CSTS_MATCH (0x01 << 2)
|
||||
#define SMB_CSTS_BB (0x01 << 1)
|
||||
#define SMB_CSTS_BUSY (0x01 << 0)
|
||||
|
||||
#define SMB_CTRL1_STASTRE (0x01 << 7)
|
||||
#define SMB_CTRL1_NMINTE (0x01 << 6)
|
||||
#define SMB_CTRL1_GCMEN (0x01 << 5)
|
||||
#define SMB_CTRL1_ACK (0x01 << 4)
|
||||
#define SMB_CTRL1_RSVD (0x01 << 3)
|
||||
#define SMB_CTRL1_INTEN (0x01 << 2)
|
||||
#define SMB_CTRL1_STOP (0x01 << 1)
|
||||
#define SMB_CTRL1_START (0x01 << 0)
|
||||
|
||||
#define SMB_ADD_SAEN (0x01 << 7)
|
||||
|
||||
#define SMB_CTRL2_ENABLE 0x01
|
||||
|
||||
#define SMBUS_TIMEOUT (100*1000*10)
|
||||
#define SMBUS_STATUS_MASK 0xfbff
|
||||
|
||||
#define SMBUS_IO_BASE 0x6000
|
||||
|
||||
static void smbus_delay(void)
|
||||
{
|
||||
outb(0x80, 0x80);
|
||||
}
|
||||
|
||||
/* generate a smbus start condition */
|
||||
static int smbus_start_condition(unsigned smbus_io_base)
|
||||
{
|
||||
unsigned char val;
|
||||
unsigned long loops;
|
||||
loops = SMBUS_TIMEOUT;
|
||||
|
||||
/* issue a START condition */
|
||||
val = inb(smbus_io_base + SMB_CTRL1);
|
||||
outb(val | SMB_CTRL1_START, smbus_io_base + SMB_CTRL1);
|
||||
|
||||
/* check for bus conflict */
|
||||
val = inb(smbus_io_base + SMB_STS);
|
||||
if ((val & SMB_STS_BER) != 0)
|
||||
return SMBUS_ERROR;
|
||||
|
||||
/* check for SDA status */
|
||||
do {
|
||||
smbus_delay();
|
||||
val = inw(smbus_io_base + SMB_STS);
|
||||
if ((val & SMB_STS_SDAST) != 0) {
|
||||
break;
|
||||
}
|
||||
} while(--loops);
|
||||
return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
|
||||
}
|
||||
|
||||
static int smbus_check_stop_condition(unsigned smbus_io_base)
|
||||
{
|
||||
unsigned char val;
|
||||
unsigned long loops;
|
||||
loops = SMBUS_TIMEOUT;
|
||||
/* check for SDA status */
|
||||
do {
|
||||
smbus_delay();
|
||||
val = inw(smbus_io_base + SMB_CTRL1);
|
||||
if ((val & SMB_CTRL1_STOP) == 0) {
|
||||
break;
|
||||
}
|
||||
} while(--loops);
|
||||
return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
|
||||
}
|
||||
|
||||
static int smbus_stop_condition(unsigned smbus_io_base)
|
||||
{
|
||||
unsigned char val;
|
||||
val = inb(smbus_io_base + SMB_CTRL1);
|
||||
outb(SMB_CTRL1_STOP, smbus_io_base + SMB_CTRL1);
|
||||
}
|
||||
|
||||
static int smbus_send_slave_address(unsigned smbus_io_base, unsigned char device)
|
||||
{
|
||||
unsigned char val;
|
||||
unsigned long loops;
|
||||
loops = SMBUS_TIMEOUT;
|
||||
|
||||
/* send the slave address */
|
||||
outb(device, smbus_io_base + SMB_SDA);
|
||||
|
||||
/* check for bus conflict and NACK */
|
||||
val = inb(smbus_io_base + SMB_STS);
|
||||
if (((val & SMB_STS_BER) != 0) ||
|
||||
((val & SMB_STS_NEGACK) != 0))
|
||||
return SMBUS_ERROR;
|
||||
|
||||
/* check for SDA status */
|
||||
do {
|
||||
smbus_delay();
|
||||
val = inw(smbus_io_base + SMB_STS);
|
||||
if ((val & SMB_STS_SDAST) != 0) {
|
||||
break;
|
||||
}
|
||||
} while(--loops);
|
||||
return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
|
||||
}
|
||||
|
||||
static int smbus_send_command(unsigned smbus_io_base, unsigned char command)
|
||||
{
|
||||
unsigned char val;
|
||||
unsigned long loops;
|
||||
loops = SMBUS_TIMEOUT;
|
||||
|
||||
/* send the command */
|
||||
outb(command, smbus_io_base + SMB_SDA);
|
||||
|
||||
/* check for bus conflict and NACK */
|
||||
val = inb(smbus_io_base + SMB_STS);
|
||||
if (((val & SMB_STS_BER) != 0) ||
|
||||
((val & SMB_STS_NEGACK) != 0))
|
||||
return SMBUS_ERROR;
|
||||
|
||||
/* check for SDA status */
|
||||
do {
|
||||
smbus_delay();
|
||||
val = inw(smbus_io_base + SMB_STS);
|
||||
if ((val & SMB_STS_SDAST) != 0) {
|
||||
break;
|
||||
}
|
||||
} while(--loops);
|
||||
return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
|
||||
}
|
||||
|
||||
static unsigned char do_smbus_read_byte(unsigned smbus_io_base, unsigned char device, unsigned char address)
|
||||
{
|
||||
unsigned char val, val1;
|
||||
|
||||
smbus_check_stop_condition(smbus_io_base);
|
||||
|
||||
smbus_start_condition(smbus_io_base);
|
||||
|
||||
smbus_send_slave_address(smbus_io_base, device);
|
||||
|
||||
smbus_send_command(smbus_io_base, address);
|
||||
|
||||
smbus_start_condition(smbus_io_base);
|
||||
|
||||
smbus_send_slave_address(smbus_io_base, device | 0x01);
|
||||
|
||||
/* send NACK to slave */
|
||||
val = inb(smbus_io_base + SMB_CTRL1);
|
||||
outb(val | SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
|
||||
|
||||
val = inb(smbus_io_base + SMB_SDA);
|
||||
|
||||
//smbus_stop_condition(smbus_io_base);
|
||||
|
||||
return val;
|
||||
}
|
Loading…
Reference in New Issue