Commit f1c0ca29 authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Jesse Barnes

PCI ASPM: introduce disable flag

Introduce 'aspm_disable' flag to manage disabled ASPM state more
robust way.
Acked-by: default avatarShaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent fc87e919
...@@ -43,6 +43,7 @@ struct pcie_link_state { ...@@ -43,6 +43,7 @@ struct pcie_link_state {
u32 aspm_support:2; /* Supported ASPM state */ u32 aspm_support:2; /* Supported ASPM state */
u32 aspm_enabled:2; /* Enabled ASPM state */ u32 aspm_enabled:2; /* Enabled ASPM state */
u32 aspm_default:2; /* Default ASPM state by BIOS */ u32 aspm_default:2; /* Default ASPM state by BIOS */
u32 aspm_disable:2; /* Disabled ASPM state */
/* Clock PM state */ /* Clock PM state */
u32 clkpm_capable:1; /* Clock PM capable? */ u32 clkpm_capable:1; /* Clock PM capable? */
...@@ -322,10 +323,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) ...@@ -322,10 +323,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
struct pci_bus *linkbus = parent->subordinate; struct pci_bus *linkbus = parent->subordinate;
if (blacklist) { if (blacklist) {
/* Set support state to 0, so we will disable ASPM later */ /* Set enabled/disable so that we will disable ASPM later */
link->aspm_support = 0;
link->aspm_default = 0;
link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1; link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
link->aspm_disable = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
return; return;
} }
...@@ -348,6 +348,17 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) ...@@ -348,6 +348,17 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
/* Save default state */ /* Save default state */
link->aspm_default = link->aspm_enabled; link->aspm_default = link->aspm_enabled;
/*
* If the downstream component has pci bridge function, don't
* do ASPM for now.
*/
list_for_each_entry(child, &linkbus->devices, bus_list) {
if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
link->aspm_disable =
PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
break;
}
}
if (!link->aspm_support) if (!link->aspm_support)
return; return;
...@@ -458,14 +469,10 @@ static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state) ...@@ -458,14 +469,10 @@ static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
struct pci_dev *child, *parent = link->pdev; struct pci_dev *child, *parent = link->pdev;
struct pci_bus *linkbus = parent->subordinate; struct pci_bus *linkbus = parent->subordinate;
/* state &= ~link->aspm_disable;
* If the downstream component has pci bridge function, don't /* Nothing to do if the link is already in the requested state */
* do ASPM now. if (link->aspm_enabled == state)
*/ return;
list_for_each_entry(child, &linkbus->devices, bus_list) {
if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
return;
}
/* /*
* Spec 2.0 suggests all functions should be configured the * Spec 2.0 suggests all functions should be configured the
* same setting for ASPM. Enabling ASPM L1 should be done in * same setting for ASPM. Enabling ASPM L1 should be done in
...@@ -719,7 +726,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) ...@@ -719,7 +726,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
void pci_disable_link_state(struct pci_dev *pdev, int state) void pci_disable_link_state(struct pci_dev *pdev, int state)
{ {
struct pci_dev *parent = pdev->bus->self; struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link_state; struct pcie_link_state *link;
if (aspm_disabled || !pdev->is_pcie) if (aspm_disabled || !pdev->is_pcie)
return; return;
...@@ -731,12 +738,12 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) ...@@ -731,12 +738,12 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
down_read(&pci_bus_sem); down_read(&pci_bus_sem);
mutex_lock(&aspm_lock); mutex_lock(&aspm_lock);
link_state = parent->link_state; link = parent->link_state;
link_state->aspm_support &= ~state; link->aspm_disable |= state;
__pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled); __pcie_aspm_configure_link_state(link, link->aspm_enabled);
if (state & PCIE_LINK_STATE_CLKPM) { if (state & PCIE_LINK_STATE_CLKPM) {
link_state->clkpm_capable = 0; link->clkpm_capable = 0;
pcie_set_clkpm(link_state, 0); pcie_set_clkpm(link, 0);
} }
mutex_unlock(&aspm_lock); mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem); up_read(&pci_bus_sem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment