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

PCI ASPM: cleanup latency field in struct pcie_link_state

Clean up latency related data structures for ASPM.

- Introduce struct acpi_latency for exit latency and acceptable
  latency management. With this change, struct endpoint_state is no
  longer needed.

- We don't need to hold both upstream latency and downstream latency
  in the current implementation.
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 80bfdbe3
...@@ -26,9 +26,9 @@ ...@@ -26,9 +26,9 @@
#endif #endif
#define MODULE_PARAM_PREFIX "pcie_aspm." #define MODULE_PARAM_PREFIX "pcie_aspm."
struct endpoint_state { struct aspm_latency {
unsigned int l0s_acceptable_latency; u32 l0s; /* L0s latency (nsec) */
unsigned int l1_acceptable_latency; u32 l1; /* L1 latency (nsec) */
}; };
struct pcie_link_state { struct pcie_link_state {
...@@ -45,22 +45,19 @@ struct pcie_link_state { ...@@ -45,22 +45,19 @@ struct pcie_link_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 */
/* upstream component */ /* Latencies */
unsigned int l0s_upper_latency; struct aspm_latency latency; /* Exit latency */
unsigned int l1_upper_latency;
/* downstream component */
unsigned int l0s_down_latency;
unsigned int l1_down_latency;
/* Clock PM state*/ /* Clock PM state*/
unsigned int clk_pm_capable; unsigned int clk_pm_capable;
unsigned int clk_pm_enabled; unsigned int clk_pm_enabled;
unsigned int bios_clk_state; unsigned int bios_clk_state;
/* /*
* A pcie downstream port only has one slot under it, so at most there * Endpoint acceptable latencies. A pcie downstream port only
* are 8 functions * has one slot under it, so at most there are 8 functions.
*/ */
struct endpoint_state endpoints[8]; struct aspm_latency acceptable[8];
}; };
static int aspm_disabled, aspm_force; static int aspm_disabled, aspm_force;
...@@ -341,8 +338,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev) ...@@ -341,8 +338,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
/* upstream component states */ /* upstream component states */
pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled); pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled);
link_state->aspm_support = support; link_state->aspm_support = support;
link_state->l0s_upper_latency = l0s; link_state->latency.l0s = l0s;
link_state->l1_upper_latency = l1; link_state->latency.l1 = l1;
link_state->aspm_enabled = enabled; link_state->aspm_enabled = enabled;
/* downstream component states, all functions have the same setting */ /* downstream component states, all functions have the same setting */
...@@ -350,8 +347,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev) ...@@ -350,8 +347,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
bus_list); bus_list);
pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled); pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled);
link_state->aspm_support &= support; link_state->aspm_support &= support;
link_state->l0s_down_latency = l0s; link_state->latency.l0s = max_t(u32, link_state->latency.l0s, l0s);
link_state->l1_down_latency = l1; link_state->latency.l1 = max_t(u32, link_state->latency.l1, l1);
if (!link_state->aspm_support) if (!link_state->aspm_support)
return; return;
...@@ -364,8 +361,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev) ...@@ -364,8 +361,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
int pos; int pos;
u32 reg32; u32 reg32;
unsigned int latency; unsigned int latency;
struct endpoint_state *ep_state = struct aspm_latency *acceptable =
&link_state->endpoints[PCI_FUNC(child_dev->devfn)]; &link_state->acceptable[PCI_FUNC(child_dev->devfn)];
if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
child_dev->pcie_type != PCI_EXP_TYPE_LEG_END) child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)
...@@ -375,11 +372,11 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev) ...@@ -375,11 +372,11 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32); pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32);
latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
latency = calc_L0S_latency(latency, 1); latency = calc_L0S_latency(latency, 1);
ep_state->l0s_acceptable_latency = latency; acceptable->l0s = latency;
if (link_state->aspm_support & PCIE_LINK_STATE_L1) { if (link_state->aspm_support & PCIE_LINK_STATE_L1) {
latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9; latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
latency = calc_L1_latency(latency, 1); latency = calc_L1_latency(latency, 1);
ep_state->l1_acceptable_latency = latency; acceptable->l1 = latency;
} }
} }
} }
...@@ -388,16 +385,16 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, ...@@ -388,16 +385,16 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
unsigned int state) unsigned int state)
{ {
struct pci_dev *parent_dev, *tmp_dev; struct pci_dev *parent_dev, *tmp_dev;
unsigned int latency, l1_latency = 0; unsigned int l1_latency = 0;
struct pcie_link_state *link_state; struct pcie_link_state *link_state;
struct endpoint_state *ep_state; struct aspm_latency *acceptable;
parent_dev = pdev->bus->self; parent_dev = pdev->bus->self;
link_state = parent_dev->link_state; link_state = parent_dev->link_state;
state &= link_state->aspm_support; state &= link_state->aspm_support;
if (state == 0) if (state == 0)
return 0; return 0;
ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)]; acceptable = &link_state->acceptable[PCI_FUNC(pdev->devfn)];
/* /*
* Check latency for endpoint device. * Check latency for endpoint device.
...@@ -411,21 +408,14 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev, ...@@ -411,21 +408,14 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
parent_dev = tmp_dev->bus->self; parent_dev = tmp_dev->bus->self;
link_state = parent_dev->link_state; link_state = parent_dev->link_state;
if (state & PCIE_LINK_STATE_L0S) { if ((state & PCIE_LINK_STATE_L0S) &&
latency = max_t(unsigned int, (link_state->latency.l0s > acceptable->l0s))
link_state->l0s_upper_latency,
link_state->l0s_down_latency);
if (latency > ep_state->l0s_acceptable_latency)
state &= ~PCIE_LINK_STATE_L0S; state &= ~PCIE_LINK_STATE_L0S;
}
if (state & PCIE_LINK_STATE_L1) { if ((state & PCIE_LINK_STATE_L1) &&
latency = max_t(unsigned int, (link_state->latency.l1 + l1_latency > acceptable->l1))
link_state->l1_upper_latency,
link_state->l1_down_latency);
if (latency + l1_latency >
ep_state->l1_acceptable_latency)
state &= ~PCIE_LINK_STATE_L1; state &= ~PCIE_LINK_STATE_L1;
}
if (!parent_dev->bus->self) /* parent_dev is a root port */ if (!parent_dev->bus->self) /* parent_dev is a root port */
break; break;
else { else {
......
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