1. 19 Mar, 2018 7 commits
  2. 16 Mar, 2018 11 commits
  3. 15 Mar, 2018 1 commit
  4. 14 Mar, 2018 14 commits
  5. 13 Mar, 2018 7 commits
    • Lukas Wunner's avatar
      drm/nouveau: Runtime suspend despite HDA being unbound · fd1eabd8
      Lukas Wunner authored
      Commit 5addcf0a ("nouveau: add runtime PM support (v0.9)") prevents
      runtime suspend of the GPU if its integrated HDA controller is not bound
      to a driver.  The rationale appears to be that probing the HDA fails if
      the GPU is in D3cold.
      
      However we now use a device link to ensure that the GPU is runtime
      resumed while the HDA controller is probed, rendering this safety
      measure obsolete.  Remove it.
      
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Takashi Iwai <tiwai@suse.de>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarPeter Wu <peter@lekensteyn.nl>
      Tested-by: Denis Lisov <dennis.lissov@gmail.com>       # Nvidia Optimus
      Tested-by: Peter Wu <peter@lekensteyn.nl>              # Nvidia Optimus
      Tested-by: Lukas Wunner <lukas@wunner.de>              # MacBook Pro
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/77e0ab74f3377ea9b6acf8fab624acfb4f7dbeca.1520068884.git.lukas@wunner.de
      fd1eabd8
    • Lukas Wunner's avatar
      vga_switcheroo: Let HDA autosuspend on mux change · b67ae78e
      Lukas Wunner authored
      When switching the display on muxed machines, we currently force the HDA
      controller into runtime suspend on the previously used GPU and into
      runtime active state on the newly used GPU.
      
      That's unnecessary if the GPU uses driver power control, we can just let
      the audio device autosuspend or autoresume as it sees fit.
      
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Takashi Iwai <tiwai@suse.de>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Reviewed-by: default avatarPeter Wu <peter@lekensteyn.nl>
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/098ed883460eb4976a899eac6f5192fefc877c0f.1520068884.git.lukas@wunner.de
      b67ae78e
    • Lukas Wunner's avatar
      vga_switcheroo: Use device link for HDA controller · 07f4f97d
      Lukas Wunner authored
      Back in 2013, runtime PM for GPUs with integrated HDA controller was
      introduced with commits 0d69704a ("gpu/vga_switcheroo: add driver
      control power feature. (v3)") and 246efa4a ("snd/hda: add runtime
      suspend/resume on optimus support (v4)").
      
      Briefly, the idea was that the HDA controller is forced on and off in
      unison with the GPU.
      
      The original code is mostly still in place even though it was never a
      100% perfect solution:  E.g. on access to the HDA controller, the GPU
      is powered up via vga_switcheroo_runtime_resume_hdmi_audio() but there
      are no provisions to keep it resumed until access to the HDA controller
      has ceased:  The GPU autosuspends after 5 seconds, rendering the HDA
      controller inaccessible.
      
      Additionally, a kludge is required when hda_intel.c probes:  It has to
      check whether the GPU is powered down (check_hdmi_disabled()) and defer
      probing if so.
      
      However in the meantime (in v4.10) the driver core has gained a feature
      called device links which promises to solve such issues in a clean way:
      It allows us to declare a dependency from the HDA controller (consumer)
      to the GPU (supplier).  The PM core then automagically ensures that the
      GPU is runtime resumed as long as the HDA controller's ->probe hook is
      executed and whenever the HDA controller is accessed.
      
      By default, the HDA controller has a dependency on its parent, a PCIe
      Root Port.  Adding a device link creates another dependency on its
      sibling:
      
                                  PCIe Root Port
                                   ^          ^
                                   |          |
                                   |          |
                                  HDA  ===>  GPU
      
      The device link is not only used for runtime PM, it also guarantees that
      on system sleep, the HDA controller suspends before the GPU and resumes
      after the GPU, and on system shutdown the HDA controller's ->shutdown
      hook is executed before the one of the GPU.  It is a complete solution.
      
      Using this functionality is as simple as calling device_link_add(),
      which results in a dmesg entry like this:
      
              pci 0000:01:00.1: Linked as a consumer to 0000:01:00.0
      
      The code for the GPU-governed audio power management can thus be removed
      (except where it's still needed for legacy manual power control).
      
      The device link is added in a PCI quirk rather than in hda_intel.c.
      It is therefore legal for the GPU to runtime suspend to D3cold even if
      the HDA controller is not bound to a driver or if CONFIG_SND_HDA_INTEL
      is not enabled, for accesses to the HDA controller will cause the GPU to
      wake up regardless if they're occurring outside of hda_intel.c (think
      config space readout via sysfs).
      
      Contrary to the previous implementation, the HDA controller's power
      state is now self-governed, rather than GPU-governed, whereas the GPU's
      power state is no longer fully self-governed.  (The HDA controller needs
      to runtime suspend before the GPU can.)
      
      It is thus crucial that runtime PM is always activated on the HDA
      controller even if CONFIG_SND_HDA_POWER_SAVE_DEFAULT is set to 0 (which
      is the default), lest the GPU stays awake.  This is achieved by setting
      the auto_runtime_pm flag on every codec and the AZX_DCAPS_PM_RUNTIME
      flag on the HDA controller.
      
      A side effect is that power consumption might be reduced if the GPU is
      in use but the HDA controller is not, because the HDA controller is now
      allowed to go to D3hot.  Before, it was forced to stay in D0 as long as
      the GPU was in use.  (There is no reduction in power consumption on my
      Nvidia GK107, but there might be on other chips.)
      
      The code paths for legacy manual power control are adjusted such that
      runtime PM is disabled during power off, thereby preventing the PM core
      from resuming the HDA controller.
      
      Note that the device link is not only added on vga_switcheroo capable
      systems, but for *any* GPU with integrated HDA controller.  The idea is
      that the HDA controller streams audio via connectors located on the GPU,
      so the GPU needs to be on for the HDA controller to do anything useful.
      
      This commit implicitly fixes an unbalanced runtime PM ref upon unbind of
      hda_intel.c:  On ->probe, a runtime PM ref was previously released under
      the condition "azx_has_pm_runtime(chip) || hda->use_vga_switcheroo", but
      on ->remove a runtime PM ref was only acquired under the first of those
      conditions.  Thus, binding and unbinding the driver twice on a
      vga_switcheroo capable system caused the runtime PM refcount to drop
      below zero.  The issue is resolved because the AZX_DCAPS_PM_RUNTIME flag
      is now always set if use_vga_switcheroo is true.
      
      For more information on device links please refer to:
      https://www.kernel.org/doc/html/latest/driver-api/device_link.html
      Documentation/driver-api/device_link.rst
      
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
      Reviewed-by: default avatarPeter Wu <peter@lekensteyn.nl>
      Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
      Tested-by: Mike Lothian <mike@fireburn.co.uk>          # AMD PowerXpress
      Tested-by: Denis Lisov <dennis.lissov@gmail.com>       # Nvidia Optimus
      Tested-by: Peter Wu <peter@lekensteyn.nl>              # Nvidia Optimus
      Tested-by: Lukas Wunner <lukas@wunner.de>              # MacBook Pro
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/51bd38360ff502a8c42b1ebf4405ee1d3f27118d.1520068884.git.lukas@wunner.de
      07f4f97d
    • Lukas Wunner's avatar
      vga_switcheroo: Deduplicate power state tracking · 8948ca1a
      Lukas Wunner authored
      If DRM drivers use runtime PM, they currently notify vga_switcheroo
      whenever they ->runtime_suspend or ->runtime_resume to update
      vga_switcheroo's internal power state tracking.
      
      That's essentially a duplication of a functionality performed by the
      PM core as it already tracks the GPU's power state and vga_switcheroo
      can always query it.
      
      Introduce a new internal helper vga_switcheroo_pwr_state() which does
      just that if runtime PM is used, or falls back to vga_switcheroo's
      internal power state tracking if manual power control is used.
      Drop a redundant power state check in set_audio_state() while at it.
      
      This removes one of the two purposes of the notification mechanism
      implemented by vga_switcheroo_set_dynamic_switch().  The other one is
      power management of the audio device and we'll remove that next.
      
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Takashi Iwai <tiwai@suse.de>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarPeter Wu <peter@lekensteyn.nl>
      Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
      Tested-by: Mike Lothian <mike@fireburn.co.uk>          # AMD PowerXpress
      Tested-by: Denis Lisov <dennis.lissov@gmail.com>       # Nvidia Optimus
      Tested-by: Peter Wu <peter@lekensteyn.nl>              # Nvidia Optimus
      Tested-by: Lukas Wunner <lukas@wunner.de>              # MacBook Pro
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/0aa49d735b988aa04524a8dc339582ace33f0f94.1520068884.git.lukas@wunner.de
      8948ca1a
    • Lukas Wunner's avatar
      vga_switcheroo: Update PCI current_state on power change · dcac86b7
      Lukas Wunner authored
      When cutting power to a GPU and its integrated HDA controller, their
      cached current_state should be updated to D3cold to reflect reality.
      
      We currently rely on the DRM and HDA drivers to do that, however:
      
      - The HDA driver updates the current_state in azx_vs_set_state(), which
        will no longer be called with driver power control once we migrate to
        device links.  (It will still be called with manual power control.)
      
      - If the HDA device is not bound, its current_state remains at D0 even
        though the GPU driver may decide to go to D3cold.
      
      - The DRM drivers update the current_state using pci_set_power_state()
        which can't put the device into a deeper power state than D3hot if the
        GPU is not deemed power-manageable by the platform (even though it
        *is* power-manageable by some nonstandard means, such as a _DSM).
      
      Centralize updating the current_state of the GPU and HDA controller in
      vga_switcheroo's ->runtime_suspend hook to overcome these deficiencies.
      
      The GPU and HDA controller are two functions of the same PCI device
      (VGA class device on function 0 and audio device on function 1) and
      no other PCI devices reside on the same bus since this is a PCIe
      point-to-point link, so we can just walk the bus and update the
      current_state of all devices.
      
      On ->runtime_resume, the HDA controller is in D0uninitialized state.
      Resume to D0active and then let it autosuspend as it sees fit.
      
      Note that vga_switcheroo_init_domain_pm_ops() is not supposed to be
      called by hybrid graphics laptops which power down the GPU via its root
      port's _PR3 resources and consequently vga_switcheroo_runtime_suspend()
      is not used.  On those laptops, the root port is power-manageable by the
      platform (instead of by a nonstandard means) and the current_state is
      therefore updated by the PCI core through the following call chain:
      
        pci_set_power_state()
          __pci_complete_power_transition()
            pci_bus_set_current_state()
      
      Resuming to D0active happens through:
      
        pci_set_power_state()
          __pci_start_power_transition()
            pci_wakeup_bus()
      
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Takashi Iwai <tiwai@suse.de>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: Bjorn Helgaas <bhelgaas@google.com>
      Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarPeter Wu <peter@lekensteyn.nl>
      Tested-by: Kai Heng Feng <kai.heng.feng@canonical.com> # AMD PowerXpress
      Tested-by: Mike Lothian <mike@fireburn.co.uk>          # AMD PowerXpress
      Tested-by: Denis Lisov <dennis.lissov@gmail.com>       # Nvidia Optimus
      Tested-by: Peter Wu <peter@lekensteyn.nl>              # Nvidia Optimus
      Tested-by: Lukas Wunner <lukas@wunner.de>              # MacBook Pro
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/8416958482c8c42d6f311ea5c1e5a65ccf21f5db.1520068884.git.lukas@wunner.de
      dcac86b7
    • Lukas Wunner's avatar
      PCI: Make pci_wakeup_bus() & pci_bus_set_current_state() public · 2a4d2c42
      Lukas Wunner authored
      There are PCI devices which are power-manageable by a nonstandard means,
      such as a custom ACPI method.  One example are discrete GPUs in hybrid
      graphics laptops, another are Thunderbolt controllers in Macs.
      
      Such devices can't be put into D3cold with pci_set_power_state() because
      pci_platform_power_transition() fails with -ENODEV.  Instead they're put
      into D3hot by pci_set_power_state() and subsequently into D3cold by
      invoking the nonstandard means.  However as a consequence the cached
      current_state is incorrectly left at D3hot.
      
      What we need to do is walk the hierarchy below such a PCI device on
      powerdown and update the current_state to D3cold.  On powerup the PCI
      device itself and the hierarchy below it is in D0uninitialized, so we
      need to walk the hierarchy again and wake all devices, causing them to
      be put into D0active and then letting them autosuspend as they see fit.
      
      To this end make pci_wakeup_bus() & pci_bus_set_current_state() public
      so PCI drivers don't have to reinvent the wheel.
      
      Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/2962443259e7faec577274b4ef8c54aad66f9a94.1520068884.git.lukas@wunner.de
      2a4d2c42
    • Rafael J. Wysocki's avatar
      PCI: Restore config space on runtime resume despite being unbound · 5775b843
      Rafael J. Wysocki authored
      We leave PCI devices not bound to a driver in D0 during runtime suspend.
      But they may have a parent which is bound and can be transitioned to
      D3cold at runtime.  Once the parent goes to D3cold, the unbound child
      may go to D3cold as well.  When the child goes to D3cold, its internal
      state, including configuration of BARs, MSI, ASPM, MPS, etc., is lost.
      
      One example are recent hybrid graphics laptops which cut power to the
      discrete GPU when the root port above it goes to ACPI power state D3.
      Users may provoke this by unbinding the GPU driver and allowing runtime
      PM on the GPU via sysfs:  The PM core will then treat the GPU as
      "suspended", which in turn allows the root port to runtime suspend,
      causing the power resources listed in its _PR3 object to be powered off.
      The GPU's BARs will be uninitialized when a driver later probes it.
      
      Another example are hybrid graphics laptops where the GPU itself (rather
      than the root port) is capable of runtime suspending to D3cold.  If the
      GPU's integrated HDA controller is not bound and the GPU's driver
      decides to runtime suspend to D3cold, the HDA controller's BARs will be
      uninitialized when a driver later probes it.
      
      Fix by saving and restoring config space over a runtime suspend cycle
      even if the device is not bound.
      Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
      Tested-by: Peter Wu <peter@lekensteyn.nl>              # Nvidia Optimus
      Tested-by: Lukas Wunner <lukas@wunner.de>              # MacBook Pro
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      [lukas: add commit message, bikeshed code comments for clarity]
      Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/92fb6e6ae2730915eb733c08e2f76c6a313e3860.1520068884.git.lukas@wunner.de
      5775b843