blob: ac27f4399cac656a8b09cba84a5f47c84de8ae96 [file] [log] [blame]
Jon Harrison9c2e7382009-08-18 15:12:13 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00005 * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
Jon Harrison9c2e7382009-08-18 15:12:13 +00006 *
7 * This program is free software; you can redistribute it and/or modify
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00008 * it under the terms of the GNU General Public License as published by
Jon Harrison9c2e7382009-08-18 15:12:13 +00009 * 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>
Florian Zumbiehl1b940fd2011-11-01 20:19:35 +010025#include "chip.h"
Jon Harrison9c2e7382009-08-18 15:12:13 +000026#include "vt8237r.h"
27
Myles Watsonec0ee642009-10-19 16:21:30 +000028#if CONFIG_EPIA_VT8237R_INIT
Jon Harrison9c2e7382009-08-18 15:12:13 +000029u32 usb_io_addr[4] = {0xcc00, 0xd000, 0xd400, 0xd800};
30#endif
31
32static void usb_i_init(struct device *dev)
33{
Myles Watsonec0ee642009-10-19 16:21:30 +000034#if CONFIG_EPIA_VT8237R_INIT
Jon Harrison9c2e7382009-08-18 15:12:13 +000035 u8 reg8;
36
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000037 printk(BIOS_DEBUG, "Entering %s\n", __func__);
Jon Harrison9c2e7382009-08-18 15:12:13 +000038
Jon Harrison9c2e7382009-08-18 15:12:13 +000039 reg8 = pci_read_config8(dev, 0x04);
40
Stefan Reinauer523ebd92010-04-14 18:59:42 +000041 printk(BIOS_SPEW, "%s Read %02X from PCI Command Reg\n", dev_path(dev), reg8);
42
Jon Harrison9c2e7382009-08-18 15:12:13 +000043 reg8 = reg8 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
44 pci_write_config8(dev, 0x04, reg8);
45
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000046 printk(BIOS_SPEW, "%s Wrote %02X to PCI Command Reg\n", dev_path(dev), reg8);
Jon Harrison9c2e7382009-08-18 15:12:13 +000047
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
71static void vt8237_usb_i_read_resources(struct device *dev)
72{
Myles Watsonec0ee642009-10-19 16:21:30 +000073#if CONFIG_EPIA_VT8237R_INIT
Jon Harrison9c2e7382009-08-18 15:12:13 +000074 struct resource *res;
75 u8 function = (u8) dev->path.pci.devfn & 0x7;
76
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000077 printk(BIOS_SPEW, "VT8237R Fixing USB 1.1 fn %d I/O resource = 0x%04X\n", function, usb_io_addr[function]);
Jon Harrison9c2e7382009-08-18 15:12:13 +000078
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
96static void usb_ii_init(struct device *dev)
97{
Florian Zumbiehl1b940fd2011-11-01 20:19:35 +010098 struct southbridge_via_vt8237r_config *cfg;
Myles Watsonec0ee642009-10-19 16:21:30 +000099#if CONFIG_EPIA_VT8237R_INIT
Jon Harrison9c2e7382009-08-18 15:12:13 +0000100 u8 reg8;
101
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000102 printk(BIOS_DEBUG, "Entering %s\n", __func__);
Jon Harrison9c2e7382009-08-18 15:12:13 +0000103
104 /* Set memory Write and Invalidate */
105 reg8 = pci_read_config8(dev, 0x04);
106 reg8 |= 0x10;
107 pci_write_config8(dev, 0x04, reg8);
108
109 /* Set Cache line Size and Latency Timer */
110 pci_write_config8(dev, 0x0c, 0x08);
111 pci_write_config8(dev, 0x0d, 0x20);
112
113 /* Clear PCI Status */
114 pci_write_config16(dev, 0x06, 0x7A10);
115#endif
116
Florian Zumbiehl1b940fd2011-11-01 20:19:35 +0100117 cfg = dev->chip_info;
118
119 if (cfg) {
120 if (cfg->usb2_termination_set) {
121 /* High Speed Port Pad Termination Resistor Fine Tune */
122 pci_write_config8(dev, 0x5a, cfg->usb2_termination_c |
123 (cfg->usb2_termination_d << 4));
124 pci_write_config8(dev, 0x5b, cfg->usb2_termination_a |
125 (cfg->usb2_termination_b << 4));
126 pci_write_config8(dev, 0x5d, cfg->usb2_termination_e |
127 (cfg->usb2_termination_f << 4));
128 pci_write_config8(dev, 0x5e, cfg->usb2_termination_g |
129 (cfg->usb2_termination_h << 4));
130 }
131
132 if (cfg->usb2_dpll_set) {
133 /* Delay DPLL Input Data Control */
134 pci_write_config8(dev, 0x5c,
135 (pci_read_config8(dev, 0x5c) & ~0x70) |
136 (cfg->usb2_dpll_delay << 4));
137 }
138 }
Jon Harrison9c2e7382009-08-18 15:12:13 +0000139}
140
141static void vt8237_usb_ii_read_resources(struct device *dev)
142{
Myles Watsonec0ee642009-10-19 16:21:30 +0000143#if CONFIG_EPIA_VT8237R_INIT
Jon Harrison9c2e7382009-08-18 15:12:13 +0000144 struct resource *res;
145
146 /* Fix the I/O Resources of the USB2.0 Interface */
147 res = new_resource(dev, PCI_BASE_ADDRESS_0);
148 res->base = 0xF6000000ULL;
149 res->size = 256;
150 res->align = 12;
151 res->gran = 8;
152 res->limit = res->base + res->size - 1;
153 res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
154 IORESOURCE_ASSIGNED;
155#else
156 pci_dev_read_resources(dev);
157#endif
158 return;
159}
160
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +0200161static void vt8237_set_subsystem(device_t dev, unsigned vendor, unsigned device)
162{
163 pci_write_config32(dev, 0x42, pci_read_config32(dev, 0x42) | 0x10);
164 pci_write_config16(dev, 0x2c, vendor);
165 pci_write_config16(dev, 0x2e, device);
166 pci_write_config32(dev, 0x42, pci_read_config32(dev, 0x42) & ~0x10);
167}
168
169static struct pci_operations lops_pci = {
170 .set_subsystem = vt8237_set_subsystem,
171};
172
Jon Harrison9c2e7382009-08-18 15:12:13 +0000173static const struct device_operations usb_i_ops = {
174 .read_resources = vt8237_usb_i_read_resources,
175 .set_resources = pci_dev_set_resources,
176 .enable_resources = pci_dev_enable_resources,
177 .init = usb_i_init,
178 .enable = 0,
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +0200179 .ops_pci = &lops_pci,
Jon Harrison9c2e7382009-08-18 15:12:13 +0000180};
181
182static const struct device_operations usb_ii_ops = {
183 .read_resources = vt8237_usb_ii_read_resources,
184 .set_resources = pci_dev_set_resources,
185 .enable_resources = pci_dev_enable_resources,
186 .init = usb_ii_init,
187 .enable = 0,
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +0200188 .ops_pci = &lops_pci,
Jon Harrison9c2e7382009-08-18 15:12:13 +0000189};
190
191static const struct pci_driver vt8237r_driver_usbii __pci_driver = {
192 .ops = &usb_ii_ops,
193 .vendor = PCI_VENDOR_ID_VIA,
194 .device = PCI_DEVICE_ID_VIA_VT8237R_EHCI,
195};
196
197static const struct pci_driver vt8237r_driver_usbi __pci_driver = {
198 .ops = &usb_i_ops,
199 .vendor = PCI_VENDOR_ID_VIA,
200 .device = PCI_DEVICE_ID_VIA_VT8237R_UHCI,
201};