2 * This file is part of the coreboot project.
4 * Copyright (C) 2005 AMD
5 * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <console/console.h>
22 #include <device/device.h>
23 #include <device/pci.h>
24 #include <device/pnp.h>
25 #include <device/pci_ids.h>
26 #include <device/pci_ops.h>
27 #include <pc80/mc146818rtc.h>
28 #include <pc80/isa-dma.h>
31 #include <device/smbus.h>
33 #include "bcm5785_smbus.h"
37 static void sb_init(device_t dev)
43 /* Set up NMI on errors */
44 byte = inb(0x70); // RTC70
47 get_option(&nmi_option, "nmi");
49 byte &= ~(1 << 7); /* set NMI */
51 byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
53 if( byte != byte_old) {
60 static void bcm5785_sb_read_resources(device_t dev)
64 /* Get the normal pci resources of this device */
65 pci_dev_read_resources(dev);
66 /* Get Resource for SMBUS */
67 pci_get_resource(dev, 0x90);
69 compact_resources(dev);
71 /* Add an extra subtractive resource for both memory and I/O */
72 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
73 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
75 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
76 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
80 static int lsmbus_recv_byte(device_t dev)
86 device = dev->path.i2c.device;
87 pbus = get_pbus_smbus(dev);
89 res = find_resource(pbus->dev, 0x90);
91 return do_smbus_recv_byte(res->base, device);
94 static int lsmbus_send_byte(device_t dev, uint8_t val)
100 device = dev->path.i2c.device;
101 pbus = get_pbus_smbus(dev);
103 res = find_resource(pbus->dev, 0x90);
105 return do_smbus_send_byte(res->base, device, val);
108 static int lsmbus_read_byte(device_t dev, uint8_t address)
111 struct resource *res;
114 device = dev->path.i2c.device;
115 pbus = get_pbus_smbus(dev);
117 res = find_resource(pbus->dev, 0x90);
119 return do_smbus_read_byte(res->base, device, address);
122 static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
125 struct resource *res;
128 device = dev->path.i2c.device;
129 pbus = get_pbus_smbus(dev);
131 res = find_resource(pbus->dev, 0x90);
133 return do_smbus_write_byte(res->base, device, address, val);
136 static struct smbus_bus_operations lops_smbus_bus = {
137 .recv_byte = lsmbus_recv_byte,
138 .send_byte = lsmbus_send_byte,
139 .read_byte = lsmbus_read_byte,
140 .write_byte = lsmbus_write_byte,
143 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
145 pci_write_config32(dev, 0x2c,
146 ((device & 0xffff) << 16) | (vendor & 0xffff));
149 static struct pci_operations lops_pci = {
150 .set_subsystem = lpci_set_subsystem,
153 static struct device_operations sb_ops = {
154 .read_resources = bcm5785_sb_read_resources,
155 .set_resources = pci_dev_set_resources,
156 .enable_resources = pci_dev_enable_resources,
158 .scan_bus = scan_static_bus,
159 // .enable = bcm5785_enable,
160 .ops_pci = &lops_pci,
161 .ops_smbus_bus = &lops_smbus_bus,
164 static const struct pci_driver sb_driver __pci_driver = {
166 .vendor = PCI_VENDOR_ID_SERVERWORKS,
167 .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN,