6e8d9e5dd07b5853ea7f6074cd4191800ddcccf7
[coreboot.git] / src / southbridge / via / vt8237r / usb.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
5  * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
6  *
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.
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 "vt8237r.h"
26
27 #if CONFIG_EPIA_VT8237R_INIT
28 u32 usb_io_addr[4] = {0xcc00, 0xd000, 0xd400, 0xd800};
29 #endif
30
31 static void usb_i_init(struct device *dev)
32 {
33 #if CONFIG_EPIA_VT8237R_INIT
34         u8 reg8;
35
36         printk(BIOS_DEBUG, "Entering %s\n", __func__);
37
38         reg8 = pci_read_config8(dev, 0x04);
39
40         printk(BIOS_SPEW, "%s Read %02X from PCI Command Reg\n", dev_path(dev), reg8);
41
42         reg8 = reg8 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
43         pci_write_config8(dev, 0x04, reg8);
44
45         printk(BIOS_SPEW, "%s Wrote %02X to PCI Command Reg\n", dev_path(dev), reg8);
46
47         /* Set Cache Line Size and Latency Timer */
48         pci_write_config8(dev, 0x0c, 0x08);
49         pci_write_config8(dev, 0x0d, 0x20);
50
51         /* Enable Sub Device ID Back Door and set Generic */
52         reg8 = pci_read_config8(dev, 0x42);
53         reg8 |= 0x10;
54         pci_write_config8(dev, 0x42, reg8);
55         pci_write_config16(dev, 0x2e, 0xAA07);
56         reg8 &= ~0x10;
57         pci_write_config8(dev, 0x42, reg8);
58
59
60         pci_write_config8(dev, 0x41, 0x12);
61
62         pci_write_config8(dev, 0x49, 0x0B);
63
64         /* Clear PCI Status */
65         pci_write_config16(dev, 0x06, 0x7A10);
66 #endif
67         return;
68 }
69
70 static void vt8237_usb_i_read_resources(struct device *dev)
71 {
72 #if CONFIG_EPIA_VT8237R_INIT
73         struct resource *res;
74         u8 function = (u8) dev->path.pci.devfn & 0x7;
75
76         printk(BIOS_SPEW, "VT8237R Fixing USB 1.1 fn %d I/O resource = 0x%04X\n", function, usb_io_addr[function]);
77
78         /* Fix the I/O Resources of the USB1.1 Interfaces */
79         /* Auto PCI probe seems to size the resources     */
80         /* Incorrectly                                    */
81         res = new_resource(dev, PCI_BASE_ADDRESS_4);
82         res->base = usb_io_addr[function];
83         res->size = 256;
84         res->limit = 0xffffUL;
85         res->align = 10;
86         res->gran = 8;
87         res->flags = IORESOURCE_IO | IORESOURCE_FIXED |
88                                 IORESOURCE_ASSIGNED;
89 #else
90         pci_dev_read_resources(dev);
91 #endif
92         return;
93 }
94
95 static void usb_ii_init(struct device *dev)
96 {
97 #if CONFIG_EPIA_VT8237R_INIT
98         u8 reg8;
99
100         printk(BIOS_DEBUG, "Entering %s\n", __func__);
101
102         /* Set memory Write and Invalidate */
103         reg8 = pci_read_config8(dev, 0x04);
104         reg8 |= 0x10;
105         pci_write_config8(dev, 0x04, reg8);
106
107         /* Set Cache line Size and Latency Timer */
108         pci_write_config8(dev, 0x0c, 0x08);
109         pci_write_config8(dev, 0x0d, 0x20);
110
111         /* Clear PCI Status */
112         pci_write_config16(dev, 0x06, 0x7A10);
113 #endif
114
115 }
116
117 static void vt8237_usb_ii_read_resources(struct device *dev)
118 {
119 #if CONFIG_EPIA_VT8237R_INIT
120         struct resource *res;
121
122         /* Fix the I/O Resources of the USB2.0 Interface */
123         res = new_resource(dev, PCI_BASE_ADDRESS_0);
124         res->base = 0xF6000000ULL;
125         res->size = 256;
126         res->align = 12;
127         res->gran = 8;
128         res->limit = res->base + res->size - 1;
129         res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
130                                 IORESOURCE_ASSIGNED;
131 #else
132         pci_dev_read_resources(dev);
133 #endif
134         return;
135 }
136
137 static const struct device_operations usb_i_ops = {
138         .read_resources         = vt8237_usb_i_read_resources,
139         .set_resources          = pci_dev_set_resources,
140         .enable_resources       = pci_dev_enable_resources,
141         .init                           = usb_i_init,
142         .enable                         = 0,
143         .ops_pci                        = 0,
144 };
145
146 static const struct device_operations usb_ii_ops = {
147         .read_resources         = vt8237_usb_ii_read_resources,
148         .set_resources          = pci_dev_set_resources,
149         .enable_resources       = pci_dev_enable_resources,
150         .init                           = usb_ii_init,
151         .enable                         = 0,
152         .ops_pci                        = 0,
153 };
154
155 static const struct pci_driver vt8237r_driver_usbii __pci_driver = {
156         .ops    = &usb_ii_ops,
157         .vendor = PCI_VENDOR_ID_VIA,
158         .device = PCI_DEVICE_ID_VIA_VT8237R_EHCI,
159 };
160
161 static const struct pci_driver vt8237r_driver_usbi __pci_driver = {
162         .ops    = &usb_i_ops,
163         .vendor = PCI_VENDOR_ID_VIA,
164         .device = PCI_DEVICE_ID_VIA_VT8237R_UHCI,
165 };