sb/intel/lynxpoint: Use PCI bitwise ops

Some cases could not be factored out while keeping reproducibility.
Also mark some potential bugs with a FIXME comment, since fixing them
while also keeping the binary unchanged is pretty much impossible.

Tested with BUILD_TIMELESS=1, Asrock B85M Pro4 does not change.

Change-Id: I27d6aaa59e12a337f80a6d3387cc9c8ae5949384
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42154
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Angel Pons 2020-06-08 00:12:43 +02:00
parent bd84485017
commit bf9bc50ec1
10 changed files with 85 additions and 167 deletions

View File

@ -41,9 +41,7 @@ static void azalia_pch_init(struct device *dev, u8 *base)
pci_write_config32(dev, 0x120, reg32);
if (!pch_is_lp()) {
reg16 = pci_read_config16(dev, 0x78);
reg16 &= ~(1 << 11);
pci_write_config16(dev, 0x78, reg16);
pci_and_config16(dev, 0x78, ~(1 << 11));
}
} else
printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
@ -53,8 +51,7 @@ static void azalia_pch_init(struct device *dev, u8 *base)
pci_write_config32(dev, 0x114, reg32);
// Set VCi enable bit
if (pci_read_config32(dev, 0x120) & ((1 << 24) |
(1 << 25) | (1 << 26))) {
if (pci_read_config32(dev, 0x120) & ((1 << 24) | (1 << 25) | (1 << 26))) {
reg32 = pci_read_config32(dev, 0x120);
if (pch_is_lp())
reg32 &= ~(1UL << 31);
@ -70,11 +67,8 @@ static void azalia_pch_init(struct device *dev, u8 *base)
reg8 |= (1 << 4);
pci_write_config8(dev, 0x43, reg8);
if (!pch_is_lp()) {
reg32 = pci_read_config32(dev, 0xc0);
reg32 |= (1 << 17);
pci_write_config32(dev, 0xc0, reg32);
}
if (!pch_is_lp())
pci_or_config32(dev, 0xc0, 1 << 17);
/* Additional programming steps */
reg32 = pci_read_config32(dev, 0xc4);
@ -84,19 +78,14 @@ static void azalia_pch_init(struct device *dev, u8 *base)
reg32 |= (1 << 14);
pci_write_config32(dev, 0xc4, reg32);
if (!pch_is_lp()) {
reg32 = pci_read_config32(dev, 0xd0);
reg32 &= ~(1UL << 31);
pci_write_config32(dev, 0xd0, reg32);
}
if (!pch_is_lp())
pci_and_config32(dev, 0xd0, ~(1UL << 31));
reg8 = pci_read_config8(dev, 0x40); // Audio Control
reg8 |= 1; // Select Azalia mode
pci_write_config8(dev, 0x40, reg8);
// Select Azalia mode
pci_or_config8(dev, 0x40, 1); // Audio Control
reg8 = pci_read_config8(dev, 0x4d); // Docking Status
reg8 &= ~(1 << 7); // Docking not supported
pci_write_config8(dev, 0x4d, reg8);
// Docking not supported
pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
if (pch_is_lp()) {
reg16 = read32(base + 0x0012);
@ -104,9 +93,7 @@ static void azalia_pch_init(struct device *dev, u8 *base)
write32(base + 0x0012, reg16);
/* disable Auto Voltage Detector */
reg8 = pci_read_config8(dev, 0x42);
reg8 |= (1 << 2);
pci_write_config8(dev, 0x42, reg8);
pci_or_config8(dev, 0x42, 1 << 2);
}
}

View File

@ -334,8 +334,7 @@ static void lpt_lp_pm_init(struct device *dev)
RCBA32_AND_OR(0x2b20, 0, 0x0005db01); /* Power Optimizer */
RCBA32_AND_OR(0x3a80, 0, 0x05145005);
pci_write_config32(dev, 0xac,
pci_read_config32(dev, 0xac) | (1 << 21));
pci_or_config32(dev, 0xac, 1 << 21);
pch_iobp_update(0xED00015C, ~(1 << 11), 0x00003700);
pch_iobp_update(0xED000118, ~0UL, 0x00c00000);
@ -424,9 +423,7 @@ static void enable_lp_clock_gating(struct device *dev)
reg16 |= (1 << 2); // PCI CLKRUN# Enable
pci_write_config16(dev, GEN_PMCON_1, reg16);
reg32 = pci_read_config32(dev, 0x64);
reg32 |= (1 << 6);
pci_write_config32(dev, 0x64, reg32);
pci_or_config32(dev, 0x64, 1 << 6);
/*
* RCBA + 0x2614[27:25,14:13,10,8] = 101,11,1,1
@ -477,22 +474,15 @@ static void pch_set_acpi_mode(void)
static void pch_disable_smm_only_flashing(struct device *dev)
{
u8 reg8;
printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... ");
reg8 = pci_read_config8(dev, BIOS_CNTL);
reg8 &= ~(1 << 5);
pci_write_config8(dev, BIOS_CNTL, reg8);
pci_and_config8(dev, BIOS_CNTL, ~(1 << 5));
}
static void pch_fixups(struct device *dev)
{
u8 gen_pmcon_2;
/* Indicate DRAM init done for MRC S3 to know it can resume */
gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2);
gen_pmcon_2 |= (1 << 7);
pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
pci_or_config8(dev, GEN_PMCON_2, 1 << 7);
/*
* Enable DMI ASPM in the PCH

View File

@ -541,7 +541,6 @@ void intel_me_finalize_smm(void)
{
struct me_hfs hfs;
u32 reg32;
u16 reg16;
mei_base_address = (u32 *)
(pci_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf);
@ -569,9 +568,8 @@ void intel_me_finalize_smm(void)
mkhi_end_of_post();
/* Make sure IO is disabled */
reg16 = pci_read_config16(PCH_ME_DEV, PCI_COMMAND);
reg16 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
pci_write_config16(PCH_ME_DEV, PCI_COMMAND, reg16);
pci_and_config16(PCH_ME_DEV, PCI_COMMAND,
~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
/* Hide the PCI device */
RCBA32_OR(FD2, PCH_DISABLE_MEI1);

View File

@ -86,9 +86,7 @@ u16 get_gpiobase(void)
/* Put device in D3Hot Power State */
static void pch_enable_d3hot(struct device *dev)
{
u32 reg32 = pci_read_config32(dev, PCH_PCS);
reg32 |= PCH_PCS_PS_D3HOT;
pci_write_config32(dev, PCH_PCS, reg32);
pci_or_config32(dev, PCH_PCS, PCH_PCS_PS_D3HOT);
}
/* Set bit in function disable register to hide this device */
@ -291,8 +289,6 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
void pch_enable(struct device *dev)
{
u16 reg16;
/* PCH PCIe Root Ports are handled in PCIe driver. */
if (PCI_SLOT(dev->path.pci.devfn) == PCH_PCIE_DEV_SLOT)
return;
@ -301,9 +297,8 @@ void pch_enable(struct device *dev)
printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
/* Ensure memory, io, and bus master are all disabled */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND,
~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
/* Disable this device if possible */
pch_disable_devfn(dev);

View File

@ -232,41 +232,40 @@ static void pcie_enable_clock_gating(void)
rp = root_port_number(dev);
if (!is_rp_enabled(rp)) {
static const uint32_t high_bit = (1UL << 31);
/* Configure shared resource clock gating. */
if (rp == 1 || rp == 5 || (rp == 6 && is_lp))
pci_update_config8(dev, 0xe1, 0xc3, 0x3c);
pci_or_config8(dev, 0xe1, 0x3c);
if (!is_lp) {
if (rp == 1 && !is_rp_enabled(2) &&
!is_rp_enabled(3) && !is_rp_enabled(4)) {
pci_update_config8(dev, 0xe2, ~1, 1);
pci_update_config8(dev, 0xe1, 0x7f, 0x80);
pci_or_config8(dev, 0xe2, 1);
pci_or_config8(dev, 0xe1, 1 << 7);
}
if (rp == 5 && !is_rp_enabled(6) &&
!is_rp_enabled(7) && !is_rp_enabled(8)) {
pci_update_config8(dev, 0xe2, ~1, 1);
pci_update_config8(dev, 0xe1, 0x7f, 0x80);
pci_or_config8(dev, 0xe2, 1);
pci_or_config8(dev, 0xe1, 1 << 7);
}
continue;
}
pci_update_config8(dev, 0xe2, ~(3 << 4), (3 << 4));
pci_update_config32(dev, 0x420, ~high_bit, high_bit);
pci_or_config8(dev, 0xe2, 3 << 4);
pci_or_config32(dev, 0x420, 1 << 31);
/* Per-Port CLKREQ# handling. */
if (is_lp && gpio_is_native(18 + rp - 1))
pci_update_config32(dev, 0x420, ~0, (3 << 29));
pci_or_config32(dev, 0x420, 3 << 29);
/* Enable static clock gating. */
if (rp == 1 && !is_rp_enabled(2) &&
!is_rp_enabled(3) && !is_rp_enabled(4)) {
pci_update_config8(dev, 0xe2, ~1, 1);
pci_update_config8(dev, 0xe1, 0x7f, 0x80);
pci_or_config8(dev, 0xe2, 1);
pci_or_config8(dev, 0xe1, 1 << 7);
} else if (rp == 5 || rp == 6) {
pci_update_config8(dev, 0xe2, ~1, 1);
pci_update_config8(dev, 0xe1, 0x7f, 0x80);
pci_or_config8(dev, 0xe2, 1);
pci_or_config8(dev, 0xe1, 1 << 7);
}
continue;
}
@ -274,29 +273,30 @@ static void pcie_enable_clock_gating(void)
enabled_ports++;
/* Enable dynamic clock gating. */
pci_update_config8(dev, 0xe1, 0xfc, 0x03);
pci_or_config8(dev, 0xe1, 0x03);
if (is_lp) {
pci_update_config8(dev, 0xe2, ~(1 << 6), (1 << 6));
pci_or_config8(dev, 0xe2, 1 << 6);
pci_update_config8(dev, 0xe8, ~(3 << 2), (2 << 2));
}
/* Update PECR1 register. */
pci_update_config8(dev, 0xe8, ~0, 1);
pci_or_config8(dev, 0xe8, 1);
/* FIXME: Are we supposed to update this register with a constant boolean? */
pci_update_config8(dev, 0x324, ~(1 << 5), (1 < 5));
/* Per-Port CLKREQ# handling. */
if (is_lp && gpio_is_native(18 + rp - 1))
pci_update_config32(dev, 0x420, ~0, (3 << 29));
pci_or_config32(dev, 0x420, 3 << 29);
/* Configure shared resource clock gating. */
if (rp == 1 || rp == 5 || (rp == 6 && is_lp))
pci_update_config8(dev, 0xe1, 0xc3, 0x3c);
pci_or_config8(dev, 0xe1, 0x3c);
}
if (!enabled_ports && is_lp && rpc.ports[0])
pci_update_config8(rpc.ports[0], 0xe1, ~(1 << 6), (1 << 6));
pci_or_config8(rpc.ports[0], 0xe1, 1 << 6);
}
static void root_port_commit_config(void)
@ -312,7 +312,6 @@ static void root_port_commit_config(void)
for (i = 0; i < rpc.num_ports; i++) {
struct device *dev;
u16 reg16;
dev = rpc.ports[i];
@ -327,9 +326,8 @@ static void root_port_commit_config(void)
printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
/* Ensure memory, io, and bus master are all disabled */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND,
~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
/* Disable this device if possible */
pch_disable_devfn(dev);
@ -639,11 +637,11 @@ static void pch_pcie_early(struct device *dev)
}
}
pci_update_config32(dev, 0x338, ~(1 << 26), 0);
pci_and_config32(dev, 0x338, ~(1 << 26));
}
/* Enable LTR in Root Port. */
pci_update_config32(dev, 0x64, ~(1 << 11), (1 << 11));
pci_or_config32(dev, 0x64, 1 << 11);
pci_update_config32(dev, 0x68, ~(1 << 10), (1 << 10));
pci_update_config32(dev, 0x318, ~(0xffffUL << 16), (0x1414UL << 16));
@ -654,7 +652,7 @@ static void pch_pcie_early(struct device *dev)
else
pci_update_config32(dev, 0x4c, ~(0x7 << 15), (0x2 << 15));
pci_update_config32(dev, 0x314, 0x0, 0x743a361b);
pci_update_config32(dev, 0x314, 0, 0x743a361b);
/* Set Common Clock Exit Latency in MPC register. */
pci_update_config32(dev, 0xd8, ~(0x7 << 15), (0x3 << 15));
@ -662,21 +660,21 @@ static void pch_pcie_early(struct device *dev)
pci_update_config32(dev, 0x33c, ~0x00ffffff, 0x854c74);
/* Set Invalid Recieve Range Check Enable in MPC register. */
pci_update_config32(dev, 0xd8, ~0, (1 << 25));
pci_or_config32(dev, 0xd8, 1 << 25);
pci_update_config8(dev, 0xf5, 0x3f, 0);
pci_and_config8(dev, 0xf5, 0x3f);
if (rp == 1 || rp == 5 || (is_lp && rp == 6))
pci_update_config8(dev, 0xf7, ~0xc, 0);
pci_and_config8(dev, 0xf7, ~0x0c);
/* Set EOI forwarding disable. */
pci_update_config32(dev, 0xd4, ~0, (1 << 1));
pci_or_config32(dev, 0xd4, 1 << 1);
/* Set something involving advanced error reporting. */
pci_update_config32(dev, 0x100, ~((1 << 20) - 1), 0x10001);
if (is_lp)
pci_update_config32(dev, 0x100, ~0, (1 << 29));
pci_or_config32(dev, 0x100, 1 << 29);
/* Read and write back write-once capability registers. */
pci_update_config32(dev, 0x34, ~0, 0);
@ -687,8 +685,6 @@ static void pch_pcie_early(struct device *dev)
static void pci_init(struct device *dev)
{
u16 reg16;
printk(BIOS_DEBUG, "Initializing PCH PCIe bridge.\n");
/* Enable SERR */
@ -701,15 +697,11 @@ static void pci_init(struct device *dev)
// This has no effect but the OS might expect it
pci_write_config8(dev, 0x0c, 0x10);
reg16 = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
reg16 &= ~PCI_BRIDGE_CTL_PARITY;
pci_write_config16(dev, PCI_BRIDGE_CONTROL, reg16);
pci_and_config16(dev, PCI_BRIDGE_CONTROL, ~PCI_BRIDGE_CTL_PARITY);
/* Clear errors in status registers */
reg16 = pci_read_config16(dev, 0x06);
pci_write_config16(dev, 0x06, reg16);
reg16 = pci_read_config16(dev, 0x1e);
pci_write_config16(dev, 0x1e, reg16);
pci_update_config16(dev, 0x06, ~0, 0);
pci_update_config16(dev, 0x1e, ~0, 0);
}
static void pch_pcie_enable(struct device *dev)

View File

@ -48,11 +48,10 @@ static void sata_init(struct device *dev)
printk(BIOS_DEBUG, "SATA: Controller in combined mode.\n");
/* No AHCI: clear AHCI base */
pci_write_config32(dev, 0x24, 0x00000000);
pci_write_config32(dev, 0x24, 0);
/* And without AHCI BAR no memory decoding */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MEMORY);
pci_write_config8(dev, 0x09, 0x80);
@ -78,8 +77,7 @@ static void sata_init(struct device *dev)
pci_write_config16(dev, 0x92, reg16);
/* SATA Initialization register */
pci_write_config32(dev, 0x94,
((config->sata_port_map ^ 0x3f) << 24) | 0x183);
pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183);
} else if (config->sata_ahci) {
u32 *abar;
@ -129,10 +127,8 @@ static void sata_init(struct device *dev)
}
pci_write_config32(dev, 0x98, reg32);
/* Setup register 9Ch */
reg16 = 0; /* Disable alternate ID */
reg16 |= (1 << 5); /* BWG step 12 */
pci_write_config16(dev, 0x9c, reg16);
/* Setup register 9Ch: Disable alternate ID and BWG step 12 */
pci_write_config16(dev, 0x9c, 1 << 5);
/* SATA Initialization register */
reg32 = 0x183;
@ -170,15 +166,16 @@ static void sata_init(struct device *dev)
printk(BIOS_DEBUG, "SATA: Controller in plain mode.\n");
/* No AHCI: clear AHCI base */
pci_write_config32(dev, 0x24, 0x00000000);
pci_write_config32(dev, 0x24, 0);
/* And without AHCI BAR no memory decoding */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MEMORY);
/* Native mode capable on both primary and secondary (0xa)
/*
* Native mode capable on both primary and secondary (0xa)
* or'ed with enabled (0x50) = 0xf
*
* FIXME: Does not match the code.
*/
pci_write_config8(dev, 0x09, 0x8f);
@ -209,8 +206,7 @@ static void sata_init(struct device *dev)
pci_write_config16(dev, 0x92, reg16);
/* SATA Initialization register */
pci_write_config32(dev, 0x94,
((config->sata_port_map ^ 0x3f) << 24) | 0x183);
pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183);
}
/* Set Gen3 Transmitter settings if needed */

View File

@ -15,6 +15,7 @@ static void pch_smbus_init(struct device *dev)
u16 reg16;
/* Enable clock gating */
/* FIXME: Using 32-bit ops with a 16-bit variable is a bug! These should be 16-bit! */
reg16 = pci_read_config32(dev, 0x80);
reg16 &= ~((1 << 8)|(1 << 10)|(1 << 12)|(1 << 14));
pci_write_config32(dev, 0x80, reg16);

View File

@ -54,7 +54,6 @@ static void busmaster_disable_on_bus(int bus)
for (slot = 0; slot < 0x20; slot++) {
for (func = 0; func < 8; func++) {
u16 reg16;
pci_devfn_t dev = PCI_DEV(bus, slot, func);
val = pci_read_config32(dev, PCI_VENDOR_ID);
@ -64,9 +63,7 @@ static void busmaster_disable_on_bus(int bus)
continue;
/* Disable Bus Mastering for this one device */
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MASTER;
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MASTER);
/* If this is a bridge, then follow it. */
hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
@ -405,8 +402,7 @@ static void southbridge_smi_tco(void)
* box.
*/
printk(BIOS_DEBUG, "Switching back to RO\n");
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc,
(bios_cntl & ~1));
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
} /* No else for now? */
} else if (tco_sts & (1 << 3)) { /* TIMEOUT */
/* Handle TCO timeout */

View File

@ -14,22 +14,18 @@
void usb_ehci_disable(pci_devfn_t dev)
{
u16 reg16;
/* 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);
pci_update_config16(dev, EHCI_PWR_CTL_STS, ~(PWR_CTL_ENABLE_PME | PWR_CTL_SET_MASK),
PWR_CTL_SET_D3);
/* Clear memory and bus master */
pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0);
reg16 = pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
pci_write_config16(dev, PCI_COMMAND, reg16);
pci_and_config16(dev, PCI_COMMAND,
~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
/* Disable device */
switch (dev) {
@ -121,21 +117,15 @@ void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
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);
pci_or_config32(dev, 0xdc, (1 << 5) | (1 << 2) | (1 << 1));
/* Dx:F0:78h[1:0] = 11b */
reg32 = pci_read_config32(dev, 0x78);
reg32 |= (1 << 1) | (1 << 0);
pci_write_config32(dev, 0x78, reg32);
pci_or_config32(dev, 0x78, (1 << 1) | (1 << 0));
}
static void usb_ehci_init(struct device *dev)

View File

@ -157,7 +157,6 @@ static void usb_xhci_reset_usb3(struct device *dev, int all)
/* Handler for XHCI controller on entry to S3/S4/S5 */
void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
{
u16 reg16;
u32 reg32;
u8 *mem_base = usb_xhci_mem_base(dev);
@ -166,15 +165,10 @@ void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
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);
pci_update_config16(dev, XHCI_PWR_CTL_STS, ~PWR_CTL_SET_MASK, PWR_CTL_SET_D0);
/* Clear PCI 0xB0[14:13] */
reg32 = pci_read_config32(dev, 0xb0);
reg32 &= ~((1 << 14) | (1 << 13));
pci_write_config32(dev, 0xb0, reg32);
pci_and_config32(dev, 0xb0, ~((1 << 14) | (1 << 13)));
/* Clear MMIO 0x816c[14,2] */
reg32 = read32(mem_base + 0x816c);
@ -200,17 +194,13 @@ void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ)
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);
pci_update_config16(PCH_XHCI_DEV, XHCI_PWR_CTL_STS, ~PWR_CTL_SET_MASK, PWR_CTL_SET_D0);
/* Set USB3 superspeed enable */
port_mask = pci_read_config32(PCH_XHCI_DEV, XHCI_USB3PRM);
@ -242,7 +232,6 @@ void usb_xhci_route_all(void)
static void usb_xhci_clock_gating(struct device *dev)
{
u32 reg32;
u16 reg16;
/* IOBP 0xE5004001[7:6] = 11b */
pch_iobp_update(0xe5004001, ~0, (1 << 7)|(1 << 6));
@ -266,9 +255,7 @@ static void usb_xhci_clock_gating(struct device *dev)
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);
pci_or_config16(dev, 0x44, (1 << 9) | (1 << 7) | (1 << 3));
reg32 = pci_read_config32(dev, 0xa0);
if (pch_is_lp()) {
@ -281,23 +268,17 @@ static void usb_xhci_clock_gating(struct device *dev)
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);
pci_and_config32(dev, 0xa4, ~(1 << 13));
}
static void usb_xhci_init(struct device *dev)
{
u32 reg32;
u16 reg16;
u8 *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;
pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16);
pci_update_config16(dev, XHCI_PWR_CTL_STS, ~PWR_CTL_SET_MASK, PWR_CTL_SET_D0);
/* Enable clock gating first */
usb_xhci_clock_gating(dev);
@ -321,10 +302,7 @@ static void usb_xhci_init(struct device *dev)
write32(mem_base + 0x816c, reg32);
/* 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);
pci_update_config32(dev, 0xb0, ~((1 << 14) | (1 << 13)), 1 << 17);
}
reg32 = pci_read_config32(dev, 0x50);
@ -340,15 +318,10 @@ static void usb_xhci_init(struct device *dev)
pci_write_config32(dev, 0x50, reg32);
/* D20:F0:44h[31] = 1 (Access Control Bit) */
reg32 = pci_read_config32(dev, 0x44);
reg32 |= (1UL << 31);
pci_write_config32(dev, 0x44, reg32);
pci_or_config32(dev, 0x44, 1 << 31);
/* D20:F0:40h[31,23] = 10b (OC Configuration Done) */
reg32 = pci_read_config32(dev, 0x40);
reg32 &= ~(1 << 23); /* unsupported request */
reg32 |= (1UL << 31);
pci_write_config32(dev, 0x40, reg32);
pci_update_config32(dev, 0x40, ~(1 << 23), 1 << 31); /* unsupported request */
if (acpi_is_wakeup_s3()) {
/* Reset ports that are disabled or