blob: 3005610439c052fd09e2fde4a47f046553b61fb2 [file] [log] [blame]
Angel Pons230e4f9d2020-04-05 15:47:14 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy4dd34ee2016-05-02 14:31:02 -07002
3#include <console/console.h>
4#include <device/pci_ids.h>
5#include <soc/pci_devs.h>
6#include <soc/reg_access.h>
7
8/* USB Phy Registers */
9#define USB2_GLOBAL_PORT 0x4001
10#define USB2_PLL1 0x7F02
11#define USB2_PLL2 0x7F03
12#define USB2_COMPBG 0x7F04
13
Lee Leahyf8841122016-05-22 09:23:49 -070014/* EHCI Packet Buffer OUT/IN Thresholds, values in number of DWORDs */
15#define EHCI_OUT_THRESHOLD_VALUE 0x7f
16#define EHCI_IN_THRESHOLD_VALUE 0x7f
17
Lee Leahyfd456582016-05-22 09:55:22 -070018/* Platform init USB device interrupt masks */
19#define V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG (0x0000007f)
20#define V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG \
21 (B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK \
22 | B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK)
23
Lee Leahy4dd34ee2016-05-02 14:31:02 -070024/* In order to configure the USB PHY to use clk120 (ickusbcoreclk) as PLL
25 * reference clock and Port2 as a USB device port, the following sequence must
26 * be followed
27 */
Lee Leahyfd456582016-05-22 09:55:22 -070028static const struct reg_script ehci_init_script[] = {
Lee Leahy4dd34ee2016-05-02 14:31:02 -070029
Lee Leahyf8841122016-05-22 09:23:49 -070030 /* Set packet buffer OUT/IN thresholds */
31 REG_MMIO_RMW32(R_IOH_EHCI_INSNREG01,
32 ~(B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK
33 | B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK),
34 (EHCI_OUT_THRESHOLD_VALUE
35 << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP)
36 | (EHCI_IN_THRESHOLD_VALUE
37 << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP)),
38
Lee Leahy4dd34ee2016-05-02 14:31:02 -070039 /* Sighting #4930631 PDNRESCFG [8:7] of USB2_GLOBAL_PORT = 11b.
40 * For port 0 & 1 as host and port 2 as device.
41 */
42 REG_USB_RXW(USB2_GLOBAL_PORT, ~(BIT8 | BIT7 | BIT1), (BIT8 | BIT7)),
43
44 /*
45 * Sighting #4930653 Required BIOS change on Disconnect vref to change
46 * to 600mV.
47 */
48 REG_USB_RXW(USB2_COMPBG, ~(BIT10 | BIT9 | BIT8 | BIT7),
49 (BIT10 | BIT7)),
50
51 /* Sideband register write to USB AFE (Phy)
52 * (pllbypass) to bypass/Disable PLL before switch
53 */
54 REG_USB_OR(USB2_PLL2, BIT29),
55
56 /* Sideband register write to USB AFE (Phy)
57 * (coreclksel) to select 120MHz (ickusbcoreclk) clk source.
58 * (Default 0 to select 96MHz (ickusbclk96_npad/ppad))
59 */
60 REG_USB_OR(USB2_PLL1, BIT1),
61
62 /* Sideband register write to USB AFE (Phy)
63 * (divide by 8) to achieve internal 480MHz clock
64 * for 120MHz input refclk. (Default: 4'b1000 (divide by 10) for 96MHz)
65 */
66 REG_USB_RXW(USB2_PLL1, ~(BIT6 | BIT5 | BIT4 | BIT3), BIT6),
67
68 /* Sideband register write to USB AFE (Phy)
69 * Clear (pllbypass)
70 */
71 REG_USB_AND(USB2_PLL2, ~BIT29),
72
73 /* Sideband register write to USB AFE (Phy)
74 * Set (startlock) to force the PLL FSM to restart the lock
75 * sequence due to input clock/freq switch.
76 */
77 REG_USB_OR(USB2_PLL2, BIT24),
78 REG_SCRIPT_END
79};
80
Lee Leahyfd456582016-05-22 09:55:22 -070081static const struct reg_script usb_device_port_init_script[] = {
82
83 /* Mask and clear controller interrupts */
84 REG_MMIO_WRITE32(R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG,
85 V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG),
86 REG_MMIO_WRITE32(R_IOH_USBDEVICE_D_INTR_UDC_REG,
87 V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG),
88
89 /* Mask and clear end point interrupts */
90 REG_MMIO_WRITE32(R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG,
91 V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG),
92 REG_MMIO_WRITE32(R_IOH_USBDEVICE_EP_INTR_UDC_REG,
93 V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG),
94 REG_SCRIPT_END
95};
96
Elyes HAOUAS696545d2018-05-25 13:11:37 +020097static void init(struct device *dev)
Lee Leahy4dd34ee2016-05-02 14:31:02 -070098{
Lee Leahyfd456582016-05-22 09:55:22 -070099 if ((dev->path.pci.devfn & 7) == EHCI_FUNC) {
100 printk(BIOS_INFO, "Initializing USB PLLs\n");
101 reg_script_run_on_dev(dev, ehci_init_script);
102 } else {
103 printk(BIOS_INFO, "Initializing USB device port\n");
104 reg_script_run_on_dev(dev, usb_device_port_init_script);
105 }
Lee Leahy4dd34ee2016-05-02 14:31:02 -0700106}
107
108static struct device_operations device_ops = {
109 .read_resources = pci_dev_read_resources,
110 .set_resources = pci_dev_set_resources,
111 .enable_resources = pci_dev_enable_resources,
112 .init = init,
113};
114
115static const struct pci_driver driver __pci_driver = {
116 .ops = &device_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100117 .vendor = PCI_VID_INTEL,
Lee Leahy4dd34ee2016-05-02 14:31:02 -0700118 .device = EHCI_DEVID,
119};