Re: [PATCH 2/3] PCI: add OBFF enable/disable support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 05, 2011 at 12:33:49PM -0700, Jesse Barnes wrote:
> OBFF (optimized buffer flush/fill), where supported, can help improve
> energy efficiency by giving devices information about when interrupts
> and other activity will have a reduced power impact.  It requires
> support from both the device and system (i.e. not only does the device
> need to respond to OBFF messages, but the platform must be capable of
> generating and routing them to the end point).

I'm really confused by the OBFF spec.  There's all kinds of caveats on
enabling OBFF; for example, it seems that the WAKE# signal might be shared
between all devices below a given switch ... but how are we to know?
Figure 6-19 in the 10Nov10 spec shows a case where _all_ the devices
connected to Switch B would need to support OBFF in order to enable it.
And not necessarily directly connected either; the device below Switch
A shares WAKE# with the devices directly below the root port.

I think we should probably leave it up to the BIOS to configure OBFF.
I don't think we can do it.

That said, I did notice a bug ...

> +	/* Make sure the topology supports OBFF as well */
> +	if (dev->bus) {
> +		ret = pci_enable_obff(dev->bus->self, type);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
> +	if (cap & PCI_EXP_OBFF_WAKE)
> +		ctrl |= PCI_EXP_OBFF_WAKE_EN;
> +	else {
> +		switch (type) {
> +		case PCI_EXP_OBFF_SIGNAL_L0:
> +			ctrl |= PCI_EXP_OBFF_MSGA_EN;
> +			break;
> +		case PCI_EXP_OBFF_SIGNAL_ALWAYS:
> +			ctrl |= PCI_EXP_OBFF_MSGB_EN;
> +			break;
> +		default:
> +			WARN(1, "bad OBFF signal type\n");
> +			return -ENOTSUPP;
> +		}
> +	}

If Device 1 asks for L0 and Device 2 asks for Always, any component above
them in the hierarchy gets WAKE set, which isn't going to work out very well.
It should look like this:

		switch (type) {
		case PCI_EXP_OBFF_SIGNAL_L0:
			if (!(ctrl & PCI_EXP_OBFF_WAKE_EN))
				ctrl |= PCI_EXP_OBFF_MSGA_EN;
			break;
		case PCI_EXP_OBFF_SIGNAL_ALWAYS:
			ctrl &= ~PCI_EXP_OBFF_WAKE_EN;
			ctrl |= PCI_EXP_OBFF_MSGB_EN;
			break;

> +	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
> +	ctrl &= ~(PCI_EXP_OBFF_MSGA_EN | PCI_EXP_OBFF_MSGA_EN |
> +		  PCI_EXP_OBFF_WAKE_EN);

That simplifies to ctrl &= ~PCI_EXP_OBFF_WAKE_EN;

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux