aspm.c 25.7 KB
Newer Older
S
Shaohua Li 已提交
1 2
/*
 * File:	drivers/pci/pcie/aspm.c
3
 * Enabling PCIe link L0s/L1 state and Clock Power Management
S
Shaohua Li 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * Copyright (C) 2007 Intel
 * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com)
 * Copyright (C) Shaohua Li (shaohua.li@intel.com)
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/slab.h>
19
#include <linux/jiffies.h>
20
#include <linux/delay.h>
S
Shaohua Li 已提交
21 22 23 24 25 26 27 28
#include <linux/pci-aspm.h>
#include "../pci.h"

#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX "pcie_aspm."

29 30 31 32 33 34 35
/* Note: those are not register definitions */
#define ASPM_STATE_L0S_UP	(1)	/* Upstream direction L0s state */
#define ASPM_STATE_L0S_DW	(2)	/* Downstream direction L0s state */
#define ASPM_STATE_L1		(4)	/* L1 state */
#define ASPM_STATE_L0S		(ASPM_STATE_L0S_UP | ASPM_STATE_L0S_DW)
#define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1)

36 37 38
struct aspm_latency {
	u32 l0s;			/* L0s latency (nsec) */
	u32 l1;				/* L1 latency (nsec) */
S
Shaohua Li 已提交
39 40 41
};

struct pcie_link_state {
42
	struct pci_dev *pdev;		/* Upstream component of the Link */
43
	struct pcie_link_state *root;	/* pointer to the root port link */
44 45 46 47
	struct pcie_link_state *parent;	/* pointer to the parent Link state */
	struct list_head sibling;	/* node in link_list */
	struct list_head children;	/* list of child link states */
	struct list_head link;		/* node in parent's children list */
S
Shaohua Li 已提交
48 49

	/* ASPM state */
50 51 52 53 54
	u32 aspm_support:3;		/* Supported ASPM state */
	u32 aspm_enabled:3;		/* Enabled ASPM state */
	u32 aspm_capable:3;		/* Capable ASPM state with latency */
	u32 aspm_default:3;		/* Default ASPM state by BIOS */
	u32 aspm_disable:3;		/* Disabled ASPM state */
55

56 57 58 59 60
	/* Clock PM state */
	u32 clkpm_capable:1;		/* Clock PM capable? */
	u32 clkpm_enabled:1;		/* Current Clock PM state */
	u32 clkpm_default:1;		/* Default Clock PM state by BIOS */

61 62 63
	/* Exit latencies */
	struct aspm_latency latency_up;	/* Upstream direction exit latency */
	struct aspm_latency latency_dw;	/* Downstream direction exit latency */
S
Shaohua Li 已提交
64
	/*
65 66
	 * Endpoint acceptable latencies. A pcie downstream port only
	 * has one slot under it, so at most there are 8 functions.
S
Shaohua Li 已提交
67
	 */
68
	struct aspm_latency acceptable[8];
S
Shaohua Li 已提交
69 70
};

71
static int aspm_disabled, aspm_force, aspm_clear_state;
72
static bool aspm_support_enabled = true;
S
Shaohua Li 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85
static DEFINE_MUTEX(aspm_lock);
static LIST_HEAD(link_list);

#define POLICY_DEFAULT 0	/* BIOS default setting */
#define POLICY_PERFORMANCE 1	/* high performance */
#define POLICY_POWERSAVE 2	/* high power saving */
static int aspm_policy;
static const char *policy_str[] = {
	[POLICY_DEFAULT] = "default",
	[POLICY_PERFORMANCE] = "performance",
	[POLICY_POWERSAVE] = "powersave"
};

86 87
#define LINK_RETRAIN_TIMEOUT HZ

88
static int policy_to_aspm_state(struct pcie_link_state *link)
S
Shaohua Li 已提交
89 90 91 92 93 94 95
{
	switch (aspm_policy) {
	case POLICY_PERFORMANCE:
		/* Disable ASPM and Clock PM */
		return 0;
	case POLICY_POWERSAVE:
		/* Enable ASPM L0s/L1 */
96
		return ASPM_STATE_ALL;
S
Shaohua Li 已提交
97
	case POLICY_DEFAULT:
98
		return link->aspm_default;
S
Shaohua Li 已提交
99 100 101 102
	}
	return 0;
}

103
static int policy_to_clkpm_state(struct pcie_link_state *link)
S
Shaohua Li 已提交
104 105 106 107 108 109 110 111 112
{
	switch (aspm_policy) {
	case POLICY_PERFORMANCE:
		/* Disable ASPM and Clock PM */
		return 0;
	case POLICY_POWERSAVE:
		/* Disable Clock PM */
		return 1;
	case POLICY_DEFAULT:
113
		return link->clkpm_default;
S
Shaohua Li 已提交
114 115 116 117
	}
	return 0;
}

K
Kenji Kaneshige 已提交
118
static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
S
Shaohua Li 已提交
119 120 121
{
	int pos;
	u16 reg16;
122 123
	struct pci_dev *child;
	struct pci_bus *linkbus = link->pdev->subordinate;
S
Shaohua Li 已提交
124

125
	list_for_each_entry(child, &linkbus->devices, bus_list) {
K
Kenji Kaneshige 已提交
126
		pos = pci_pcie_cap(child);
S
Shaohua Li 已提交
127 128
		if (!pos)
			return;
129
		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
S
Shaohua Li 已提交
130 131 132 133
		if (enable)
			reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
		else
			reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
134
		pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16);
S
Shaohua Li 已提交
135
	}
136
	link->clkpm_enabled = !!enable;
S
Shaohua Li 已提交
137 138
}

K
Kenji Kaneshige 已提交
139 140 141 142
static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
{
	/* Don't enable Clock PM if the link is not Clock PM capable */
	if (!link->clkpm_capable && enable)
143
		enable = 0;
K
Kenji Kaneshige 已提交
144 145 146 147 148 149
	/* Need nothing if the specified equals to current state */
	if (link->clkpm_enabled == enable)
		return;
	pcie_set_clkpm_nocheck(link, enable);
}

150
static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
S
Shaohua Li 已提交
151
{
152
	int pos, capable = 1, enabled = 1;
S
Shaohua Li 已提交
153 154
	u32 reg32;
	u16 reg16;
155 156
	struct pci_dev *child;
	struct pci_bus *linkbus = link->pdev->subordinate;
S
Shaohua Li 已提交
157 158

	/* All functions should have the same cap and state, take the worst */
159
	list_for_each_entry(child, &linkbus->devices, bus_list) {
K
Kenji Kaneshige 已提交
160
		pos = pci_pcie_cap(child);
S
Shaohua Li 已提交
161 162
		if (!pos)
			return;
163
		pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
S
Shaohua Li 已提交
164 165 166 167 168
		if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
			capable = 0;
			enabled = 0;
			break;
		}
169
		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
S
Shaohua Li 已提交
170 171 172
		if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
			enabled = 0;
	}
173 174
	link->clkpm_enabled = enabled;
	link->clkpm_default = enabled;
175
	link->clkpm_capable = (blacklist) ? 0 : capable;
176 177
}

S
Shaohua Li 已提交
178 179 180 181 182
/*
 * pcie_aspm_configure_common_clock: check if the 2 ends of a link
 *   could use common clock. If they are, configure them to use the
 *   common clock. That will reduce the ASPM state exit latency.
 */
183
static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
S
Shaohua Li 已提交
184
{
185 186
	int ppos, cpos, same_clock = 1;
	u16 reg16, parent_reg, child_reg[8];
187
	unsigned long start_jiffies;
188 189
	struct pci_dev *child, *parent = link->pdev;
	struct pci_bus *linkbus = parent->subordinate;
S
Shaohua Li 已提交
190
	/*
191
	 * All functions of a slot should have the same Slot Clock
S
Shaohua Li 已提交
192
	 * Configuration, so just check one function
193 194
	 */
	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
K
Kenji Kaneshige 已提交
195
	BUG_ON(!pci_is_pcie(child));
S
Shaohua Li 已提交
196 197

	/* Check downstream component if bit Slot Clock Configuration is 1 */
K
Kenji Kaneshige 已提交
198
	cpos = pci_pcie_cap(child);
199
	pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
S
Shaohua Li 已提交
200 201 202 203
	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
		same_clock = 0;

	/* Check upstream component if bit Slot Clock Configuration is 1 */
K
Kenji Kaneshige 已提交
204
	ppos = pci_pcie_cap(parent);
205
	pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
S
Shaohua Li 已提交
206 207 208 209
	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
		same_clock = 0;

	/* Configure downstream component, all functions */
210
	list_for_each_entry(child, &linkbus->devices, bus_list) {
K
Kenji Kaneshige 已提交
211
		cpos = pci_pcie_cap(child);
212 213
		pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
		child_reg[PCI_FUNC(child->devfn)] = reg16;
S
Shaohua Li 已提交
214 215 216 217
		if (same_clock)
			reg16 |= PCI_EXP_LNKCTL_CCC;
		else
			reg16 &= ~PCI_EXP_LNKCTL_CCC;
218
		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
S
Shaohua Li 已提交
219 220 221
	}

	/* Configure upstream component */
222
	pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, &reg16);
223
	parent_reg = reg16;
S
Shaohua Li 已提交
224 225 226 227
	if (same_clock)
		reg16 |= PCI_EXP_LNKCTL_CCC;
	else
		reg16 &= ~PCI_EXP_LNKCTL_CCC;
228
	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
S
Shaohua Li 已提交
229

230
	/* Retrain link */
S
Shaohua Li 已提交
231
	reg16 |= PCI_EXP_LNKCTL_RL;
232
	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
S
Shaohua Li 已提交
233

234
	/* Wait for link training end. Break out after waiting for timeout */
235
	start_jiffies = jiffies;
236
	for (;;) {
237
		pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
S
Shaohua Li 已提交
238 239
		if (!(reg16 & PCI_EXP_LNKSTA_LT))
			break;
240 241 242
		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
			break;
		msleep(1);
S
Shaohua Li 已提交
243
	}
244 245 246 247 248 249 250
	if (!(reg16 & PCI_EXP_LNKSTA_LT))
		return;

	/* Training failed. Restore common clock configurations */
	dev_printk(KERN_ERR, &parent->dev,
		   "ASPM: Could not configure common clock\n");
	list_for_each_entry(child, &linkbus->devices, bus_list) {
K
Kenji Kaneshige 已提交
251
		cpos = pci_pcie_cap(child);
252 253
		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
				      child_reg[PCI_FUNC(child->devfn)]);
254
	}
255
	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg);
S
Shaohua Li 已提交
256 257
}

258 259
/* Convert L0s latency encoding to ns */
static u32 calc_l0s_latency(u32 encoding)
S
Shaohua Li 已提交
260
{
261 262 263 264
	if (encoding == 0x7)
		return (5 * 1000);	/* > 4us */
	return (64 << encoding);
}
S
Shaohua Li 已提交
265

266 267 268 269 270 271
/* Convert L0s acceptable latency encoding to ns */
static u32 calc_l0s_acceptable(u32 encoding)
{
	if (encoding == 0x7)
		return -1U;
	return (64 << encoding);
S
Shaohua Li 已提交
272 273
}

274 275
/* Convert L1 latency encoding to ns */
static u32 calc_l1_latency(u32 encoding)
S
Shaohua Li 已提交
276
{
277 278 279 280
	if (encoding == 0x7)
		return (65 * 1000);	/* > 64us */
	return (1000 << encoding);
}
S
Shaohua Li 已提交
281

282 283 284 285 286 287
/* Convert L1 acceptable latency encoding to ns */
static u32 calc_l1_acceptable(u32 encoding)
{
	if (encoding == 0x7)
		return -1U;
	return (1000 << encoding);
S
Shaohua Li 已提交
288 289
}

290 291 292 293 294 295 296 297 298
struct aspm_register_info {
	u32 support:2;
	u32 enabled:2;
	u32 latency_encoding_l0s;
	u32 latency_encoding_l1;
};

static void pcie_get_aspm_reg(struct pci_dev *pdev,
			      struct aspm_register_info *info)
S
Shaohua Li 已提交
299 300 301
{
	int pos;
	u16 reg16;
302
	u32 reg32;
S
Shaohua Li 已提交
303

K
Kenji Kaneshige 已提交
304
	pos = pci_pcie_cap(pdev);
S
Shaohua Li 已提交
305
	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
306 307 308
	info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
	info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
	info->latency_encoding_l1  = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
S
Shaohua Li 已提交
309
	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
310
	info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC;
S
Shaohua Li 已提交
311 312
}

313 314
static void pcie_aspm_check_latency(struct pci_dev *endpoint)
{
315
	u32 latency, l1_switch_latency = 0;
316 317 318 319 320 321 322 323 324 325 326 327
	struct aspm_latency *acceptable;
	struct pcie_link_state *link;

	/* Device not in D0 doesn't need latency check */
	if ((endpoint->current_state != PCI_D0) &&
	    (endpoint->current_state != PCI_UNKNOWN))
		return;

	link = endpoint->bus->self->link_state;
	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];

	while (link) {
328 329 330 331 332 333 334 335 336
		/* Check upstream direction L0s latency */
		if ((link->aspm_capable & ASPM_STATE_L0S_UP) &&
		    (link->latency_up.l0s > acceptable->l0s))
			link->aspm_capable &= ~ASPM_STATE_L0S_UP;

		/* Check downstream direction L0s latency */
		if ((link->aspm_capable & ASPM_STATE_L0S_DW) &&
		    (link->latency_dw.l0s > acceptable->l0s))
			link->aspm_capable &= ~ASPM_STATE_L0S_DW;
337 338 339 340 341
		/*
		 * Check L1 latency.
		 * Every switch on the path to root complex need 1
		 * more microsecond for L1. Spec doesn't mention L0s.
		 */
342 343 344 345
		latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1);
		if ((link->aspm_capable & ASPM_STATE_L1) &&
		    (latency + l1_switch_latency > acceptable->l1))
			link->aspm_capable &= ~ASPM_STATE_L1;
346 347 348 349 350 351
		l1_switch_latency += 1000;

		link = link->parent;
	}
}

352
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
S
Shaohua Li 已提交
353
{
354 355
	struct pci_dev *child, *parent = link->pdev;
	struct pci_bus *linkbus = parent->subordinate;
356
	struct aspm_register_info upreg, dwreg;
S
Shaohua Li 已提交
357

358
	if (blacklist) {
359
		/* Set enabled/disable so that we will disable ASPM later */
360 361
		link->aspm_enabled = ASPM_STATE_ALL;
		link->aspm_disable = ASPM_STATE_ALL;
362 363 364 365 366 367
		return;
	}

	/* Configure common clock before checking latencies */
	pcie_aspm_configure_common_clock(link);

368 369
	/* Get upstream/downstream components' register state */
	pcie_get_aspm_reg(parent, &upreg);
370
	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
	pcie_get_aspm_reg(child, &dwreg);

	/*
	 * Setup L0s state
	 *
	 * Note that we must not enable L0s in either direction on a
	 * given link unless components on both sides of the link each
	 * support L0s.
	 */
	if (dwreg.support & upreg.support & PCIE_LINK_STATE_L0S)
		link->aspm_support |= ASPM_STATE_L0S;
	if (dwreg.enabled & PCIE_LINK_STATE_L0S)
		link->aspm_enabled |= ASPM_STATE_L0S_UP;
	if (upreg.enabled & PCIE_LINK_STATE_L0S)
		link->aspm_enabled |= ASPM_STATE_L0S_DW;
	link->latency_up.l0s = calc_l0s_latency(upreg.latency_encoding_l0s);
	link->latency_dw.l0s = calc_l0s_latency(dwreg.latency_encoding_l0s);

	/* Setup L1 state */
	if (upreg.support & dwreg.support & PCIE_LINK_STATE_L1)
		link->aspm_support |= ASPM_STATE_L1;
	if (upreg.enabled & dwreg.enabled & PCIE_LINK_STATE_L1)
		link->aspm_enabled |= ASPM_STATE_L1;
	link->latency_up.l1 = calc_l1_latency(upreg.latency_encoding_l1);
	link->latency_dw.l1 = calc_l1_latency(dwreg.latency_encoding_l1);
396

397 398
	/* Save default state */
	link->aspm_default = link->aspm_enabled;
399 400 401

	/* Setup initial capable state. Will be updated later */
	link->aspm_capable = link->aspm_support;
402 403 404 405 406 407
	/*
	 * 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) {
408
			link->aspm_disable = ASPM_STATE_ALL;
409 410 411
			break;
		}
	}
412

413
	/* Get and check endpoint acceptable latencies */
414
	list_for_each_entry(child, &linkbus->devices, bus_list) {
S
Shaohua Li 已提交
415
		int pos;
416
		u32 reg32, encoding;
417
		struct aspm_latency *acceptable =
418
			&link->acceptable[PCI_FUNC(child->devfn)];
S
Shaohua Li 已提交
419

420 421
		if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
		    child->pcie_type != PCI_EXP_TYPE_LEG_END)
S
Shaohua Li 已提交
422 423
			continue;

K
Kenji Kaneshige 已提交
424
		pos = pci_pcie_cap(child);
425
		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
426
		/* Calculate endpoint L0s acceptable latency */
427 428
		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
		acceptable->l0s = calc_l0s_acceptable(encoding);
429 430 431 432 433
		/* Calculate endpoint L1 acceptable latency */
		encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
		acceptable->l1 = calc_l1_acceptable(encoding);

		pcie_aspm_check_latency(child);
S
Shaohua Li 已提交
434 435 436
	}
}

437
static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
S
Shaohua Li 已提交
438 439
{
	u16 reg16;
K
Kenji Kaneshige 已提交
440
	int pos = pci_pcie_cap(pdev);
S
Shaohua Li 已提交
441 442 443

	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
	reg16 &= ~0x3;
444
	reg16 |= val;
S
Shaohua Li 已提交
445 446 447
	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
}

448
static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
S
Shaohua Li 已提交
449
{
450
	u32 upstream = 0, dwstream = 0;
451 452
	struct pci_dev *child, *parent = link->pdev;
	struct pci_bus *linkbus = parent->subordinate;
S
Shaohua Li 已提交
453

454
	/* Nothing to do if the link is already in the requested state */
455
	state &= (link->aspm_capable & ~link->aspm_disable);
456 457
	if (link->aspm_enabled == state)
		return;
458 459 460 461 462 463 464 465 466
	/* Convert ASPM state to upstream/downstream ASPM register state */
	if (state & ASPM_STATE_L0S_UP)
		dwstream |= PCIE_LINK_STATE_L0S;
	if (state & ASPM_STATE_L0S_DW)
		upstream |= PCIE_LINK_STATE_L0S;
	if (state & ASPM_STATE_L1) {
		upstream |= PCIE_LINK_STATE_L1;
		dwstream |= PCIE_LINK_STATE_L1;
	}
S
Shaohua Li 已提交
467
	/*
468 469 470 471
	 * Spec 2.0 suggests all functions should be configured the
	 * same setting for ASPM. Enabling ASPM L1 should be done in
	 * upstream component first and then downstream, and vice
	 * versa for disabling ASPM L1. Spec doesn't mention L0S.
S
Shaohua Li 已提交
472
	 */
473 474
	if (state & ASPM_STATE_L1)
		pcie_config_aspm_dev(parent, upstream);
475
	list_for_each_entry(child, &linkbus->devices, bus_list)
476 477 478
		pcie_config_aspm_dev(child, dwstream);
	if (!(state & ASPM_STATE_L1))
		pcie_config_aspm_dev(parent, upstream);
S
Shaohua Li 已提交
479

480
	link->aspm_enabled = state;
S
Shaohua Li 已提交
481 482
}

483
static void pcie_config_aspm_path(struct pcie_link_state *link)
S
Shaohua Li 已提交
484
{
485 486 487
	while (link) {
		pcie_config_aspm_link(link, policy_to_aspm_state(link));
		link = link->parent;
488
	}
S
Shaohua Li 已提交
489 490
}

491
static void free_link_state(struct pcie_link_state *link)
S
Shaohua Li 已提交
492
{
493 494
	link->pdev->link_state = NULL;
	kfree(link);
S
Shaohua Li 已提交
495 496
}

497 498
static int pcie_aspm_sanity_check(struct pci_dev *pdev)
{
499 500
	struct pci_dev *child;
	int pos;
501
	u32 reg32;
502 503 504 505

	if (aspm_clear_state)
		return -EINVAL;

506
	/*
507
	 * Some functions in a slot might not all be PCIe functions,
508
	 * very strange. Disable ASPM for the whole slot
509
	 */
510
	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
K
Kenji Kaneshige 已提交
511
		pos = pci_pcie_cap(child);
512
		if (!pos)
513
			return -EINVAL;
514 515 516 517
		/*
		 * Disable ASPM for pre-1.1 PCIe device, we follow MS to use
		 * RBER bit to determine if a function is 1.1 version device
		 */
518
		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
S
Sitsofe Wheeler 已提交
519
		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
520
			dev_printk(KERN_INFO, &child->dev, "disabling ASPM"
521 522
				" on pre-1.1 PCIe device.  You can enable it"
				" with 'pcie_aspm=force'\n");
523 524
			return -EINVAL;
		}
525 526 527 528
	}
	return 0;
}

529
static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
{
	struct pcie_link_state *link;

	link = kzalloc(sizeof(*link), GFP_KERNEL);
	if (!link)
		return NULL;
	INIT_LIST_HEAD(&link->sibling);
	INIT_LIST_HEAD(&link->children);
	INIT_LIST_HEAD(&link->link);
	link->pdev = pdev;
	if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
		struct pcie_link_state *parent;
		parent = pdev->bus->parent->self->link_state;
		if (!parent) {
			kfree(link);
			return NULL;
		}
		link->parent = parent;
		list_add(&link->link, &parent->children);
	}
550 551 552 553 554 555
	/* Setup a pointer to the root port link */
	if (!link->parent)
		link->root = link;
	else
		link->root = link->parent->root;

556 557 558 559 560
	list_add(&link->sibling, &link_list);
	pdev->link_state = link;
	return link;
}

S
Shaohua Li 已提交
561 562 563 564 565 566 567
/*
 * pcie_aspm_init_link_state: Initiate PCI express link state.
 * It is called after the pcie and its children devices are scaned.
 * @pdev: the root port or switch downstream port
 */
void pcie_aspm_init_link_state(struct pci_dev *pdev)
{
568
	struct pcie_link_state *link;
569
	int blacklist = !!pcie_aspm_sanity_check(pdev);
S
Shaohua Li 已提交
570

571
	if (!pci_is_pcie(pdev) || pdev->link_state)
S
Shaohua Li 已提交
572 573
		return;
	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
574
	    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
S
Shaohua Li 已提交
575
		return;
576

577 578 579
	if (aspm_disabled && !aspm_clear_state)
		return;

580 581
	/* VIA has a strange chipset, root port is under a bridge */
	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
582
	    pdev->bus->self)
583
		return;
584

S
Shaohua Li 已提交
585 586 587 588 589
	down_read(&pci_bus_sem);
	if (list_empty(&pdev->subordinate->devices))
		goto out;

	mutex_lock(&aspm_lock);
590
	link = alloc_pcie_link_state(pdev);
591 592 593
	if (!link)
		goto unlock;
	/*
594 595 596
	 * Setup initial ASPM state. Note that we need to configure
	 * upstream links also because capable state of them can be
	 * update through pcie_aspm_cap_init().
597
	 */
598
	pcie_aspm_cap_init(link, blacklist);
S
Shaohua Li 已提交
599

600
	/* Setup initial Clock PM state */
601
	pcie_clkpm_cap_init(link, blacklist);
602 603 604 605 606 607 608 609 610 611 612 613 614 615

	/*
	 * At this stage drivers haven't had an opportunity to change the
	 * link policy setting. Enabling ASPM on broken hardware can cripple
	 * it even before the driver has had a chance to disable ASPM, so
	 * default to a safe level right now. If we're enabling ASPM beyond
	 * the BIOS's expectation, we'll do so once pci_enable_device() is
	 * called.
	 */
	if (aspm_policy != POLICY_POWERSAVE) {
		pcie_config_aspm_path(link);
		pcie_set_clkpm(link, policy_to_clkpm_state(link));
	}

616
unlock:
S
Shaohua Li 已提交
617 618 619 620 621
	mutex_unlock(&aspm_lock);
out:
	up_read(&pci_bus_sem);
}

622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
/* Recheck latencies and update aspm_capable for links under the root */
static void pcie_update_aspm_capable(struct pcie_link_state *root)
{
	struct pcie_link_state *link;
	BUG_ON(root->parent);
	list_for_each_entry(link, &link_list, sibling) {
		if (link->root != root)
			continue;
		link->aspm_capable = link->aspm_support;
	}
	list_for_each_entry(link, &link_list, sibling) {
		struct pci_dev *child;
		struct pci_bus *linkbus = link->pdev->subordinate;
		if (link->root != root)
			continue;
		list_for_each_entry(child, &linkbus->devices, bus_list) {
			if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT) &&
			    (child->pcie_type != PCI_EXP_TYPE_LEG_END))
				continue;
			pcie_aspm_check_latency(child);
		}
	}
}

S
Shaohua Li 已提交
646 647 648 649
/* @pdev: the endpoint device */
void pcie_aspm_exit_link_state(struct pci_dev *pdev)
{
	struct pci_dev *parent = pdev->bus->self;
650
	struct pcie_link_state *link, *root, *parent_link;
S
Shaohua Li 已提交
651

652
	if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
K
Kenji Kaneshige 已提交
653
	    !parent || !parent->link_state)
S
Shaohua Li 已提交
654
		return;
655 656
	if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
	    (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
S
Shaohua Li 已提交
657
		return;
658

S
Shaohua Li 已提交
659 660 661 662
	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
	/*
	 * All PCIe functions are in one slot, remove one function will remove
663
	 * the whole slot, so just wait until we are the last function left.
S
Shaohua Li 已提交
664
	 */
665
	if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
S
Shaohua Li 已提交
666 667
		goto out;

668
	link = parent->link_state;
669
	root = link->root;
670
	parent_link = link->parent;
671

S
Shaohua Li 已提交
672
	/* All functions are removed, so just disable ASPM for the link */
673
	pcie_config_aspm_link(link, 0);
674 675
	list_del(&link->sibling);
	list_del(&link->link);
S
Shaohua Li 已提交
676
	/* Clock PM is for endpoint device */
677
	free_link_state(link);
678 679

	/* Recheck latencies and configure upstream links */
680 681 682 683
	if (parent_link) {
		pcie_update_aspm_capable(root);
		pcie_config_aspm_path(parent_link);
	}
S
Shaohua Li 已提交
684 685 686 687 688 689 690 691
out:
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);
}

