📄 pci.txt
字号:
PCI Power Management~~~~~~~~~~~~~~~~~~~~An overview of the concepts and the related functions in the Linux kernelPatrick Mochel <mochel@transmeta.com>---------------------------------------------------------------------------1. Overview2. How the PCI Subsystem Does Power Management3. PCI Utility Functions4. PCI Device Drivers5. Resources1. Overview~~~~~~~~~~~The PCI Power Management Specification was introduced between the PCI 2.1 andPCI 2.2 Specifications. It a standard interface for controlling various power management operations.Implementation of the PCI PM Spec is optional, as are several sub-components ofit. If a device supports the PCI PM Spec, the device will have an 8 bytecapability field in its PCI configuration space. This field is used to describeand control the standard PCI power management features.The PCI PM spec defines 4 operating states for devices (D0 - D3) and for buses(B0 - B3). The higher the number, the less power the device consumes. However,the higher the number, the longer the latency is for the device to return to an operational state (D0).Bus power management is not covered in this version of this document.Note that all PCI devices support D0 and D3 by default, regardless of whether ornot they implement any of the PCI PM spec.The possible state transitions that a device can undergo are:+---------------------------+| Current State | New State |+---------------------------+| D0 | D1, D2, D3|+---------------------------+| D1 | D2, D3 |+---------------------------+| D2 | D3 |+---------------------------+| D1, D2, D3 | D0 |+---------------------------+Note that when the system is entering a global suspend state, all devices willbe placed into D3 and when resuming, all devices will be placed into D0.However, when the system is running, other state transitions are possible.2. How The PCI Subsystem Handles Power Management~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The PCI suspend/resume functionality is accessed indirectly via the PowerManagement subsystem. At boot, the PCI driver registers a power managementcallback with that layer. Upon entering a suspend state, the PM layer iteratesthrough all of its registered callbacks. This currently takes place only duringAPM state transitions.Upon going to sleep, the PCI subsystem walks its device tree twice. Both times,it does a depth first walk of the device tree. The first walk saves each of thedevice's state and checks for devices that will prevent the system from enteringa global power state. The next walk then places the devices in a low powerstate.The first walk allows a graceful recovery in the event of a failure, since noneof the devices have actually been powered down.In both walks, in particular the second, all children of a bridge are touchedbefore the actual bridge itself. This allows the bridge to retain power whileits children are being accessed.Upon resuming from sleep, just the opposite must be true: all bridges must bepowered on and restored before their children are powered on. This is easilyaccomplished with a breadth-first walk of the PCI device tree.3. PCI Utility Functions~~~~~~~~~~~~~~~~~~~~~~~~These are helper functions designed to be called by individual device drivers.Assuming that a device behaves as advertised, these should be applicable in mostcases. However, results may vary.Note that these functions are never implicitly called for the driver. The driveris always responsible for deciding when and if to call these.pci_save_state--------------Usage: pci_save_state(dev, buffer);Description: Save first 64 bytes of PCI config space. Buffer must be allocated by caller.pci_restore_state-----------------Usage: pci_restore_state(dev, buffer);Description: Restore previously saved config space. (First 64 bytes only); If buffer is NULL, then restore what information we know about the device from bootup: BARs and interrupt line.pci_set_power_state-------------------Usage: pci_set_power_state(dev, state);Description: Transition device to low power state using PCI PM Capabilities registers. Will fail under one of the following conditions: - If state is less than current state, but not D0 (illegal transition) - Device doesn't support PM Capabilities - Device does not support requested statepci_enable_wake---------------Usage: pci_enable_wake(dev, state, enable);Description: Enable device to generate PME# during low power state using PCI PM Capabilities. Checks whether if device supports generating PME# from requested state and fail if it does not, unless enable == 0 (request is to disable wake events, which is implicit if it doesn't even support it in the first place). Note that the PMC Register in the device's PM Capabilties has a bitmask of the states it supports generating PME# from. D3hot is bit 3 and D3cold is bit 4. So, while a value of 4 as the state may not seem semantically correct, it is. 4. PCI Device Drivers~~~~~~~~~~~~~~~~~~~~~These functions are intended for use by individual drivers, and are defined in struct pci_driver: int (*save_state) (struct pci_dev *dev, u32 state); int (*suspend) (struct pci_dev *dev, u32 state); int (*resume) (struct pci_dev *dev); int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);save_state----------Usage:if (dev->driver && dev->driver->save_state) dev->driver->save_state(dev,state);The driver should use this callback to save device state. It should take intoaccount the current state of the device and the requested state in order toavoid any unnecessary operations.For example, a video card that supports all 4 states (D0-D3), all controllercontext is preserved when entering D1, but the screen is placed into a low powerstate (blanked). The driver can also interpret this function as a notification that it may beentering a sleep state in the near future. If it knows that the device cannotenter the requested state, either because of lack of support for it, or becausethe device is middle of some critical operation, then it should fail.This function should not be used to set any state in the device or the driverbecause the device may not actually enter the sleep state (e.g. another driverlater causes causes a global state transition to fail).Note that in intermediate low power states, a device's I/O and memory spaces maybe disabled and may not be available in subsequent transitions to lower powerstates.suspend-------Usage:if (dev->driver && dev->driver->suspend) dev->driver->suspend(dev,state);A driver uses this function to actually transition the device into a low powerstate. This may include disabling I/O, memory and bus-mastering, as well asphysically transitioning the device to a lower power state.Bus mastering may be disabled by doing:pci_disable_device(dev);For devices that support the PCI PM Spec, this may be used to set the device'spower state:pci_set_power_state(dev,state);The driver is also responsible for disabling any other device-specific features(e.g blanking screen, turning off on-card memory, etc).The driver should be sure to track the current state of the device, as it mayobviate the need for some operations.The driver should update the current_state field in its pci_dev structure inthis function.resume------Usage:if (dev->driver && dev->driver->suspend) dev->driver->resume(dev)The resume callback may be called from any power state, and is always meant totransition the device to the D0 state. The driver is responsible for reenabling any features of the device that hadbeen disabled during previous suspend calls and restoring all state that wassaved in previous save_state calls.If the device is currently in D3, it must be completely reinitialized, as itmust be assumed that the device has lost all of its context (even that of itsPCI config space). For almost all current drivers, this means that theinitialization code that the driver does at boot must be separated out andcalled again from the resume callback. Note that some values for the device maynot have to be probed for this time around if they are saved before entering thelow power state.If the device supports the PCI PM Spec, it can use this to physically transitionthe device to D0:pci_set_power_state(dev,0);Note that if the entire system is transitioning out of a global sleep state, alldevices will be placed in the D0 state, so this is not necessary. However, inthe event that the device is placed in the D3 state during normal operation,this call is necessary. It is impossible to determine which of the two events istaking place in the driver, so it is always a good idea to make that call.The driver should take note of the state that it is resuming from in order toensure correct (and speedy) operation.The driver should update the current_state field in its pci_dev structure inthis function.enable_wake-----------Usage:if (dev->driver && dev->driver->enable_wake) dev->driver->enable_wake(dev,state,enable);This callback is generally only relevant for devices that support the PCI PMspec and have the ability to generate a PME# (Power Management Event Signal)to wake the system up. (However, it is possible that a device may support some non-standard way of generating a wake event on sleep.)Bits 15:11 of the PMC (Power Mgmt Capabilities) Register in a device'sPM Capabilties describe what power states the device supports generating a wake event from:+------------------+| Bit | State |+------------------+| 11 | D0 || 12 | D1 || 13 | D2 || 14 | D3hot || 15 | D3cold |+------------------+A device can use this to enable wake events: pci_enable_wake(dev,state,enable);Note that to enable PME# from D3cold, a value of 4 should be passed to pci_enable_wake (since it uses an index into a bitmask). If a driver getsa request to enable wake events from D3, two calls should be made to pci_enable_wake (one for both D3hot and D3cold).5. Resources~~~~~~~~~~~~PCI Local Bus Specification PCI Bus Power Management Interface Specification http://pcisig.org
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -