blob: c6484151adcee0d126ac2cab23053dc9411b5737 [file] [log] [blame]
Duncan Laurie3c9f1742013-11-01 13:34:00 -07001/*
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 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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <arch/acpi.h>
21#include <console/console.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <stdint.h>
26#include <reg_script.h>
27
28#include <baytrail/iomap.h>
29#include <baytrail/iosf.h>
30#include <baytrail/pci_devs.h>
31#include <baytrail/pmc.h>
32#include <baytrail/ramstage.h>
33#include <baytrail/ehci.h>
34
35#include "chip.h"
36
37const struct reg_script ehci_init_script[] = {
38 /* Enable S0 PLL shutdown
39 * D29:F0:7A[12,10,7,6,4,3,2,1]=11111111b */
40 REG_PCI_OR16(0x7a, 0x14de),
41 /* Enable SB local clock gating
42 * D29:F0:7C[14,3,2]=111b (14 set in clock gating step) */
43 REG_PCI_OR32(0x7c, 0x0000000c),
44 REG_PCI_OR32(0x8c, 0x00000001),
45 /* Enable dynamic clock gating 0x4001=0xCE */
46 REG_IOSF_RMW(IOSF_PORT_USBPHY, 0x4001, 0xFFFFFF00, 0xCE),
47 /* Magic RCBA register set sequence */
48 /* RCBA + 0x200=0x1 */
49 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x200, 0x00000001),
50 /* RCBA + 0x204=0x2 */
51 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x204, 0x00000002),
52 /* RCBA + 0x208=0x0 */
53 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x208, 0x00000000),
54 /* RCBA + 0x240[4,3,2,1,0]=00000b */
55 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x240, ~0x0000001f, 0),
56 /* RCBA + 0x318[9,8,6,5,4,3,2,1,0]=000000111b */
57 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x318, ~0x00000378, 0x00000007),
58 /* RCBA + 0x31c[3,2,1,0]=0011b */
59 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x31c, ~0x0000000c, 0x00000003),
60 REG_SCRIPT_END
61};
62
63const struct reg_script ehci_clock_gating_script[] = {
64 /* Enable SB local clock gating */
65 REG_PCI_OR32(0x7c, 0x00004000),
66 /* RCBA + 0x284=0xbe (step B0+) */
67 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x284, 0x000000be),
68 REG_SCRIPT_END
69};
70
71const struct reg_script ehci_disable_script[] = {
72 /* Clear Run/Stop Bit */
73 REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD, ~USB2CMD_RS, 0),
74 /* Wait for HC Halted */
75 REG_RES_POLL32(PCI_BASE_ADDRESS_0, USB2STS,
76 USB2STS_HCHALT, USB2STS_HCHALT, 10000),
77 /* Disable Interrupts */
78 REG_PCI_OR32(EHCI_CMD_STS, INTRDIS),
79 /* Disable Asynchronous and Periodic Scheduler */
80 REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD,
81 ~(USB2CMD_ASE | USB2CMD_PSE), 0),
82 /* Disable port wake */
83 REG_PCI_RMW32(EHCI_SBRN_FLA_PWC, ~(PORTWKIMP | PORTWKCAPMASK), 0),
84 /* Set Function Disable bit in RCBA */
85 REG_MMIO_OR32(RCBA_BASE_ADDRESS + RCBA_FUNC_DIS, RCBA_EHCI_DIS),
86 REG_SCRIPT_END
87};
88
89static void usb2_phy_init(device_t dev)
90{
91 struct soc_intel_baytrail_config *config = dev->chip_info;
92 struct reg_script usb2_phy_script[] = {
93 /* USB3PHYInit() */
94 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_COMPBG, 0x4700),
95 /* Per port phy settings, set in devicetree.cb */
96 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE0,
97 config->usb2_per_port_lane0),
98 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
99 USBPHY_PER_PORT_RCOMP_HS_PULLUP0,
100 config->usb2_per_port_rcomp_hs_pullup0),
101 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE1,
102 config->usb2_per_port_lane1),
103 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
104 USBPHY_PER_PORT_RCOMP_HS_PULLUP1,
105 config->usb2_per_port_rcomp_hs_pullup1),
106 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE2,
107 config->usb2_per_port_lane2),
108 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
109 USBPHY_PER_PORT_RCOMP_HS_PULLUP2,
110 config->usb2_per_port_rcomp_hs_pullup2),
111 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE3,
112 config->usb2_per_port_lane3),
113 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
114 USBPHY_PER_PORT_RCOMP_HS_PULLUP3,
115 config->usb2_per_port_rcomp_hs_pullup3),
116 REG_SCRIPT_END
117 };
118 reg_script_run(usb2_phy_script);
119}
120
121static void ehci_init(device_t dev)
122{
123 struct soc_intel_baytrail_config *config = dev->chip_info;
124 struct reg_script ehci_hc_reset[] = {
125 REG_SCRIPT_SET_DEV(dev),
126 REG_RES_OR16(PCI_BASE_ADDRESS_0, USB2CMD, USB2CMD_HCRESET),
127 REG_SCRIPT_END
128 };
129 struct reg_script ehci_hc_disable[] = {
130 REG_SCRIPT_SET_DEV(dev),
131 REG_SCRIPT_NEXT(ehci_disable_script),
132 REG_SCRIPT_END
133 };
134 struct reg_script ehci_hc_init[] = {
135 REG_SCRIPT_SET_DEV(dev),
136 /* Controller init */
137 REG_SCRIPT_NEXT(ehci_init_script),
138 /* Enable clock gating */
139 REG_SCRIPT_NEXT(ehci_clock_gating_script),
140 /*
141 * Disable ports if requested
142 */
143 /* Open per-port disable control override */
144 REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~0, UPRWC_WR_EN),
145 REG_PCI_WRITE8(EHCI_USB2PDO, config->usb2_port_disable_mask),
146 /* Close per-port disable control override */
147 REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~UPRWC_WR_EN, 0),
148 REG_SCRIPT_END
149 };
150
151 /* Don't reset controller in S3 resume path */
152 if (acpi_slp_type != 3)
153 reg_script_run(ehci_hc_reset);
154
155 /* Disable controller if ports are routed to XHCI */
156 if (config->usb_route_to_xhci) {
157 /* Disable controller */
158 reg_script_run(ehci_hc_disable);
159
160 /* Hide device with southcluster function */
161 dev->enabled = 0;
162 southcluster_enable_dev(dev);
163 } else {
164 /* Initialize EHCI controller */
165 reg_script_run(ehci_hc_init);
166 }
167
168 /* Setup USB2 PHY based on board config */
169 usb2_phy_init(dev);
170}
171
172static struct device_operations ehci_device_ops = {
173 .read_resources = pci_dev_read_resources,
174 .set_resources = pci_dev_set_resources,
175 .enable_resources = pci_dev_enable_resources,
176 .init = ehci_init,
177 .ops_pci = &soc_pci_ops,
178};
179
180static const struct pci_driver baytrail_ehci __pci_driver = {
181 .ops = &ehci_device_ops,
182 .vendor = PCI_VENDOR_ID_INTEL,
183 .device = EHCI_DEVID
184};