2005-07-06 19:13:46 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2004 Tyan Computer
|
|
|
|
* by yhlu@tyan.com
|
|
|
|
*/
|
|
|
|
#include <console/console.h>
|
|
|
|
#include <device/device.h>
|
|
|
|
#include <device/pci.h>
|
|
|
|
#include <device/pci_ids.h>
|
|
|
|
#include <device/pci_ops.h>
|
|
|
|
#include "ck804.h"
|
|
|
|
|
2007-02-02 23:40:10 +01:00
|
|
|
static void usb1_init(struct device *dev) {
|
|
|
|
struct southbridge_nvidia_ck804_config const * conf=dev->chip_info;
|
|
|
|
if (conf->usb1_hc_reset) {
|
|
|
|
//Somehow the warm reset does not really resets the USB controller.
|
|
|
|
//Later, during boot, when the Bus Master bit is set, the USB
|
|
|
|
//controller trashes the memory, causing weird misbehavior.
|
|
|
|
//Was detected on Sun Ultra40, where mptable was damaged.
|
|
|
|
uint32_t bar0=pci_read_config32(dev,0x10);
|
|
|
|
uint32_t* regs=(uint32_t*)(bar0&~0xfff);
|
|
|
|
regs[2]|=1; //OHCI USB HCCommandStatus Register, HostControllerReset bit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-06 19:13:46 +02:00
|
|
|
static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
2007-02-02 23:40:10 +01:00
|
|
|
{
|
|
|
|
pci_write_config32(dev, 0x40,
|
2005-07-06 19:13:46 +02:00
|
|
|
((device & 0xffff) << 16) | (vendor & 0xffff));
|
|
|
|
}
|
|
|
|
static struct pci_operations lops_pci = {
|
|
|
|
.set_subsystem = lpci_set_subsystem,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct device_operations usb_ops = {
|
|
|
|
.read_resources = pci_dev_read_resources,
|
|
|
|
.set_resources = pci_dev_set_resources,
|
|
|
|
.enable_resources = pci_dev_enable_resources,
|
2007-02-02 23:40:10 +01:00
|
|
|
.init = usb1_init,
|
2005-07-06 19:13:46 +02:00
|
|
|
// .enable = ck804_enable,
|
|
|
|
.scan_bus = 0,
|
|
|
|
.ops_pci = &lops_pci,
|
|
|
|
};
|
|
|
|
|
2007-10-24 11:08:58 +02:00
|
|
|
static const struct pci_driver usb_driver __pci_driver = {
|
2005-07-06 19:13:46 +02:00
|
|
|
.ops = &usb_ops,
|
|
|
|
.vendor = PCI_VENDOR_ID_NVIDIA,
|
|
|
|
.device = PCI_DEVICE_ID_NVIDIA_CK804_USB,
|
|
|
|
};
|
|
|
|
|