blob: 2b8ae28b463e841cf380765c735e802b48bbee55 [file] [log] [blame]
Duncan Laurie645b3762013-02-12 14:00:47 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2013 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
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.
15 *
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
19 */
20
21#include <console/console.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include "pch.h"
26#include <usbdebug.h>
27#include <arch/io.h>
28
29static void usb_xhci_init(struct device *dev)
30{
31 u32 reg32;
32
33 printk(BIOS_DEBUG, "XHCI: Setting up controller.. ");
34
35 /* lock overcurrent map */
36 reg32 = pci_read_config32(dev, 0x44);
37 reg32 |= 1;
38 pci_write_config32(dev, 0x44, reg32);
39
40 /* Enable clock gating */
41 reg32 = pci_read_config32(dev, 0x40);
42 reg32 &= ~((1 << 20) | (1 << 21));
43 reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
44 reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
45 reg32 |= (1 << 31); /* lock */
46 pci_write_config32(dev, 0x40, reg32);
47
48 printk(BIOS_DEBUG, "done.\n");
49}
50
51static void xhci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
52{
53 if (!vendor || !device) {
54 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
55 pci_read_config32(dev, PCI_VENDOR_ID));
56 } else {
57 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
58 ((device & 0xffff) << 16) | (vendor & 0xffff));
59 }
60}
61
62static struct pci_operations xhci_pci_ops = {
63 .set_subsystem = xhci_set_subsystem,
64};
65
66static struct device_operations usb_xhci_ops = {
67 .read_resources = pci_dev_read_resources,
68 .set_resources = pci_dev_set_resources,
69 .enable_resources = pci_dev_enable_resources,
70 .init = usb_xhci_init,
71 .scan_bus = 0,
72 .ops_pci = &xhci_pci_ops,
73};
74
75static const unsigned short pci_device_ids[] = { 0x1e31, 0 };
76
77static const struct pci_driver pch_usb_xhci __pci_driver = {
78 .ops = &usb_xhci_ops,
79 .vendor = PCI_VENDOR_ID_INTEL,
80 .devices = pci_device_ids,
81};