aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aspm.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2009-05-12 23:14:58 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-18 16:57:25 -0400
commitb6c2e54d3ea27719b920faf15db92dfe0260f0d2 (patch)
tree407745d063fcae2b390515059e17cee5b2d3c13e /drivers/pci/pcie/aspm.c
parent80bfdbe370d56a1448c7078cd6d286b89241a72e (diff)
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: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r--drivers/pci/pcie/aspm.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index fdb3b7da7383..88351c242a48 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -26,9 +26,9 @@
26#endif 26#endif
27#define MODULE_PARAM_PREFIX "pcie_aspm." 27#define MODULE_PARAM_PREFIX "pcie_aspm."
28 28
29struct endpoint_state { 29struct aspm_latency {
30 unsigned int l0s_acceptable_latency; 30 u32 l0s; /* L0s latency (nsec) */
31 unsigned int l1_acceptable_latency; 31 u32 l1; /* L1 latency (nsec) */
32}; 32};
33 33
34struct pcie_link_state { 34struct pcie_link_state {
@@ -45,22 +45,19 @@ struct pcie_link_state {
45 u32 aspm_enabled:2; /* Enabled ASPM state */ 45 u32 aspm_enabled:2; /* Enabled ASPM state */
46 u32 aspm_default:2; /* Default ASPM state by BIOS */ 46 u32 aspm_default:2; /* Default ASPM state by BIOS */
47 47
48 /* upstream component */ 48 /* Latencies */
49 unsigned int l0s_upper_latency; 49 struct aspm_latency latency; /* Exit latency */
50 unsigned int l1_upper_latency; 50
51 /* downstream component */
52 unsigned int l0s_down_latency;
53 unsigned int l1_down_latency;
54 /* Clock PM state*/ 51 /* Clock PM state*/
55 unsigned int clk_pm_capable; 52 unsigned int clk_pm_capable;
56 unsigned int clk_pm_enabled; 53 unsigned int clk_pm_enabled;
57 unsigned int bios_clk_state; 54 unsigned int bios_clk_state;
58 55
59 /* 56 /*
60 * A pcie downstream port only has one slot under it, so at most there 57 * Endpoint acceptable latencies. A pcie downstream port only
61 * are 8 functions 58 * has one slot under it, so at most there are 8 functions.
62 */ 59 */
63 struct endpoint_state endpoints[8]; 60 struct aspm_latency acceptable[8];
64}; 61};
65 62
66static int aspm_disabled, aspm_force; 63static int aspm_disabled, aspm_force;
@@ -341,8 +338,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
341 /* upstream component states */ 338 /* upstream component states */
342 pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled); 339 pcie_aspm_get_cap_device(pdev, &support, &l0s, &l1, &enabled);
343 link_state->aspm_support = support; 340 link_state->aspm_support = support;
344 link_state->l0s_upper_latency = l0s; 341 link_state->latency.l0s = l0s;
345 link_state->l1_upper_latency = l1; 342 link_state->latency.l1 = l1;
346 link_state->aspm_enabled = enabled; 343 link_state->aspm_enabled = enabled;
347 344
348 /* downstream component states, all functions have the same setting */ 345 /* downstream component states, all functions have the same setting */
@@ -350,8 +347,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
350 bus_list); 347 bus_list);
351 pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled); 348 pcie_aspm_get_cap_device(child_dev, &support, &l0s, &l1, &enabled);
352 link_state->aspm_support &= support; 349 link_state->aspm_support &= support;
353 link_state->l0s_down_latency = l0s; 350 link_state->latency.l0s = max_t(u32, link_state->latency.l0s, l0s);
354 link_state->l1_down_latency = l1; 351 link_state->latency.l1 = max_t(u32, link_state->latency.l1, l1);
355 352
356 if (!link_state->aspm_support) 353 if (!link_state->aspm_support)
357 return; 354 return;
@@ -364,8 +361,8 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
364 int pos; 361 int pos;
365 u32 reg32; 362 u32 reg32;
366 unsigned int latency; 363 unsigned int latency;
367 struct endpoint_state *ep_state = 364 struct aspm_latency *acceptable =
368 &link_state->endpoints[PCI_FUNC(child_dev->devfn)]; 365 &link_state->acceptable[PCI_FUNC(child_dev->devfn)];
369 366
370 if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT && 367 if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
371 child_dev->pcie_type != PCI_EXP_TYPE_LEG_END) 368 child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)
@@ -375,11 +372,11 @@ static void pcie_aspm_cap_init(struct pci_dev *pdev)
375 pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32); 372 pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32);
376 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; 373 latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
377 latency = calc_L0S_latency(latency, 1); 374 latency = calc_L0S_latency(latency, 1);
378 ep_state->l0s_acceptable_latency = latency; 375 acceptable->l0s = latency;
379 if (link_state->aspm_support & PCIE_LINK_STATE_L1) { 376 if (link_state->aspm_support & PCIE_LINK_STATE_L1) {
380 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9; 377 latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
381 latency = calc_L1_latency(latency, 1); 378 latency = calc_L1_latency(latency, 1);
382 ep_state->l1_acceptable_latency = latency; 379 acceptable->l1 = latency;
383 } 380 }
384 } 381 }
385} 382}
@@ -388,16 +385,16 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
388 unsigned int state) 385 unsigned int state)
389{ 386{
390 struct pci_dev *parent_dev, *tmp_dev; 387 struct pci_dev *parent_dev, *tmp_dev;
391 unsigned int latency, l1_latency = 0; 388 unsigned int l1_latency = 0;
392 struct pcie_link_state *link_state; 389 struct pcie_link_state *link_state;
393 struct endpoint_state *ep_state; 390 struct aspm_latency *acceptable;
394 391
395 parent_dev = pdev->bus->self; 392 parent_dev = pdev->bus->self;
396 link_state = parent_dev->link_state; 393 link_state = parent_dev->link_state;
397 state &= link_state->aspm_support; 394 state &= link_state->aspm_support;
398 if (state == 0) 395 if (state == 0)
399 return 0; 396 return 0;
400 ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)]; 397 acceptable = &link_state->acceptable[PCI_FUNC(pdev->devfn)];
401 398
402 /* 399 /*
403 * Check latency for endpoint device. 400 * Check latency for endpoint device.
@@ -411,21 +408,14 @@ static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
411 while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { 408 while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
412 parent_dev = tmp_dev->bus->self; 409 parent_dev = tmp_dev->bus->self;
413 link_state = parent_dev->link_state; 410 link_state = parent_dev->link_state;
414 if (state & PCIE_LINK_STATE_L0S) { 411 if ((state & PCIE_LINK_STATE_L0S) &&
415 latency = max_t(unsigned int, 412 (link_state->latency.l0s > acceptable->l0s))
416 link_state->l0s_upper_latency, 413 state &= ~PCIE_LINK_STATE_L0S;
417 link_state->l0s_down_latency); 414
418 if (latency > ep_state->l0s_acceptable_latency) 415 if ((state & PCIE_LINK_STATE_L1) &&
419 state &= ~PCIE_LINK_STATE_L0S; 416 (link_state->latency.l1 + l1_latency > acceptable->l1))
420 } 417 state &= ~PCIE_LINK_STATE_L1;
421 if (state & PCIE_LINK_STATE_L1) { 418
422 latency = max_t(unsigned int,
423 link_state->l1_upper_latency,
424 link_state->l1_down_latency);
425 if (latency + l1_latency >
426 ep_state->l1_acceptable_latency)
427 state &= ~PCIE_LINK_STATE_L1;
428 }
429 if (!parent_dev->bus->self) /* parent_dev is a root port */ 419 if (!parent_dev->bus->self) /* parent_dev is a root port */
430 break; 420 break;
431 else { 421 else {