blob: 464747d93fc79d78359a0bc8845931640d7aad47 [file] [log] [blame]
Zheng Baod0985752011-01-20 04:45:48 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Zheng Baod0985752011-01-20 04:45:48 +000014 */
15
16#include <console/console.h>
17#include <device/device.h>
18#include <device/pci.h>
19#include <device/pci_ids.h>
20#include <device/pci_ops.h>
Kyösti Mälkkie2227a22014-02-05 13:02:55 +020021#include <device/pci_ehci.h>
Zheng Baod0985752011-01-20 04:45:48 +000022#include <arch/io.h>
23#include "sb800.h"
24
25static struct pci_operations lops_pci = {
26 .set_subsystem = pci_dev_set_subsystem,
27};
28
29static void usb_init(struct device *dev)
30{
31 u8 byte;
32 u16 word;
33
34 /* 7.1 Enable OHCI0-4 and EHCI Controllers */
35 /* pmio 0xEF; */
36
37 /* RPR 7.2 USB S4/S5 Wake-up or PHY Power-down Support */
38 byte = pm_ioread(0xF0);
39 byte |= 1 << 0; /* A12, USB Wake from S5 not supported on the platform */
40 pm_iowrite(0xF0, byte);
41
42 /* RPR 7.4 Enable the USB controller to get reset by any software that generate a PCIRst# condition */
43 byte = pm_ioread(0xF0);
44 byte |= (1 << 2);
45 byte |= 3 << 8; /* rpr 7.5 */
46 pm_iowrite(0xF0, byte);
47
48 /* RPR 7.9 Disable OHCI MSI Capability. */
49 word = pci_read_config16(dev, 0x40);
50 word |= (0x1 << 8);
51 pci_write_config16(dev, 0x40, word);
52}
53
54static void usb_init2(struct device *dev)
55{
56 u32 dword;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080057 void *usb2_bar0;
Zheng Baod0985752011-01-20 04:45:48 +000058 device_t sm_dev;
59
60 sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
61 //rev = get_sb800_revision(sm_dev);
62
63 /* dword = pci_read_config32(dev, 0xf8); */
64 /* dword |= 40; */
65 /* pci_write_config32(dev, 0xf8, dword); */
66
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080067 usb2_bar0 = (void *)(pci_read_config32(dev, 0x10) & ~0xFF);
68 printk(BIOS_INFO, "usb2_bar0=0x%p\n", usb2_bar0);
Zheng Baod0985752011-01-20 04:45:48 +000069
Martin Rothdcf253c2014-12-16 20:51:31 -070070 /* RPR7.3 Enables the USB PHY auto calibration resister to match 45ohm resistance */
Zheng Baod0985752011-01-20 04:45:48 +000071 dword = 0x00020F00;
72 write32(usb2_bar0 + 0xC0, dword);
73
74 /* RPR7.8 Sets In/OUT FIFO threshold for best performance */
75 dword = 0x00400040;
76 write32(usb2_bar0 + 0xA4, dword);
77
78 /* RPR7.10 Disable EHCI MSI support */
79 dword = pci_read_config32(dev, 0x50);
80 dword |= (1 << 6);
81 pci_write_config32(dev, 0x50, dword);
82
83 /* RPR7.12 EHCI Async Park Mode */
84 dword = pci_read_config32(dev, 0x50);
85 dword &= ~(0xF << 8);
86 dword &= ~(0xF << 12);
87 dword |= 1 << 8;
88 dword |= 2 << 12;
89 pci_write_config32(dev, 0x50, dword);
90
91 /* RPR 6.12 EHCI Advance PHY Power Savings */
92 /* RPR says it is just for A12. CIMM sets it when it is above A11. */
93 /* But it makes the linux crash, so we skip it */
94 #if 0
95 dword = pci_read_config32(dev, 0x50);
96 dword |= 1 << 31;
97 pci_write_config32(dev, 0x50, dword);
98 #endif
99
100 /* Each step below causes the linux crashes. Leave them here
101 * for future debugging. */
102#if 0
103 u8 byte;
104 u16 word;
105
106
107 /* RPR6.17 Disable the EHCI Dynamic Power Saving feature */
108 word = read32(usb2_bar0 + 0xBC);
109 word &= ~(1 << 12);
110 write16(usb2_bar0 + 0xBC, word);
111
112 /* RPR6.19 USB Controller DMA Read Delay Tolerant. */
113 if (rev >= REV_SB800_A14) {
114 byte = pci_read_config8(dev, 0x50);
115 byte |= (1 << 7);
116 pci_write_config8(dev, 0x50, byte);
117 }
118
119 /* RPR6.20 Async Park Mode. */
120 /* RPR recommends not to set these bits. */
121 #if 0
122 dword = pci_read_config32(dev, 0x50);
123 dword |= 1 << 23;
124 if (rev >= REV_SB800_A14) {
125 dword &= ~(1 << 2);
126 }
127 pci_write_config32(dev, 0x50, dword);
128 #endif
129
130 /* RPR6.22 Advance Async Enhancement */
131 /* RPR6.23 USB Periodic Cache Setting */
132 dword = pci_read_config32(dev, 0x50);
133 if (rev == REV_SB800_A12) {
134 dword |= 1 << 28; /* 6.22 */
135 dword |= 1 << 27; /* 6.23 */
136 } else if (rev >= REV_SB800_A14) {
137 dword |= 1 << 3;
138 dword &= ~(1 << 28); /* 6.22 */
139 dword |= 1 << 8;
140 dword &= ~(1 << 27); /* 6.23 */
141 }
142 printk(BIOS_DEBUG, "rpr 6.23, final dword=%x\n", dword);
143#endif
144}
145
Zheng Baod0985752011-01-20 04:45:48 +0000146static struct device_operations usb_ops = {
Kyösti Mälkkifb387df2013-06-07 22:16:52 +0300147 .read_resources = pci_ehci_read_resources,
148 .set_resources = pci_dev_set_resources,
Zheng Baod0985752011-01-20 04:45:48 +0000149 .enable_resources = pci_dev_enable_resources,
150 .init = usb_init,
151 .scan_bus = 0,
152 .ops_pci = &lops_pci,
153};
154
155static const struct pci_driver usb_0_driver __pci_driver = {
156 .ops = &usb_ops,
157 .vendor = PCI_VENDOR_ID_ATI,
158 .device = PCI_DEVICE_ID_ATI_SB800_USB_18_0,
159};
160static const struct pci_driver usb_1_driver __pci_driver = {
161 .ops = &usb_ops,
162 .vendor = PCI_VENDOR_ID_ATI,
163 .device = PCI_DEVICE_ID_ATI_SB800_USB_18_2,
164};
165
166/* the pci id of usb ctrl 0 and 1 are the same. */
167/*
168 * static const struct pci_driver usb_3_driver __pci_driver = {
169 * .ops = &usb_ops,
170 * .vendor = PCI_VENDOR_ID_ATI,
171 * .device = PCI_DEVICE_ID_ATI_SB800_USB_19_0,
172 * };
173 * static const struct pci_driver usb_4_driver __pci_driver = {
174 * .ops = &usb_ops,
175 * .vendor = PCI_VENDOR_ID_ATI,
176 * .device = PCI_DEVICE_ID_ATI_SB800_USB_19_1,
177 * };
178 */
179
180static const struct pci_driver usb_4_driver __pci_driver = {
181 .ops = &usb_ops,
182 .vendor = PCI_VENDOR_ID_ATI,
183 .device = PCI_DEVICE_ID_ATI_SB800_USB_20_5,
184};
185
186static struct device_operations usb_ops2 = {
Kyösti Mälkkifb387df2013-06-07 22:16:52 +0300187 .read_resources = pci_ehci_read_resources,
188 .set_resources = pci_dev_set_resources,
Zheng Baod0985752011-01-20 04:45:48 +0000189 .enable_resources = pci_dev_enable_resources,
190 .init = usb_init2,
191 .scan_bus = 0,
192 .ops_pci = &lops_pci,
193};
194
195static const struct pci_driver usb_5_driver __pci_driver = {
196 .ops = &usb_ops2,
197 .vendor = PCI_VENDOR_ID_ATI,
198 .device = PCI_DEVICE_ID_ATI_SB800_USB_18_2,
199};
200/*
201 * static const struct pci_driver usb_5_driver __pci_driver = {
202 * .ops = &usb_ops2,
203 * .vendor = PCI_VENDOR_ID_ATI,
204 * .device = PCI_DEVICE_ID_ATI_SB800_USB_19_2,
205 * };
206 */