soc: Remove copyright notices
[coreboot.git] / src / soc / intel / baytrail / ehci.c
blob6b759f2f901e50e1afed71976f46f3f4e6318239
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <arch/acpi.h>
16 #include <device/device.h>
17 #include <device/pci.h>
18 #include <device/pci_ids.h>
19 #include <stdint.h>
20 #include <reg_script.h>
22 #include <soc/iomap.h>
23 #include <soc/iosf.h>
24 #include <soc/pci_devs.h>
25 #include <soc/pmc.h>
26 #include <soc/ramstage.h>
27 #include <soc/ehci.h>
29 #include "chip.h"
31 static const struct reg_script ehci_init_script[] = {
32 /* Enable S0 PLL shutdown
33 * D29:F0:7A[12,10,7,6,4,3,2,1]=11111111b */
34 REG_PCI_OR16(0x7a, 0x14de),
35 /* Enable SB local clock gating
36 * D29:F0:7C[14,3,2]=111b (14 set in clock gating step) */
37 REG_PCI_OR32(0x7c, 0x0000000c),
38 REG_PCI_OR32(0x8c, 0x00000001),
39 /* Enable dynamic clock gating 0x4001=0xCE */
40 REG_IOSF_RMW(IOSF_PORT_USBPHY, 0x4001, 0xFFFFFF00, 0xCE),
41 /* Magic RCBA register set sequence */
42 /* RCBA + 0x200=0x1 */
43 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x200, 0x00000001),
44 /* RCBA + 0x204=0x2 */
45 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x204, 0x00000002),
46 /* RCBA + 0x208=0x0 */
47 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x208, 0x00000000),
48 /* RCBA + 0x240[4,3,2,1,0]=00000b */
49 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x240, ~0x0000001f, 0),
50 /* RCBA + 0x318[9,8,6,5,4,3,2,1,0]=000000111b */
51 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x318, ~0x00000378, 0x00000007),
52 /* RCBA + 0x31c[3,2,1,0]=0011b */
53 REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x31c, ~0x0000000c, 0x00000003),
54 REG_SCRIPT_END
57 static const struct reg_script ehci_clock_gating_script[] = {
58 /* Enable SB local clock gating */
59 REG_PCI_OR32(0x7c, 0x00004000),
60 /* RCBA + 0x284=0xbe (step B0+) */
61 REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x284, 0x000000be),
62 REG_SCRIPT_END
65 static const struct reg_script ehci_disable_script[] = {
66 /* Clear Run/Stop Bit */
67 REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD, ~USB2CMD_RS, 0),
68 /* Wait for HC Halted */
69 REG_RES_POLL32(PCI_BASE_ADDRESS_0, USB2STS,
70 USB2STS_HCHALT, USB2STS_HCHALT, 10000),
71 /* Disable Interrupts */
72 REG_PCI_OR32(EHCI_CMD_STS, INTRDIS),
73 /* Disable Asynchronous and Periodic Scheduler */
74 REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD,
75 ~(USB2CMD_ASE | USB2CMD_PSE), 0),
76 /* Disable port wake */
77 REG_PCI_RMW32(EHCI_SBRN_FLA_PWC, ~(PORTWKIMP | PORTWKCAPMASK), 0),
78 /* Set Function Disable bit in RCBA */
79 REG_MMIO_OR32(RCBA_BASE_ADDRESS + RCBA_FUNC_DIS, RCBA_EHCI_DIS),
80 REG_SCRIPT_END
83 static const struct reg_script ehci_hc_reset[] = {
84 REG_RES_OR16(PCI_BASE_ADDRESS_0, USB2CMD, USB2CMD_HCRESET),
85 REG_SCRIPT_END
88 static void usb2_phy_init(struct device *dev)
90 struct soc_intel_baytrail_config *config = config_of(dev);
91 u32 usb2_comp_bg = (config->usb2_comp_bg == 0 ?
92 0x4700 : config->usb2_comp_bg);
93 struct reg_script usb2_phy_script[] = {
94 /* USB3PHYInit() */
95 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_COMPBG,
96 usb2_comp_bg),
97 /* Per port phy settings, set in devicetree.cb */
98 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE0,
99 config->usb2_per_port_lane0),
100 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
101 USBPHY_PER_PORT_RCOMP_HS_PULLUP0,
102 config->usb2_per_port_rcomp_hs_pullup0),
103 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE1,
104 config->usb2_per_port_lane1),
105 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
106 USBPHY_PER_PORT_RCOMP_HS_PULLUP1,
107 config->usb2_per_port_rcomp_hs_pullup1),
108 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE2,
109 config->usb2_per_port_lane2),
110 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
111 USBPHY_PER_PORT_RCOMP_HS_PULLUP2,
112 config->usb2_per_port_rcomp_hs_pullup2),
113 REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE3,
114 config->usb2_per_port_lane3),
115 REG_IOSF_WRITE(IOSF_PORT_USBPHY,
116 USBPHY_PER_PORT_RCOMP_HS_PULLUP3,
117 config->usb2_per_port_rcomp_hs_pullup3),
118 REG_SCRIPT_END
120 reg_script_run(usb2_phy_script);
123 static void ehci_init(struct device *dev)
125 struct soc_intel_baytrail_config *config = config_of(dev);
126 struct reg_script ehci_hc_init[] = {
127 /* Controller init */
128 REG_SCRIPT_NEXT(ehci_init_script),
129 /* Enable clock gating */
130 REG_SCRIPT_NEXT(ehci_clock_gating_script),
132 * Disable ports if requested
134 /* Open per-port disable control override */
135 REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~0, UPRWC_WR_EN),
136 REG_PCI_WRITE8(EHCI_USB2PDO, config->usb2_port_disable_mask),
137 /* Close per-port disable control override */
138 REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~UPRWC_WR_EN, 0),
139 REG_SCRIPT_END
142 /* Don't reset controller in S3 resume path */
143 if (!acpi_is_wakeup_s3())
144 reg_script_run_on_dev(dev, ehci_hc_reset);
146 /* Disable controller if ports are routed to XHCI */
147 if (config->usb_route_to_xhci) {
148 /* Disable controller */
149 reg_script_run_on_dev(dev, ehci_disable_script);
151 /* Hide device with southcluster function */
152 dev->enabled = 0;
153 southcluster_enable_dev(dev);
154 } else {
155 /* Initialize EHCI controller */
156 reg_script_run_on_dev(dev, ehci_hc_init);
159 /* Setup USB2 PHY based on board config */
160 usb2_phy_init(dev);
163 static struct device_operations ehci_device_ops = {
164 .read_resources = pci_dev_read_resources,
165 .set_resources = pci_dev_set_resources,
166 .enable_resources = pci_dev_enable_resources,
167 .init = ehci_init,
168 .ops_pci = &soc_pci_ops,
171 static const struct pci_driver baytrail_ehci __pci_driver = {
172 .ops = &ehci_device_ops,
173 .vendor = PCI_VENDOR_ID_INTEL,
174 .device = EHCI_DEVID