path: root/drivers/gpu/vga/vga_switcheroo.c
AgeCommit message (Collapse)AuthorFilesLines
2018-11-05vga_switcheroo: Fix missing gpu_bound call at audio client registrationTakashi Iwai1-0/+3
The commit 37a3a98ef601 ("ALSA: hda - Enable runtime PM only for discrete GPU") added a new ops gpu_bound to be called when GPU gets bound. The patch overlooked, however, that vga_switcheroo_enable() is called only once at GPU is bound. When an audio client is registered after that point, it would miss the gpu_bound call. This leads to the unexpected lack of runtime PM in HD-audio side. For addressing that regression, just call gpu_bound callback manually at vga_switcheroo_register_audio_client() when the GPU was already bound. Bugzilla: Fixes: 37a3a98ef601 ("ALSA: hda - Enable runtime PM only for discrete GPU") Cc: <> Reviewed-by: Lukas Wunner <> Signed-off-by: Takashi Iwai <>
2018-09-13ALSA: hda - Enable runtime PM only for discrete GPUTakashi Iwai1-0/+2
The recent change of vga_switcheroo allowed the runtime PM for HD-audio on AMD GPUs, but this also resulted in a regression. When the HD-audio controller driver gets runtime-suspended, HD-audio link is turned off, and the hotplug notification is ignored. This leads to the inconsistent audio state (the connection isn't notified and ELD is ignored). The best fix would be to implement the proper ELD notification via the audio component, but it's still not ready. As a quick workaround, this patch adds the check of runtime_idle and allows the runtime suspend only when the vga_switcheroo is bound with discrete GPU. That is, a system with a single GPU and APU would be again without runtime PM to keep the HD-audio link for the hotplug notification and ELD read out. Also, the codec->auto_runtime_pm flag is set only for the discrete GPU at the time GPU gets bound via vga_switcheroo (i.e. only dGPU is forcibly runtime-PM enabled), so that APU can still get the ELD notification. For identifying which GPU is bound, a new vga_switcheroo client callback, gpu_bound, is implemented. The vga_switcheroo simply calls this when GPU is bound, and tells whether it's dGPU or APU. Bugzilla: Fixes: 07f4f97d7b4b ("vga_switcheroo: Use device link for HDA controller") Reported-by: Jian-Hong Pan <> Tested-by: Jian-Hong Pan <> Acked-by: Lukas Wunner <> Signed-off-by: Takashi Iwai <>
2018-07-17vga_switcheroo: set audio client id according to bound GPU idJim Qu1-11/+52
On modern laptop, there are more and more platforms have two GPUs, and each of them maybe have audio codec for HDMP/DP output. For some dGPU which is no output, audio codec usually is disabled. In currect HDA audio driver, it will set all codec as VGA_SWITCHEROO_DIS, the audio which is binded to UMA will be suspended if user use debugfs to contorl power In HDA driver side, it is difficult to know which GPU the audio has binded to. So set the bound gpu pci dev to vga_switcheroo. if the audio client is not the third registration, audio id will set in vga_switcheroo enable function. if the audio client is the last registration when vga_switcheroo _ready() get true, we should get audio client id from bound GPU directly. Signed-off-by: Jim Qu <> Reviewed-by: Lukas Wunner <> Signed-off-by: Takashi Iwai <>
2018-03-13vga_switcheroo: Let HDA autosuspend on mux changeLukas Wunner1-2/+6
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 <> Cc: Ben Skeggs <> Cc: Takashi Iwai <> Cc: Alex Deucher <> Reviewed-by: Peter Wu <> Signed-off-by: Lukas Wunner <> Link:
2018-03-13vga_switcheroo: Use device link for HDA controllerLukas Wunner1-107/+8
Back in 2013, runtime PM for GPUs with integrated HDA controller was introduced with commits 0d69704ae348 ("gpu/vga_switcheroo: add driver control power feature. (v3)") and 246efa4a072f ("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: Documentation/driver-api/device_link.rst Cc: Dave Airlie <> Cc: Ben Skeggs <> Cc: Alex Deucher <> Cc: Rafael J. Wysocki <> Acked-by: Bjorn Helgaas <> Reviewed-by: Takashi Iwai <> Reviewed-by: Peter Wu <> Tested-by: Kai Heng Feng <> # AMD PowerXpress Tested-by: Mike Lothian <> # AMD PowerXpress Tested-by: Denis Lisov <> # Nvidia Optimus Tested-by: Peter Wu <> # Nvidia Optimus Tested-by: Lukas Wunner <> # MacBook Pro Signed-off-by: Lukas Wunner <> Link:
2018-03-13vga_switcheroo: Deduplicate power state trackingLukas Wunner1-12/+23
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 <> Cc: Ben Skeggs <> Cc: Takashi Iwai <> Cc: Alex Deucher <> Cc: Rafael J. Wysocki <> Reviewed-by: Peter Wu <> Tested-by: Kai Heng Feng <> # AMD PowerXpress Tested-by: Mike Lothian <> # AMD PowerXpress Tested-by: Denis Lisov <> # Nvidia Optimus Tested-by: Peter Wu <> # Nvidia Optimus Tested-by: Lukas Wunner <> # MacBook Pro Signed-off-by: Lukas Wunner <> Link:
2018-03-13vga_switcheroo: Update PCI current_state on power changeLukas Wunner1-0/+2
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 <> Cc: Ben Skeggs <> Cc: Takashi Iwai <> Cc: Alex Deucher <> Cc: Bjorn Helgaas <> Cc: Rafael J. Wysocki <> Reviewed-by: Peter Wu <> Tested-by: Kai Heng Feng <> # AMD PowerXpress Tested-by: Mike Lothian <> # AMD PowerXpress Tested-by: Denis Lisov <> # Nvidia Optimus Tested-by: Peter Wu <> # Nvidia Optimus Tested-by: Lukas Wunner <> # MacBook Pro Signed-off-by: Lukas Wunner <> Link:
2017-03-01drivers:gpu: vga :vga_switcheroo.c : Fixed some coding style issuesJoan Jani1-13/+15
Fixed the following style issues drivers/gpu/vga/vga_switcheroo.c:98: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:99: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:102: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:103: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:129: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:135: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:217: WARNING: line over 80 characters drivers/gpu/vga/vga_switcheroo.c:218: WARNING: line over 80 characters drivers/gpu/vga/vga_switcheroo.c:308: WARNING: please, no space before tabs drivers/gpu/vga/vga_switcheroo.c:340: WARNING: line over 80 characters drivers/gpu/vga/vga_switcheroo.c:1087: WARNING: Block comments use * on subsequent lines drivers/gpu/vga/vga_switcheroo.c:1087: WARNING: Block comments use a trailing */ on a separate line Signed-off-by: Joan Jani <> Signed-off-by: Daniel Vetter <> Link:
2016-07-12vga_switcheroo: Sphinxify docsLukas Wunner1-14/+14
Fix up formatting glitches remaining after the automatic rst conversion. Cc: Jonathan Corbet <> Cc: Jani Nikula <> Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <> Link:
2016-05-31vga_switcheroo: Support deferred probing of audio clientsLukas Wunner1-8/+11
Daniel Vetter pointed out that vga_switcheroo_client_probe_defer() could be needed by audio clients as well. To avoid mistakes when someone adds conditions for these in the future, constrain the single existing condition to VGA clients by checking for PCI_BASE_CLASS_DISPLAY. This encompasses both PCI_CLASS_DISPLAY_VGA as well as PCI_CLASS_DISPLAY_3D, which is used by some Nvidia Optimus GPUs. Any future checks for audio clients should then be constrained to PCI_BASE_CLASS_MULTIMEDIA. v6: Spun out from commit introducing vga_switcheroo_client_probe_defer() to keep it a pure refactoring change. (Emil Velikov, Jani Nikula) Cc: Daniel Vetter <> Cc: Emil Velikov <> Cc: Jani Nikula <> Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <> Link:
2016-05-31vga_switcheroo: Add helper for deferred probingLukas Wunner1-1/+28
So far we've got one condition when DRM drivers need to defer probing on a dual GPU system and it's coded separately into each of the relevant drivers. As suggested by Daniel Vetter, deduplicate that code in the drivers and move it to a new vga_switcheroo helper. This yields better encapsulation of concepts and lets us add further checks in a central place. (The existing check pertains to pre-retina MacBook Pros and an additional check is expected to be needed for retinas.) One might be tempted to check deferred probing conditions in vga_switcheroo_register_client(), but this is usually called fairly late during driver load. The GPU is fully brought up and ready for switching at that point. On boot the ->probe hook is potentially called dozens of times until it finally succeeds, and each time we'd repeat bringup and teardown of the GPU, lengthening boot time considerably and cluttering logfiles. A separate helper is therefore needed which can be called right at the beginning of the ->probe hook. Note that amdgpu currently does not call this helper as the AMD GPUs built into MacBook Pros are only supported by radeon so far. v2: This helper could eventually be used by audio clients as well, so rephrase kerneldoc to refer to "client" instead of "GPU" and move the single existing check in an if block specific to PCI_CLASS_DISPLAY_VGA devices. Move documentation on that check from kerneldoc to a comment. (Daniel Vetter) v3: Mandate in kerneldoc that registration of client shall only happen after calling this helper. (Daniel Vetter) v4: Rebase on 412c8f7de011 ("drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded") v5: Some Optimus GPUs use PCI_CLASS_DISPLAY_3D, make sure those are matched as well. (Emil Velikov) v6: The if-condition referring to PCI_BASE_CLASS_DISPLAY may be considered a functional change. Move to a separate commit to keep this a pure refactoring change. (Emil Velikov, Jani Nikula) Cc: Daniel Vetter <> Cc: Ben Skeggs <> Cc: Alex Deucher <> Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <> Link:
2016-02-09vga_switcheroo: Add support for switching only the DDCLukas Wunner1-2/+95
Originally by Seth Forshee <>, 2012-10-04: During graphics driver initialization it's useful to be able to mux only the DDC to the inactive client in order to read the EDID. Add a switch_ddc callback to allow capable handlers to provide this functionality, and add vga_switcheroo_switch_ddc() to allow DRM to mux only the DDC. Modified by Dave Airlie <>, 2012-12-22: I can't figure out why I didn't like this, but I rewrote this [...] to lock/unlock the ddc lines [...]. I think I'd prefer something like that otherwise the interface got really ugly. Modified by Lukas Wunner <>, 2015-04 - 2015-10: Change semantics of ->switch_ddc handler callback to return previous DDC owner. Original version tried to determine previous DDC owner with find_active_client() but this fails if the inactive client registers before the active client. Don't lock vgasr_mutex in _lock_ddc() / _unlock_ddc(), it can cause deadlocks because (a) during switch (with vgasr_mutex already held), GPU is woken and probes its outputs, tries to re-acquire vgasr_mutex to lock DDC lines; (b) Likewise during switch, GPU is suspended and calls cancel_delayed_work_sync() to stop output polling, if poll task is running at this moment we may wait forever for it to finish. Instead, lock mux_hw_lock when unregistering the handler because the only reason why we'd want to lock vgasr_mutex in _lock_ddc() / _unlock_ddc() is to block the handler from disappearing while DDC lines are switched. Also acquire mux_hw_lock in stage2 to avoid race condition where reading the EDID and switching happens simultaneously. Likewise on MIGD / MDIS commands and on runtime suspend. v2.1: Overhaul locking, squash commits (Daniel Vetter) v2.2: Readability improvements (Thierry Reding) v2.3: Overhaul locking once more v2.4: Retain semantics of ->switchto handler callback to switch all pins, including DDC (Daniel Vetter) v5: Rename ddc_lock to mux_hw_lock: Since we acquire this both when calling ->switch_ddc and ->switchto, it protects not just access to the DDC lines but to the mux in general. This is in line with the DRM convention to use low-level locks to avoid concurrent hw access (e.g. i2c, dp_aux) which are often called hw_lock (Daniel Vetter) Bugzilla: Bugzilla: Tested-by: Lukas Wunner <> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Cc: Seth Forshee <> Cc: Dave Airlie <> Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <> Link:
2016-02-09vga_switcheroo: Add handler flags infrastructureLukas Wunner1-1/+21
Allow handlers to declare their capabilities and allow clients to obtain that information. So far we have these use cases: * If the handler is able to switch DDC separately, clients need to probe EDID with drm_get_edid_switcheroo(). We should allow them to detect a capable handler to ensure this function only gets called when needed. * Likewise if the handler is unable to switch AUX separately, the active client needs to communicate link training parameters to the inactive client, which may then skip the AUX handshake and set up its output with these pre-calibrated values (DisplayPort specification v1.1a, section Clients need a way to recognize such a situation. The flags for the radeon_atpx_handler and amdgpu_atpx_handler are initially set to 0, this can later on be amended with handler_flags |= VGA_SWITCHEROO_CAN_SWITCH_DDC; when a ->switch_ddc callback is added. Bugzilla: Bugzilla: Tested-by: Lukas Wunner <> [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner <> Reviewed-by: Darren Hart <> Signed-off-by: Daniel Vetter <> Link:
2016-01-20Merge tag 'pm+acpi-4.5-rc1-2' of ↵Linus Torvalds1-5/+6
git:// Pull more power management and ACPI updates from Rafael Wysocki: "This includes fixes on top of the previous batch of PM+ACPI updates and some new material as well. From the new material perspective the most significant are the driver core changes that should allow USB devices to stay suspended over system suspend/resume cycles if they have been runtime-suspended already beforehand. Apart from that, ACPICA is updated to upstream revision 20160108 (cosmetic mostly, but including one fixup on top of the previous ACPICA update) and there are some devfreq updates the didn't make it before (due to timing). A few recent regressions are fixed, most importantly in the cpuidle menu governor and in the ACPI backlight driver and some x86 platform drivers depending on it. Some more bugs are fixed and cleanups are made on top of that. Specifics: - Modify the driver core and the USB subsystem to allow USB devices to stay suspended over system suspend/resume cycles if they have been runtime-suspended already beforehand and fix some bugs on top of these changes (Tomeu Vizoso, Rafael Wysocki). - Update ACPICA to upstream revision 20160108, including updates of the ACPICA's copyright notices, a code fixup resulting from a regression fix that was necessary in the upstream code only (the regression fixed by it has never been present in Linux) and a compiler warning fix (Bob Moore, Lv Zheng). - Fix a recent regression in the cpuidle menu governor that broke it on practically all architectures other than x86 and make a couple of optimizations on top of that fix (Rafael Wysocki). - Clean up the selection of cpuidle governors depending on whether or not the kernel is configured for tickless systems (Jean Delvare). - Revert a recent commit that introduced a regression in the ACPI backlight driver, address the problem it attempted to fix in a different way and revert one more cosmetic change depending on the problematic commit (Hans de Goede). - Add two more ACPI backlight quirks (Hans de Goede). - Fix a few minor problems in the core devfreq code, clean it up a bit and update the MAINTAINERS information related to it (Chanwoo Choi, MyungJoo Ham). - Improve an error message in the ACPI fan driver (Andy Lutomirski). - Fix a recent build regression in the cpupower tool (Shreyas Prabhu)" * tag 'pm+acpi-4.5-rc1-2' of git:// (32 commits) cpuidle: menu: Avoid pointless checks in menu_select() sched / idle: Drop default_idle_call() fallback from call_cpuidle() cpupower: Fix build error in cpufreq-info cpuidle: Don't enable all governors by default cpuidle: Default to ladder governor on ticking systems time: nohz: Expose tick_nohz_enabled ACPICA: Update version to 20160108 ACPICA: Silence a -Wbad-function-cast warning when acpi_uintptr_t is 'uintptr_t' ACPICA: Additional 2016 copyright changes ACPICA: Reduce regression fix divergence from upstream ACPICA ACPI / video: Add disable_backlight_sysfs_if quirk for the Toshiba Satellite R830 ACPI / video: Revert "thinkpad_acpi: Use acpi_video_handles_brightness_key_presses()" ACPI / video: Document acpi_video_handles_brightness_key_presses() a bit ACPI / video: Fix using an uninitialized mutex / list_head in acpi_video_handles_brightness_key_presses() ACPI / video: Revert "ACPI / video: driver must be registered before checking for keypresses" ACPI / fan: Improve acpi_device_update_power error message ACPI / video: Add disable_backlight_sysfs_if quirk for the Toshiba Portege R700 cpuidle: menu: Fix menu_select() for CPUIDLE_DRIVER_STATE_START == 0 MAINTAINERS: Add devfreq-event entry MAINTAINERS: Add missing git repository and directory for devfreq ...
2016-01-08PM / Domains: add setter for dev.pm_domainTomeu Vizoso1-5/+6
Adds a function that sets the pointer to dev_pm_domain in struct device and that warns if the device has already finished probing. The reason why we want to enforce that is because in the general case that can cause problems and also that we can simplify code quite a bit if we can always assume that. This patch also changes all current code that directly sets the dev.pm_domain pointer. Signed-off-by: Tomeu Vizoso <> Reviewed-by: Ulf Hansson <> Signed-off-by: Rafael J. Wysocki <>
2016-01-04vga_switcheroo: Prettify documentationLukas Wunner1-1/+1
Fix indentation of vga_switcheroo sections in gpu.tmpl. Change section type of API documentation from "chapter" to "sect1" so that the individual functions no longer clutter up the ToC. Group together under a new "API" chapter. Fix wording "heretoforth" -> "henceforth". Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <>
2015-11-05vga_switcheroo: Drop client power state VGA_SWITCHEROO_INITLukas Wunner1-2/+0
hda_intel.c:azx_probe() defers initialization of an audio controller on the discrete GPU if the GPU is powered off. The power state of the GPU is determined by calling vga_switcheroo_get_client_state(). vga_switcheroo_get_client_state() returns VGA_SWITCHEROO_INIT if vga_switcheroo is not enabled, i.e. if no second GPU or no handler has registered. This can go wrong in the following scenario: - Driver for the integrated GPU is not loaded. - Driver for the discrete GPU registers with vga_switcheroo, uses driver power control to power down the GPU, handler cuts power to the GPU. - Driver for the audio controller gets loaded after the GPU was powered down, calls vga_switcheroo_get_client_state() which returns VGA_SWITCHEROO_INIT instead of VGA_SWITCHEROO_OFF. - Consequence: azx_probe() tries to initialize the audio controller even though the GPU is powered down. The power state VGA_SWITCHEROO_INIT was introduced by c8e9cf7bb240 ("vga_switcheroo: Add a helper function to get the client state"). It is not apparent what its benefit might be. The idea seems to be to initialize the audio controller even if the power state is VGA_SWITCHEROO_OFF (were vga_switcheroo enabled), but as shown above this can fail. Drop VGA_SWITCHEROO_INIT to solve this. Acked-by: Takashi Iwai <> Signed-off-by: Lukas Wunner <> Signed-off-by: Dave Airlie <>
2015-10-20vga_switcheroo: Constify vga_switcheroo_handlerLukas Wunner1-2/+2
vga_switcheroo_client_ops has always been declared const since its introduction with 26ec685ff9d9 ("vga_switcheroo: Introduce struct vga_switcheroo_client_ops"). Do so for vga_switcheroo_handler as well. drivers/gpu/drm/amd/amdgpu/amdgpu.ko: 6 .rodata 00009888 - 19 .data 00001f00 + 19 .data 00001ee0 drivers/gpu/drm/nouveau/nouveau.ko: 6 .rodata 000460b8 17 .data 00018fe0 drivers/gpu/drm/radeon/radeon.ko: - 7 .rodata 00030944 + 7 .rodata 00030964 - 21 .data 0000d6a0 + 21 .data 0000d678 drivers/platform/x86/apple-gmux.ko: - 7 .rodata 00000140 + 7 .rodata 00000160 - 11 .data 000000e0 + 11 .data 000000b8 Cc: Ben Skeggs <> Cc: Darren Hart <> Cc: Alex Deucher <> Signed-off-by: Lukas Wunner <> Reviewed-by: Christian König <>. Signed-off-by: Daniel Vetter <>
2015-10-16vga_switcheroo: Use enum vga_switcheroo_client_id instead of intLukas Wunner1-7/+10
Signed-off-by: Lukas Wunner <> Reviewed-by: Alex Deucher <> Signed-off-by: Daniel Vetter <>
2015-10-16vga_switcheroo: Use VGA_SWITCHEROO_UNKNOWN_ID instead of -1Lukas Wunner1-8/+9
Signed-off-by: Lukas Wunner <> Reviewed-by: Alex Deucher <> Signed-off-by: Daniel Vetter <>
2015-10-16vga_switcheroo: Use enum vga_switcheroo_state instead of intLukas Wunner1-3/+3
Signed-off-by: Lukas Wunner <> Reviewed-by: Jani Nikula <> Reviewed-by: Alex Deucher <> Signed-off-by: Daniel Vetter <>
2015-10-02vga_switcheroo: Add missing lockingLukas Wunner1-18/+32
The following functions iterate over the client list, invoke client callbacks or invoke handler callbacks without locking anything at all: - Introduced by c8e9cf7bb240 ("vga_switcheroo: Add a helper function to get the client state"): vga_switcheroo_get_client_state() - Introduced by 0d69704ae348 ("gpu/vga_switcheroo: add driver control power feature. (v3)"): vga_switcheroo_set_dynamic_switch() vga_switcheroo_runtime_suspend() vga_switcheroo_runtime_resume() vga_switcheroo_runtime_resume_hdmi_audio() Refactor vga_switcheroo_runtime_resume_hdmi_audio() a bit to be able to release vgasr_mutex immediately after iterating over the client list. Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <>
2015-09-24vga_switcheroo: Set active attribute to false for audio clientsLukas Wunner1-4/+3
The active attribute in struct vga_switcheroo_client denotes whether the outputs are currently switched to this client. The attribute is only meaningful for vga clients. It is never used for audio clients. The function vga_switcheroo_register_audio_client() misuses this attribute to store whether the audio device is fully initialized. Most likely there was a misunderstanding about the meaning of "active" when this was added. Comment from Takashi's review: "Not really. The full initialization of audio was meant that the audio is active indeed. Admittedly, though, the active flag for each audio client doesn't play any role because the audio always follows the gfx state changes, and the value passed there doesn't reflect the actual state due to the later change. So, I agree with the removal of the flag itself -- or let the audio active flag following the corresponding gfx flag. The latter will make the proc output more consistent while the former is certainly more reduction of code." Set the active attribute to false for audio clients. Remove the active parameter from vga_switcheroo_register_audio_client() and its sole caller, hda_intel.c:register_vga_switcheroo(). vga_switcheroo_register_audio_client() was introduced by 3e9e63dbd374 ("vga_switcheroo: Add the support for audio clients"). Its use in hda_intel.c was introduced by a82d51ed24bb ("ALSA: hda - Support VGA-switcheroo"). v1.1: The changes above imply that in find_active_client() the call to client_is_vga() is now superfluous. Drop it. Cc: Takashi Iwai <> Signed-off-by: Lukas Wunner <> [danvet: Add Takashi's clarification to the commit message.] Reviewed-by: Takashi Iwai <> Signed-off-by: Daniel Vetter <>
2015-09-24vga_switcheroo: Sort headers alphabeticallyLukas Wunner1-8/+6
Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <>
2015-09-22vga_switcheroo: Document _ALL_ the things!Lukas Wunner1-14/+271
This adds an "Overview" DOC section plus two DOC sections for the modes of use ("Manual switching and manual power control" and "Driver power control"). Also included is kernel-doc for all public functions, structs and enums. Signed-off-by: Lukas Wunner <> Signed-off-by: Daniel Vetter <>
2015-08-12vga_switcheroo: Remove unnecessary checksThierry Reding1-8/+5
debugfs_remove() gracefully ignores NULL parameters, so the explicit checks can be removed. Signed-off-by: Thierry Reding <> Signed-off-by: Daniel Vetter <>
2015-08-12vga_switcheroo: Wrap overly long linesThierry Reding1-9/+24
Wrap overly long lines to make checkpatch happy. While at it, also add blank lines after declarations to eliminate additional problems flagged by checkpatch. Signed-off-by: Thierry Reding <> Signed-off-by: Daniel Vetter <>
2015-08-12vga_switcheroo: Use pr_fmt()Thierry Reding1-13/+18
Use pr_fmt() to define the "vga_switcheroo: " prefix that is prepended to all output messages emitted by pr_*() functions. This allows making existing strings much shorter and eliminates a bunch of warnings from checkpatch about lines being overly long. Signed-off-by: Thierry Reding <> Signed-off-by: Daniel Vetter <>
2015-08-12vga_switcheroo: Cleanup header commentThierry Reding1-9/+9
The header comment uses a weird combination of formatting styles. Make it consistent. Signed-off-by: Thierry Reding <> Signed-off-by: Daniel Vetter <>
2015-08-12vga_switcheroo: Use pr_*() instead of printk()Thierry Reding1-12/+12
This silences a bunch of checkpatch warnings and makes the code shorter. Signed-off-by: Thierry Reding <> Signed-off-by: Daniel Vetter <>
2014-09-18vgaswitcheroo: add vga_switcheroo_fini_domain_pm_opsAlex Deucher1-0/+6
Drivers should call this on unload to unregister pmops. Bug: Reviewed-by: Ben Skeggs <> Signed-off-by: Alex Deucher <> Cc: Signed-off-by: Pali Rohár <> Cc: Ben Skeggs <>
2014-06-02vgaswitcheroo: switch the mux to the igp on power down when runpm is enabledAlex Deucher1-1/+2
Avoids blank screens on muxed systems when runpm is active. bug: Signed-off-by: Alex Deucher <> Cc:
2013-08-29gpu/vga_switcheroo: add driver control power feature. (v3)Dave Airlie1-5/+142
For optimus and powerxpress muxless we really want the GPU driver deciding when to power up/down the GPU, not userspace. This adds the ability for a driver to dynamically power up/down the GPU and remove the switcheroo from controlling it, the switcheroo reports the dynamic state to userspace also. It also adds 2 power domains, one for machine where the power switch is controlled outside the GPU D3 state, so the powerdown ordering is done correctly, and the second for the hdmi audio device to make sure it can resume for PCI config space accesses. v1.1: fix build with switcheroo off v2: add power domain support for radeon and v1 nvidia dsms v2.1: fix typo in off case v3: add audio power domain for hdmi audio + misc audio fixes v4: use PCI_SLOT macro, drop power reference on hdmi audio resume failure also. Signed-off-by: Dave Airlie <>
2013-02-08fbcon: fix locking harderDave Airlie1-0/+3
Okay so Alan's patch handled the case where there was no registered fbcon, however the other path entered in set_con2fb_map pit. In there we called fbcon_takeover, but we also took the console lock in a couple of places. So push the console lock out to the callers of set_con2fb_map, this means fbmem and switcheroo needed to take the lock around the fb notifier entry points that lead to this. This should fix the efifb regression seen by Maarten. Tested-by: Maarten Lankhorst <> Tested-by: Lu Hua <> Signed-off-by: Dave Airlie <>
2012-11-20vga_switcheroo: Drop unused include and unused variables.Igor Murzov1-6/+0
Signed-off-by: Igor Murzov <> Signed-off-by: Dave Airlie <>
2012-08-17vga_switcheroo: Don't require handler init callbackSeth Forshee1-1/+2
This callback is a no-op in nouveau, and the upcoming apple-gmux switcheroo support won't require it either. Rather than forcing drivers to stub it out, just make it optional and remove the callback from nouveau. Signed-off-by: Seth Forshee <> Signed-off-by: Matthew Garrett <>
2012-08-17vga_switcheroo: Remove assumptions about registration/unregistration orderingSeth Forshee1-22/+36
vga_switcheroo assumes that the handler will be registered before the last client, otherwise switching will not be enabled. Likewise it's assumed that the handler will not be unregistered without at least one client also being unregistered, otherwise switching will remain enabled despite no longer having a handler. These assumptions cannot be enforced if the handler is in a separate driver from both clients, as with the gmux found in Apple laptops. Remove this assumption. Signed-off-by: Seth Forshee <> Signed-off-by: Matthew Garrett <>
2012-06-09vga_switcheroo: Enable/disable audio clients at the right timeTakashi Iwai1-6/+8
The audio clients have to be disabled before disabling the VGA and switching. Similarly, enabling the audio client should be done at last. Otherwise the audio-side operation stalls, eventually leading to Oops or lockups. Tested-by: Jörg-Volker Peetz <> Acked-by: Dave Airlie <> Signed-off-by: Takashi Iwai <>
2012-06-08vga_switcheroo: Add a helper function to get the client stateTakashi Iwai1-0/+13
Add vga_switcheroo_get_client_state() to get the current state of the client. This is necessary to determine the proper initial state of audio clients in HD-audio driver. Acked-by: Dave Airlie <> Signed-off-by: Takashi Iwai <>
2012-05-13vga_switcheroo: Add the support for audio clientsTakashi Iwai1-14/+56
Add the support for audio clients to VGA-switcheroo for handling the HDMI audio controller together with VGA switching. The id of the audio controller should be given explicitly at registration time unlike the video controller. Bugzilla: Signed-off-by: Takashi Iwai <>
2012-05-13vga_switcheroo: Introduce struct vga_switcheroo_client_opsTakashi Iwai1-14/+8
This changes the API as a clean-up. Instead of passing multiple function pointers at each time, introduce a new struct holding the whole callback functions and pass it to the registration. The same struct will be used for the upcoming audio client registration, too. Signed-off-by: Takashi Iwai <>
2012-05-13vga_switcheroo: Refactor using linked listTakashi Iwai1-99/+110
Refactor the code base a bit for the further work to adapt more clients. Signed-off-by: Takashi Iwai <>
2012-04-24vga-switcheroo: Use vga_default_device()Matthew Garrett1-4/+5
vga-switcheroo currently changes the default VGA device by fiddling with the IORESOURCE_ROM_SHADOW flag on the device. This isn't strictly accurate, since there's no guarantee that switching also changes the ROM decoding. Switch over to using the vgaarb functions for this. Signed-off-by: Matthew Garrett <> Signed-off-by: Dave Airlie <>
2011-05-24Merge branch 'drm-core-next' of ↵Linus Torvalds1-6/+0
git:// * 'drm-core-next' of git:// (169 commits) drivers/gpu/drm/radeon/atom.c: fix warning drm/radeon/kms: bump kms version number drm/radeon/kms: properly set num banks for fusion asics drm/radeon/kms/atom: move dig phy init out of modesetting drm/radeon/kms/cayman: fix typo in register mask drm/radeon/kms: fix typo in spread spectrum code drm/radeon/kms: fix tile_config value reported to userspace on cayman. drm/radeon/kms: fix incorrect comparison in cayman setup code. drm/radeon/kms: add wait idle ioctl for eg->cayman drm/radeon/cayman: setup hdp to invalidate and flush when asked drm/radeon/evergreen/btc/fusion: setup hdp to invalidate and flush when asked agp/uninorth: Fix lockups with radeon KMS and >1x. drm/radeon/kms: the SS_Id field in the LCD table if for LVDS only drm/radeon/kms: properly set the CLK_REF bit for DCE3 devices drm/radeon/kms: fixup eDP connector handling drm/radeon/kms: bail early for eDP in hotplug callback drm/radeon/kms: simplify hotplug handler logic drm/radeon/kms: rewrite DP handling drm/radeon/kms/atom: add support for setting DP panel mode drm/radeon/kms: atombios.h updates for DP panel mode ...
2011-05-16vga_switcheroo: don't toggle-switch devicesFlorian Mickler1-3/+3
If the requested device is already active, ignore the request. This restores the original behaviour of the interface. The change was probably an unintended side effect of commit 66b37c6777c4 vga_switcheroo: split switching into two stages which did not take into account to duplicate the !active check in the split-off stage2. Fix this by factoring that check out of stage1 into the debugfs_write routine. References: Reported-by: Igor Murzov <> Tested-by: Igor Murzov <> Signed-off-by: Florian Mickler <> Signed-off-by: Dave Airlie <>
2011-05-04vga_switcheroo: Remove unbalanced pci_enable_deviceAlex Williamson1-6/+0
This is unbalanced and probably more fitting for the client to take care of. Remove it. Signed-off-by: Alex Williamson <> Signed-off-by: Dave Airlie <>
2011-01-07vga_switcheroo: comparing too few characters in strncmp()Dan Carpenter1-2/+2
This is a copy-and-paste bug. We should be comparing 4 characters here instead of 3. Signed-off-by: Dan Carpenter <> Signed-off-by: Dave Airlie <>
2011-01-05vga_switcheroo: split switching into two stages.Dave Airlie1-11/+34
stage 1: turn card on, switch boot vga pointer. stage 2: switch fbs, switch mux and power off old card. Signed-off-by: Dave Airlie <>
2011-01-05vga_switcheroo: add reprobe hook for fbcon to recheck connected outputs.Dave Airlie1-0/+6
This adds a hook after the mux is switched for the driver to reprobe the connected outputs. Signed-off-by: Dave Airlie <>
2011-01-05vga_switcheroo: add debugging mux switch option.Dave Airlie1-0/+16
This allows the mux to be switched from userspace using MIGD/MDIS command to the switch. Signed-off-by: Dave Airlie <>