/* @pdev: the root port or switch downstream port */
void pcie_aspm_pm_state_change(struct pci_dev *pdev)
{
692
	struct pcie_link_state *link = pdev->link_state;
S
Shaohua Li 已提交
693

K
Kenji Kaneshige 已提交
694
	if (aspm_disabled || !pci_is_pcie(pdev) || !link)
S
Shaohua Li 已提交
695
		return;
696 697
	if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
	    (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
S
Shaohua Li 已提交
698 699
		return;
	/*
700 701
	 * Devices changed PM state, we should recheck if latency
	 * meets all functions' requirement
S
Shaohua Li 已提交
702
	 */
703 704 705
	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
	pcie_update_aspm_capable(link->root);
706
	pcie_config_aspm_path(link);
707 708
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);
S
Shaohua Li 已提交
709 710 711 712 713 714 715 716 717
}

/*
 * pci_disable_link_state - disable pci device's link state, so the link will
 * never enter specific states
 */
void pci_disable_link_state(struct pci_dev *pdev, int state)
{
	struct pci_dev *parent = pdev->bus->self;
718
	struct pcie_link_state *link;
S
Shaohua Li 已提交
719

K
Kenji Kaneshige 已提交
720
	if (aspm_disabled || !pci_is_pcie(pdev))
S
Shaohua Li 已提交
721 722 723 724 725 726 727 728 729
		return;
	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
	    pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
		parent = pdev;
	if (!parent || !parent->link_state)
		return;

	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
730
	link = parent->link_state;
731 732 733 734
	if (state & PCIE_LINK_STATE_L0S)
		link->aspm_disable |= ASPM_STATE_L0S;
	if (state & PCIE_LINK_STATE_L1)
		link->aspm_disable |= ASPM_STATE_L1;
735 736
	pcie_config_aspm_link(link, policy_to_aspm_state(link));

K
Kenji Kaneshige 已提交
737
	if (state & PCIE_LINK_STATE_CLKPM) {
738 739
		link->clkpm_capable = 0;
		pcie_set_clkpm(link, 0);
K
Kenji Kaneshige 已提交
740
	}
S
Shaohua Li 已提交
741 742 743 744 745 746 747 748
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);
}
EXPORT_SYMBOL(pci_disable_link_state);

static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
{
	int i;
749
	struct pcie_link_state *link;
S
Shaohua Li 已提交
750 751 752 753 754 755 756 757 758 759 760 761

	for (i = 0; i < ARRAY_SIZE(policy_str); i++)
		if (!strncmp(val, policy_str[i], strlen(policy_str[i])))
			break;
	if (i >= ARRAY_SIZE(policy_str))
		return -EINVAL;
	if (i == aspm_policy)
		return 0;

	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
	aspm_policy = i;
762 763 764
	list_for_each_entry(link, &link_list, sibling) {
		pcie_config_aspm_link(link, policy_to_aspm_state(link));
		pcie_set_clkpm(link, policy_to_clkpm_state(link));
S
Shaohua Li 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
	}
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);
	return 0;
}

static int pcie_aspm_get_policy(char *buffer, struct kernel_param *kp)
{
	int i, cnt = 0;
	for (i = 0; i < ARRAY_SIZE(policy_str); i++)
		if (i == aspm_policy)
			cnt += sprintf(buffer + cnt, "[%s] ", policy_str[i]);
		else
			cnt += sprintf(buffer + cnt, "%s ", policy_str[i]);
	return cnt;
}

module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy,
	NULL, 0644);

#ifdef CONFIG_PCIEASPM_DEBUG
static ssize_t link_state_show(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct pci_dev *pci_device = to_pci_dev(dev);
	struct pcie_link_state *link_state = pci_device->link_state;

793
	return sprintf(buf, "%d\n", link_state->aspm_enabled);
S
Shaohua Li 已提交
794 795 796 797 798 799 800
}

static ssize_t link_state_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t n)
{
801
	struct pci_dev *pdev = to_pci_dev(dev);
802
	struct pcie_link_state *link, *root = pdev->link_state->root;
803
	u32 val = buf[0] - '0', state = 0;
S
Shaohua Li 已提交
804

805
	if (n < 1 || val > 3)
S
Shaohua Li 已提交
806 807
		return -EINVAL;

808 809 810 811 812 813
	/* Convert requested state to ASPM state */
	if (val & PCIE_LINK_STATE_L0S)
		state |= ASPM_STATE_L0S;
	if (val & PCIE_LINK_STATE_L1)
		state |= ASPM_STATE_L1;

814 815 816 817 818 819 820 821 822 823
	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
	list_for_each_entry(link, &link_list, sibling) {
		if (link->root != root)
			continue;
		pcie_config_aspm_link(link, state);
	}
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);
	return n;
