blob: a7ada4b8f1024a362c5bddd9e1a93d6ad01f9b2c [file] [log] [blame]
Patrick Georgibe61a172010-12-18 07:48:43 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2010 coresystems GmbH
5 * Copyright (C) 2009-2010 iWave Systems
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
Uwe Hermann405721d2010-12-18 13:22:37 +00009 * published by the Free Software Foundation; version 2 of the License.
Patrick Georgibe61a172010-12-18 07:48:43 +000010 *
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.
Patrick Georgibe61a172010-12-18 07:48:43 +000015 */
16
17#include <console/console.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
21
22static void usb_init(struct device *dev)
23{
24 u32 reg32;
25
Uwe Hermann405721d2010-12-18 13:22:37 +000026 /* USB Specification says the device must be Bus Master. */
Patrick Georgibe61a172010-12-18 07:48:43 +000027 printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
28
29 reg32 = pci_read_config32(dev, PCI_COMMAND);
30 pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
Uwe Hermann405721d2010-12-18 13:22:37 +000031 /* Disable clock gating. */
Patrick Georgibe61a172010-12-18 07:48:43 +000032 reg32 = pci_read_config32(dev, 0xFC);
33 reg32 |= (1 << 2);
34 pci_write_config32(dev, 0xFC, reg32);
Stefan Reinauer4bab6e72016-05-03 15:53:33 -070035 pci_write_config8(dev, 0xF8, 0x86);
36 pci_write_config8(dev, 0xF9, 0x0F);
37 pci_write_config8(dev, 0xFA, 0x06);
Patrick Georgibe61a172010-12-18 07:48:43 +000038 reg32 = pci_read_config32(dev, 0x4);
Stefan Reinauer4bab6e72016-05-03 15:53:33 -070039 printk(BIOS_DEBUG, "PCI_COMMAND %x.\n", reg32);
Patrick Georgibe61a172010-12-18 07:48:43 +000040 reg32 = pci_read_config32(dev, 0x20);
Stefan Reinauer4bab6e72016-05-03 15:53:33 -070041 printk(BIOS_DEBUG, "PCI_BASE %x.\n", reg32);
Patrick Georgibe61a172010-12-18 07:48:43 +000042 reg32 = pci_read_config32(dev, 0xFC);
Stefan Reinauer4bab6e72016-05-03 15:53:33 -070043 printk(BIOS_DEBUG, "PCI_FD %x.\n", reg32);
Patrick Georgibe61a172010-12-18 07:48:43 +000044 printk(BIOS_DEBUG, "done.\n");
45}
46
47static void usb_set_subsystem(device_t dev, unsigned vendor, unsigned device)
48{
49 if (!vendor || !device) {
50 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
51 pci_read_config32(dev, PCI_VENDOR_ID));
52 } else {
53 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
54 ((device & 0xffff) << 16) | (vendor & 0xffff));
55 }
56}
57
58static struct pci_operations usb_pci_ops = {
Uwe Hermann405721d2010-12-18 13:22:37 +000059 .set_subsystem = usb_set_subsystem,
Patrick Georgibe61a172010-12-18 07:48:43 +000060};
61
62static struct device_operations usb_ops = {
63 .read_resources = pci_dev_read_resources,
64 .set_resources = pci_dev_set_resources,
65 .enable_resources = pci_dev_enable_resources,
66 .init = usb_init,
67 .scan_bus = 0,
68 .ops_pci = &usb_pci_ops,
69};
70
Patrick Georgibe61a172010-12-18 07:48:43 +000071static const struct pci_driver sch_usb0 __pci_driver = {
72 .ops = &usb_ops,
73 .vendor = PCI_VENDOR_ID_INTEL,
74 .device = 0x8114,
75};
Uwe Hermann405721d2010-12-18 13:22:37 +000076
Patrick Georgibe61a172010-12-18 07:48:43 +000077static const struct pci_driver sch_usb1 __pci_driver = {
78 .ops = &usb_ops,
79 .vendor = PCI_VENDOR_ID_INTEL,
80 .device = 0x8115,
81};
Uwe Hermann405721d2010-12-18 13:22:37 +000082
Patrick Georgibe61a172010-12-18 07:48:43 +000083static const struct pci_driver sch_usb2 __pci_driver = {
84 .ops = &usb_ops,
85 .vendor = PCI_VENDOR_ID_INTEL,
86 .device = 0x8116,
87};