diff --git a/src/soc/intel/broadwell/ehci.c b/src/soc/intel/broadwell/ehci.c index 7ec82d7f3a..e27c8e59c9 100644 --- a/src/soc/intel/broadwell/ehci.c +++ b/src/soc/intel/broadwell/ehci.c @@ -23,150 +23,9 @@ #include #include #include -#include "pch.h" #include #include - -#ifdef __SMM__ - -void usb_ehci_disable(device_t dev) -{ - u16 reg16; - u32 reg32; - - /* Set 0xDC[0]=1 */ - pci_or_config32(dev, 0xdc, (1 << 0)); - - /* Set D3Hot state and disable PME */ - reg16 = pci_read_config16(dev, EHCI_PWR_CTL_STS); - reg16 &= ~(PWR_CTL_ENABLE_PME | PWR_CTL_SET_MASK); - reg16 |= PWR_CTL_SET_D3; - pci_write_config16(dev, EHCI_PWR_CTL_STS, reg16); - - /* Clear memory and bus master */ - pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0); - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Disable device */ - switch (dev) { - case PCH_EHCI1_DEV: - RCBA32_OR(FD, PCH_DISABLE_EHCI1); - break; - case PCH_EHCI2_DEV: - RCBA32_OR(FD, PCH_DISABLE_EHCI2); - break; - } -} - -/* Handler for EHCI controller on entry to S3/S4/S5 */ -void usb_ehci_sleep_prepare(device_t dev, u8 slp_typ) -{ - u32 reg32; - u32 bar0_base; - u16 pwr_state; - u16 pci_cmd; - - /* Check if the controller is disabled or not present */ - bar0_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); - if (bar0_base == 0 || bar0_base == 0xffffffff) - return; - pci_cmd = pci_read_config32(dev, PCI_COMMAND); - - switch (slp_typ) { - case SLP_TYP_S4: - case SLP_TYP_S5: - /* Check if controller is in D3 power state */ - pwr_state = pci_read_config16(dev, EHCI_PWR_CTL_STS); - if ((pwr_state & PWR_CTL_SET_MASK) == PWR_CTL_SET_D3) { - /* Put in D0 */ - u32 new_state = pwr_state & ~PWR_CTL_SET_MASK; - new_state |= PWR_CTL_SET_D0; - pci_write_config16(dev, EHCI_PWR_CTL_STS, new_state); - - /* Make sure memory bar is set */ - pci_write_config32(dev, PCI_BASE_ADDRESS_0, bar0_base); - - /* Make sure memory space is enabled */ - pci_write_config16(dev, PCI_COMMAND, pci_cmd | - PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - } - - /* - * If Run/Stop (bit0) is clear in USB2.0_CMD: - * - Clear Async Schedule Enable (bit5) and - * - Clear Periodic Schedule Enable (bit4) and - * - Set Run/Stop (bit0) - */ - reg32 = read32(bar0_base + EHCI_USB_CMD); - if (reg32 & EHCI_USB_CMD_RUN) { - reg32 &= ~(EHCI_USB_CMD_PSE | EHCI_USB_CMD_ASE); - reg32 |= EHCI_USB_CMD_RUN; - write32(bar0_base + EHCI_USB_CMD, reg32); - } - - /* Check for Port Enabled in PORTSC(0) (RMH) */ - reg32 = read32(bar0_base + EHCI_PORTSC(0)); - if (reg32 & EHCI_PORTSC_ENABLED) { - /* Set suspend bit in PORTSC if not already set */ - if (!(reg32 & EHCI_PORTSC_SUSPEND)) { - reg32 |= EHCI_PORTSC_SUSPEND; - write32(bar0_base + EHCI_PORTSC(0), reg32); - } - - /* Delay 25ms !! */ - udelay(25 * 1000); - - /* Clear Run/Stop bit */ - reg32 = read32(bar0_base + EHCI_USB_CMD); - reg32 &= EHCI_USB_CMD_RUN; - write32(bar0_base + EHCI_USB_CMD, reg32); - } - - /* Restore state to D3 if that is what it was at the start */ - if ((pwr_state & PWR_CTL_SET_MASK) == PWR_CTL_SET_D3) { - /* Restore pci command reg */ - pci_write_config16(dev, PCI_COMMAND, pci_cmd); - - /* Enable D3 */ - pci_write_config16(dev, EHCI_PWR_CTL_STS, pwr_state); - } - } -} - -#else /* !__SMM__ */ - -static void usb_ehci_clock_gating(struct device *dev) -{ - u32 reg32; - - /* IOBP 0xE5004001[7:6] = 11b */ - pch_iobp_update(0xe5004001, ~0, (1 << 7)|(1 << 6)); - - /* Dx:F0:DCh[5,2,1] = 111b - * Dx:F0:DCh[0] = 1b when EHCI controller is disabled */ - reg32 = pci_read_config32(dev, 0xdc); - reg32 |= (1 << 5) | (1 << 2) | (1 << 1); - pci_write_config32(dev, 0xdc, reg32); - - /* Dx:F0:78h[1:0] = 11b */ - reg32 = pci_read_config32(dev, 0x78); - reg32 |= (1 << 1) | (1 << 0); - pci_write_config32(dev, 0x78, reg32); -} - -static void usb_ehci_init(struct device *dev) -{ - printk(BIOS_DEBUG, "EHCI: Setting up controller.. "); - - usb_ehci_clock_gating(dev); - - /* Disable Wake on Disconnect in RMH */ - RCBA32_OR(0x35b0, 0x00000022); - - printk(BIOS_DEBUG, "done.\n"); -} +#include static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) { @@ -233,5 +92,3 @@ static const struct pci_driver pch_usb_ehci __pci_driver = { .vendor = PCI_VENDOR_ID_INTEL, .devices = pci_device_ids, }; - -#endif /* !__SMM__ */ diff --git a/src/soc/intel/broadwell/xhci.c b/src/soc/intel/broadwell/xhci.c index 3e74f2acde..89e1139f14 100644 --- a/src/soc/intel/broadwell/xhci.c +++ b/src/soc/intel/broadwell/xhci.c @@ -23,11 +23,10 @@ #include #include #include -#include "pch.h" - -typedef struct southbridge_intel_lynxpoint_config config_t; #include +#include +#ifdef __SMM__ static u32 usb_xhci_mem_base(device_t dev) { u32 mem_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); @@ -41,23 +40,8 @@ static u32 usb_xhci_mem_base(device_t dev) static int usb_xhci_port_count_usb3(device_t dev) { - if (pch_is_lp()) { - /* LynxPoint-LP has 4 SS ports */ - return 4; - } else { - /* LynxPoint-H can have 0, 2, 4, or 6 SS ports */ - u32 mem_base = usb_xhci_mem_base(dev); - u32 fus = read32(mem_base + XHCI_USB3FUS); - fus >>= XHCI_USB3FUS_SS_SHIFT; - fus &= XHCI_USB3FUS_SS_MASK; - switch (fus) { - case 3: return 0; - case 2: return 2; - case 1: return 4; - case 0: default: return 6; - } - } - return 0; + /* PCH-LP has 4 SS ports */ + return 4; } static void usb_xhci_reset_status_usb3(u32 mem_base, int port) @@ -157,8 +141,6 @@ static void usb_xhci_reset_usb3(device_t dev, int all) usb_xhci_reset_status_usb3(mem_base, port); } -#ifdef __SMM__ - /* Handler for XHCI controller on entry to S3/S4/S5 */ void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ) { @@ -169,219 +151,36 @@ void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ) if (!mem_base || slp_typ < 3) return; - if (pch_is_lp()) { - /* Set D0 state */ - reg16 = pci_read_config16(dev, XHCI_PWR_CTL_STS); - reg16 &= ~PWR_CTL_SET_MASK; - reg16 |= PWR_CTL_SET_D0; - pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16); - - /* Clear PCI 0xB0[14:13] */ - reg32 = pci_read_config32(dev, 0xb0); - reg32 &= ~((1 << 14) | (1 << 13)); - pci_write_config32(dev, 0xb0, reg32); - - /* Clear MMIO 0x816c[14,2] */ - reg32 = read32(mem_base + 0x816c); - reg32 &= ~((1 << 14) | (1 << 2)); - write32(mem_base + 0x816c, reg32); - - /* Reset disconnected USB3 ports */ - usb_xhci_reset_usb3(dev, 0); - - /* Set MMIO 0x80e0[15] */ - reg32 = read32(mem_base + 0x80e0); - reg32 |= (1 << 15); - write32(mem_base + 0x80e0, reg32); - } - - /* Set D3Hot state and enable PME */ - pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_SET_D3); - pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_STATUS_PME); - pci_or_config16(dev, XHCI_PWR_CTL_STS, PWR_CTL_ENABLE_PME); -} - -/* Route all ports to XHCI controller */ -void usb_xhci_route_all(void) -{ - u32 port_mask, route; - u16 reg16; - - /* Skip if EHCI is already disabled */ - if (RCBA32(FD) & PCH_DISABLE_EHCI1) - return; - /* Set D0 state */ - reg16 = pci_read_config16(PCH_XHCI_DEV, XHCI_PWR_CTL_STS); - reg16 &= ~PWR_CTL_SET_MASK; - reg16 |= PWR_CTL_SET_D0; - pci_write_config16(PCH_XHCI_DEV, XHCI_PWR_CTL_STS, reg16); - - /* Set USB3 superspeed enable */ - port_mask = pci_read_config32(PCH_XHCI_DEV, XHCI_USB3PRM); - route = pci_read_config32(PCH_XHCI_DEV, XHCI_USB3PR); - route &= ~XHCI_USB3PR_SSEN; - route |= XHCI_USB3PR_SSEN & port_mask; - pci_write_config32(PCH_XHCI_DEV, XHCI_USB3PR, route); - - /* Route USB2 ports to XHCI controller */ - port_mask = pci_read_config32(PCH_XHCI_DEV, XHCI_USB2PRM); - route = pci_read_config32(PCH_XHCI_DEV, XHCI_USB2PR); - route &= ~XHCI_USB2PR_HCSEL; - route |= XHCI_USB2PR_HCSEL & port_mask; - pci_write_config32(PCH_XHCI_DEV, XHCI_USB2PR, route); - - /* Disable EHCI controller */ - usb_ehci_disable(PCH_EHCI1_DEV); - - /* LynxPoint-H has a second EHCI controller */ - if (!pch_is_lp()) - usb_ehci_disable(PCH_EHCI2_DEV); - - /* Reset and clear port change status */ - usb_xhci_reset_usb3(PCH_XHCI_DEV, 1); -} - -#else /* !__SMM__ */ - -static void usb_xhci_clock_gating(device_t dev) -{ - u32 reg32; - u16 reg16; - - /* IOBP 0xE5004001[7:6] = 11b */ - pch_iobp_update(0xe5004001, ~0, (1 << 7)|(1 << 6)); - - reg32 = pci_read_config32(dev, 0x40); - reg32 &= ~(1 << 23); /* unsupported request */ - - if (pch_is_lp()) { - /* D20:F0:40h[18,17,8] = 111b */ - reg32 |= (1 << 18) | (1 << 17) | (1 << 8); - /* D20:F0:40h[21,20,19] = 110b to enable XHCI Idle L1 */ - reg32 &= ~(1 << 19); - reg32 |= (1 << 21) | (1 << 20); - } else { - /* D20:F0:40h[21,20,18,17,8] = 11111b */ - reg32 |= (1 << 21)|(1 << 20)|(1 << 18)|(1 << 17)|(1 << 8); - } - - /* Avoid writing upper byte as it is write-once */ - pci_write_config16(dev, 0x40, (u16)(reg32 & 0xffff)); - pci_write_config8(dev, 0x40 + 2, (u8)((reg32 >> 16) & 0xff)); - - /* D20:F0:44h[9,7,3] = 111b */ - reg16 = pci_read_config16(dev, 0x44); - reg16 |= (1 << 9) | (1 << 7) | (1 << 3); - pci_write_config16(dev, 0x44, reg16); - - reg32 = pci_read_config32(dev, 0xa0); - if (pch_is_lp()) { - /* D20:F0:A0h[18] = 1 */ - reg32 |= (1 << 18); - } else { - /* D20:F0:A0h[6] = 1 */ - reg32 |= (1 << 6); - } - pci_write_config32(dev, 0xa0, reg32); - - /* D20:F0:A4h[13] = 0 */ - reg32 = pci_read_config32(dev, 0xa4); - reg32 &= ~(1 << 13); - pci_write_config32(dev, 0xa4, reg32); -} - -static void usb_xhci_init(device_t dev) -{ - u32 reg32; - u16 reg16; - u32 mem_base = usb_xhci_mem_base(dev); - config_t *config = dev->chip_info; - - /* D20:F0:74h[1:0] = 00b (set D0 state) */ reg16 = pci_read_config16(dev, XHCI_PWR_CTL_STS); - reg16 &= ~PWR_CTL_SET_MASK; - reg16 |= PWR_CTL_SET_D0; + reg16 &= ~XHCI_PWR_CTL_SET_MASK; + reg16 |= XHCI_PWR_CTL_SET_D0; pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16); - /* Enable clock gating first */ - usb_xhci_clock_gating(dev); + /* Clear PCI 0xB0[14:13] */ + reg32 = pci_read_config32(dev, 0xb0); + reg32 &= ~((1 << 14) | (1 << 13)); + pci_write_config32(dev, 0xb0, reg32); - reg32 = read32(mem_base + 0x8144); - if (pch_is_lp()) { - /* XHCIBAR + 8144h[8,7,6] = 111b */ - reg32 |= (1 << 8) | (1 << 7) | (1 << 6); - } else { - /* XHCIBAR + 8144h[8,7,6] = 100b */ - reg32 &= ~((1 << 7) | (1 << 6)); - reg32 |= (1 << 8); - } - write32(mem_base + 0x8144, reg32); + /* Clear MMIO 0x816c[14,2] */ + reg32 = read32(mem_base + 0x816c); + reg32 &= ~((1 << 14) | (1 << 2)); + write32(mem_base + 0x816c, reg32); - if (pch_is_lp()) { - /* XHCIBAR + 816Ch[19:0] = 000e0038h */ - reg32 = read32(mem_base + 0x816c); - reg32 &= ~0x000fffff; - reg32 |= 0x000e0038; - write32(mem_base + 0x816c, reg32); + /* Reset disconnected USB3 ports */ + usb_xhci_reset_usb3(dev, 0); - /* D20:F0:B0h[17,14,13] = 100b */ - reg32 = pci_read_config32(dev, 0xb0); - reg32 &= ~((1 << 14) | (1 << 13)); - reg32 |= (1 << 17); - pci_write_config32(dev, 0xb0, reg32); - } + /* Set MMIO 0x80e0[15] */ + reg32 = read32(mem_base + 0x80e0); + reg32 |= (1 << 15); + write32(mem_base + 0x80e0, reg32); - reg32 = pci_read_config32(dev, 0x50); - if (pch_is_lp()) { - /* D20:F0:50h[28:0] = 0FCE2E5Fh */ - reg32 &= ~0x1fffffff; - reg32 |= 0x0fce2e5f; - } else { - /* D20:F0:50h[26:0] = 07886E9Fh */ - reg32 &= ~0x07ffffff; - reg32 |= 0x07886e9f; - } - pci_write_config32(dev, 0x50, reg32); - - /* D20:F0:44h[31] = 1 (Access Control Bit) */ - reg32 = pci_read_config32(dev, 0x44); - reg32 |= (1 << 31); - pci_write_config32(dev, 0x44, reg32); - - /* D20:F0:40h[31,23] = 10b (OC Configuration Done) */ - reg32 = pci_read_config32(dev, 0x40); - reg32 &= ~(1 << 23); /* unsupported request */ - reg32 |= (1 << 31); - pci_write_config32(dev, 0x40, reg32); - -#if CONFIG_HAVE_ACPI_RESUME - if (acpi_slp_type == 3) { - /* Reset ports that are disabled or - * polling before returning to the OS. */ - usb_xhci_reset_usb3(dev, 0); - } else -#endif - /* Route all ports to XHCI */ - if (config->xhci_default) - outb(0xca, 0xb2); + /* Set D3Hot state and enable PME */ + pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_SET_D3); + pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_STATUS_PME); + pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_ENABLE_PME); } - -static void usb_xhci_set_subsystem(device_t dev, unsigned vendor, - unsigned device) -{ - if (!vendor || !device) { - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, - pci_read_config32(dev, PCI_VENDOR_ID)); - } else { - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, - ((device & 0xffff) << 16) | (vendor & 0xffff)); - } -} - -static struct pci_operations lops_pci = { - .set_subsystem = &usb_xhci_set_subsystem, -}; +#else /* !__SMM__ */ static struct device_operations usb_xhci_ops = { .read_resources = &pci_dev_read_resources,