S
Shaohua Li 已提交
824 825 826 827 828 829 830 831 832
}

static ssize_t clk_ctl_show(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct pci_dev *pci_device = to_pci_dev(dev);
	struct pcie_link_state *link_state = pci_device->link_state;

833
	return sprintf(buf, "%d\n", link_state->clkpm_enabled);
S
Shaohua Li 已提交
834 835 836 837 838 839 840
}

static ssize_t clk_ctl_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf,
		size_t n)
{
K
Kenji Kaneshige 已提交
841
	struct pci_dev *pdev = to_pci_dev(dev);
S
Shaohua Li 已提交
842 843 844 845 846 847 848 849
	int state;

	if (n < 1)
		return -EINVAL;
	state = buf[0]-'0';

	down_read(&pci_bus_sem);
	mutex_lock(&aspm_lock);
K
Kenji Kaneshige 已提交
850
	pcie_set_clkpm_nocheck(pdev->link_state, !!state);
S
Shaohua Li 已提交
851 852 853 854 855 856 857 858 859 860 861 862 863 864
	mutex_unlock(&aspm_lock);
	up_read(&pci_bus_sem);

	return n;
}

static DEVICE_ATTR(link_state, 0644, link_state_show, link_state_store);
static DEVICE_ATTR(clk_ctl, 0644, clk_ctl_show, clk_ctl_store);

static char power_group[] = "power";
void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
{
	struct pcie_link_state *link_state = pdev->link_state;

K
Kenji Kaneshige 已提交
865 866 867
	if (!pci_is_pcie(pdev) ||
	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
S
Shaohua Li 已提交
868 869
		return;

870
	if (link_state->aspm_support)
S
Shaohua Li 已提交
871 872
		sysfs_add_file_to_group(&pdev->dev.kobj,
			&dev_attr_link_state.attr, power_group);
873
	if (link_state->clkpm_capable)
S
Shaohua Li 已提交
874 875 876 877 878 879 880 881
		sysfs_add_file_to_group(&pdev->dev.kobj,
			&dev_attr_clk_ctl.attr, power_group);
}

void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
{
	struct pcie_link_state *link_state = pdev->link_state;

K
Kenji Kaneshige 已提交
882 883 884
	if (!pci_is_pcie(pdev) ||
	    (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
	     pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
S
Shaohua Li 已提交
885 886
		return;

887
	if (link_state->aspm_support)
S
Shaohua Li 已提交
888 889
		sysfs_remove_file_from_group(&pdev->dev.kobj,
			&dev_attr_link_state.attr, power_group);
890
	if (link_state->clkpm_capable)
S
Shaohua Li 已提交
891 892 893 894 895 896 897
		sysfs_remove_file_from_group(&pdev->dev.kobj,
			&dev_attr_clk_ctl.attr, power_group);
}
#endif

static int __init pcie_aspm_disable(char *str)
{
898 899
	if (!strcmp(str, "off")) {
		aspm_disabled = 1;
900
		aspm_support_enabled = false;
901 902 903 904 905
		printk(KERN_INFO "PCIe ASPM is disabled\n");
	} else if (!strcmp(str, "force")) {
		aspm_force = 1;
		printk(KERN_INFO "PCIe ASPM is forcedly enabled\n");
	}
S
Shaohua Li 已提交
906 907 908
	return 1;
}

909
__setup("pcie_aspm=", pcie_aspm_disable);
S
Shaohua Li 已提交
910

911 912 913 914 915 916
void pcie_clear_aspm(void)
{
	if (!aspm_force)
		aspm_clear_state = 1;
}

917 918
void pcie_no_aspm(void)
{
919 920
	if (!aspm_force)
		aspm_disabled = 1;
921 922
}

923 924 925 926 927 928 929
/**
 * pcie_aspm_enabled - is PCIe ASPM enabled?
 *
 * Returns true if ASPM has not been disabled by the command-line option
 * pcie_aspm=off.
 **/
int pcie_aspm_enabled(void)
S
Shaohua Li 已提交
930
{
931
       return !aspm_disabled;
S
Shaohua Li 已提交
932
}
933
EXPORT_SYMBOL(pcie_aspm_enabled);
S
Shaohua Li 已提交
934

935 936 937 938 939
bool pcie_aspm_support_enabled(void)
{
	return aspm_support_enabled;
}
EXPORT_SYMBOL(pcie_aspm_support_enabled);