Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * vga_switcheroo.h - Support for laptop with dual GPU using one set of outputs
  3.  *
  4.  * Copyright (c) 2010 Red Hat Inc.
  5.  * Author : Dave Airlie <airlied@redhat.com>
  6.  *
  7.  * Copyright (c) 2015 Lukas Wunner <lukas@wunner.de>
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice (including the next
  17.  * paragraph) shall be included in all copies or substantial portions of the
  18.  * Software.
  19.  *
  20.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  23.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS
  27.  * IN THE SOFTWARE.
  28.  *
  29.  */
  30.  
  31. #ifndef _LINUX_VGA_SWITCHEROO_H_
  32. #define _LINUX_VGA_SWITCHEROO_H_
  33.  
  34. #include <linux/fb.h>
  35.  
  36. struct pci_dev;
  37.  
  38. /**
  39.  * enum vga_switcheroo_handler_flags_t - handler flags bitmask
  40.  * @VGA_SWITCHEROO_CAN_SWITCH_DDC: whether the handler is able to switch the
  41.  *      DDC lines separately. This signals to clients that they should call
  42.  *      drm_get_edid_switcheroo() to probe the EDID
  43.  * @VGA_SWITCHEROO_NEEDS_EDP_CONFIG: whether the handler is unable to switch
  44.  *      the AUX channel separately. This signals to clients that the active
  45.  *      GPU needs to train the link and communicate the link parameters to the
  46.  *      inactive GPU (mediated by vga_switcheroo). The inactive GPU may then
  47.  *      skip the AUX handshake and set up its output with these pre-calibrated
  48.  *      values (DisplayPort specification v1.1a, section 2.5.3.3)
  49.  *
  50.  * Handler flags bitmask. Used by handlers to declare their capabilities upon
  51.  * registering with vga_switcheroo.
  52.  */
  53. enum vga_switcheroo_handler_flags_t {
  54.         VGA_SWITCHEROO_CAN_SWITCH_DDC   = (1 << 0),
  55.         VGA_SWITCHEROO_NEEDS_EDP_CONFIG = (1 << 1),
  56. };
  57.  
  58. /**
  59.  * enum vga_switcheroo_state - client power state
  60.  * @VGA_SWITCHEROO_OFF: off
  61.  * @VGA_SWITCHEROO_ON: on
  62.  * @VGA_SWITCHEROO_NOT_FOUND: client has not registered with vga_switcheroo.
  63.  *      Only used in vga_switcheroo_get_client_state() which in turn is only
  64.  *      called from hda_intel.c
  65.  *
  66.  * Client power state.
  67.  */
  68. enum vga_switcheroo_state {
  69.         VGA_SWITCHEROO_OFF,
  70.         VGA_SWITCHEROO_ON,
  71.         /* below are referred only from vga_switcheroo_get_client_state() */
  72.         VGA_SWITCHEROO_NOT_FOUND,
  73. };
  74.  
  75. /**
  76.  * enum vga_switcheroo_client_id - client identifier
  77.  * @VGA_SWITCHEROO_UNKNOWN_ID: initial identifier assigned to vga clients.
  78.  *      Determining the id requires the handler, so GPUs are given their
  79.  *      true id in a delayed fashion in vga_switcheroo_enable()
  80.  * @VGA_SWITCHEROO_IGD: integrated graphics device
  81.  * @VGA_SWITCHEROO_DIS: discrete graphics device
  82.  * @VGA_SWITCHEROO_MAX_CLIENTS: currently no more than two GPUs are supported
  83.  *
  84.  * Client identifier. Audio clients use the same identifier & 0x100.
  85.  */
  86. enum vga_switcheroo_client_id {
  87.         VGA_SWITCHEROO_UNKNOWN_ID = -1,
  88.         VGA_SWITCHEROO_IGD,
  89.         VGA_SWITCHEROO_DIS,
  90.         VGA_SWITCHEROO_MAX_CLIENTS,
  91. };
  92.  
  93. /**
  94.  * struct vga_switcheroo_handler - handler callbacks
  95.  * @init: initialize handler.
  96.  *      Optional. This gets called when vga_switcheroo is enabled, i.e. when
  97.  *      two vga clients have registered. It allows the handler to perform
  98.  *      some delayed initialization that depends on the existence of the
  99.  *      vga clients. Currently only the radeon and amdgpu drivers use this.
  100.  *      The return value is ignored
  101.  * @switchto: switch outputs to given client.
  102.  *      Mandatory. For muxless machines this should be a no-op. Returning 0
  103.  *      denotes success, anything else failure (in which case the switch is
  104.  *      aborted)
  105.  * @switch_ddc: switch DDC lines to given client.
  106.  *      Optional. Should return the previous DDC owner on success or a
  107.  *      negative int on failure
  108.  * @power_state: cut or reinstate power of given client.
  109.  *      Optional. The return value is ignored
  110.  * @get_client_id: determine if given pci device is integrated or discrete GPU.
  111.  *      Mandatory
  112.  *
  113.  * Handler callbacks. The multiplexer itself. The @switchto and @get_client_id
  114.  * methods are mandatory, all others may be set to NULL.
  115.  */
  116. struct vga_switcheroo_handler {
  117.         int (*init)(void);
  118.         int (*switchto)(enum vga_switcheroo_client_id id);
  119.         int (*switch_ddc)(enum vga_switcheroo_client_id id);
  120.         int (*power_state)(enum vga_switcheroo_client_id id,
  121.                            enum vga_switcheroo_state state);
  122.         enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev);
  123. };
  124.  
  125. /**
  126.  * struct vga_switcheroo_client_ops - client callbacks
  127.  * @set_gpu_state: do the equivalent of suspend/resume for the card.
  128.  *      Mandatory. This should not cut power to the discrete GPU,
  129.  *      which is the job of the handler
  130.  * @reprobe: poll outputs.
  131.  *      Optional. This gets called after waking the GPU and switching
  132.  *      the outputs to it
  133.  * @can_switch: check if the device is in a position to switch now.
  134.  *      Mandatory. The client should return false if a user space process
  135.  *      has one of its device files open
  136.  *
  137.  * Client callbacks. A client can be either a GPU or an audio device on a GPU.
  138.  * The @set_gpu_state and @can_switch methods are mandatory, @reprobe may be
  139.  * set to NULL. For audio clients, the @reprobe member is bogus.
  140.  */
  141. struct vga_switcheroo_client_ops {
  142.         void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
  143.         void (*reprobe)(struct pci_dev *dev);
  144.         bool (*can_switch)(struct pci_dev *dev);
  145. };
  146.  
  147. #if defined(CONFIG_VGA_SWITCHEROO)
  148. void vga_switcheroo_unregister_client(struct pci_dev *dev);
  149. int vga_switcheroo_register_client(struct pci_dev *dev,
  150.                                    const struct vga_switcheroo_client_ops *ops,
  151.                                    bool driver_power_control);
  152. int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
  153.                                          const struct vga_switcheroo_client_ops *ops,
  154.                                          enum vga_switcheroo_client_id id);
  155.  
  156. void vga_switcheroo_client_fb_set(struct pci_dev *dev,
  157.                                   struct fb_info *info);
  158.  
  159. int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
  160.                                     enum vga_switcheroo_handler_flags_t handler_flags);
  161. void vga_switcheroo_unregister_handler(void);
  162. enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void);
  163. int vga_switcheroo_lock_ddc(struct pci_dev *pdev);
  164. int vga_switcheroo_unlock_ddc(struct pci_dev *pdev);
  165.  
  166. int vga_switcheroo_process_delayed_switch(void);
  167.  
  168. enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev);
  169.  
  170. void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic);
  171.  
  172. int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain);
  173. void vga_switcheroo_fini_domain_pm_ops(struct device *dev);
  174. int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain);
  175. #else
  176.  
  177. static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
  178. static inline int vga_switcheroo_register_client(struct pci_dev *dev,
  179.                 const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; }
  180. static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
  181. static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
  182.                 enum vga_switcheroo_handler_flags_t handler_flags) { return 0; }
  183. static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
  184.         const struct vga_switcheroo_client_ops *ops,
  185.         enum vga_switcheroo_client_id id) { return 0; }
  186. static inline void vga_switcheroo_unregister_handler(void) {}
  187. static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) { return 0; }
  188. static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; }
  189. static inline int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) { return -ENODEV; }
  190. static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
  191. static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
  192.  
  193. static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {}
  194.  
  195. static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; }
  196. static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {}
  197. static inline int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; }
  198.  
  199. #endif
  200. #endif /* _LINUX_VGA_SWITCHEROO_H_ */
  201.