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