VGA 切换¶
vga_switcheroo 是 Linux 子系统,用于笔记本电脑的混合图形。它们有两种类型
复用型:双 GPU,带有一个多路复用器芯片,用于在 GPU 之间切换输出。
无复用型:双 GPU,但只有一个连接到输出。另一个仅用于卸载渲染,其结果通过 PCIe 复制到帧缓冲。在 Linux 上,这通过 DRI PRIME 支持。
混合图形在 2000 年代后期开始出现,最初都是复用型的。较新的笔记本电脑出于成本原因转向了无复用架构。一个值得注意的例外是 MacBook Pro,它继续使用多路复用器。多路复用器具有不同的功能:一些仅切换面板,另一些还可以切换外部显示器。一些同时切换所有显示引脚,而另一些则只能切换 DDC 线。(允许探测非活动 GPU 的 EDID。)此外,多路复用器通常用于在未使用独立 GPU 时切断其电源。
DRM 驱动程序使用 vga_switcheroo 注册 GPU,这些 GPU 此后被称为客户端。多路复用器称为处理程序。无复用机器还会注册一个处理程序来控制独立 GPU 的电源状态,出于显而易见的原因,其 ->switchto 回调是一个空操作。独立 GPU 通常配备用于 HDMI/DP 音频信号的 HDA 控制器,它也会注册为客户端,以便 vga_switcheroo 可以在更改独立 GPU 的电源状态时处理正确的挂起/恢复顺序。因此,总共最多可以有三个客户端:两个 VGA 客户端(GPU)和一个音频客户端(在独立 GPU 上)。代码主要准备好支持具有两个以上 GPU 的机器,如果它们可用的话。
当前切换到输出的 GPU 在 vga_switcheroo 术语中称为活动客户端。未使用的 GPU 是非活动客户端。当加载非活动客户端的 DRM 驱动程序时,它将无法探测面板的 EDID,因此依赖于 VBIOS 来提供其显示模式。如果 VBIOS 模式是虚假的,或者根本没有 VBIOS(这在 MacBook Pro 上很常见),则客户端可以选择请求将 DDC 线临时切换到它,前提是处理程序支持此功能。仅切换 DDC 线而不切换整个输出可以避免不必要的闪烁。
使用模式¶
手动切换和手动电源控制¶
在这种使用模式下,可以读取文件 /sys/kernel/debug/vgaswitcheroo/switch 来检索当前的 vga_switcheroo 状态,并且可以向其中写入命令来更改状态。一旦两个 GPU 驱动程序和一个处理程序在 vga_switcheroo 中注册,该文件就会出现。以下命令被理解
OFF:关闭未使用的设备的电源。
ON:打开未使用的设备的电源。
IGD:切换到集成图形设备。如果需要,打开集成 GPU 的电源,关闭独立 GPU 的电源。前提是用户空间进程(例如 Xorg、alsactl)没有打开 GPU 或音频客户端的设备文件。如果切换失败,用户可以在 /dev/dri/ 和 /dev/snd/controlC1 上调用 lsof(8) 或 fuser(1) 来识别阻止切换的进程。
DIS:切换到独立图形设备。
DIGD:延迟切换到集成图形设备。一旦最后一个用户空间进程关闭了 GPU 和音频客户端的设备文件,就会执行此切换。
DDIS:延迟切换到独立图形设备。
MIGD:仅多路复用切换到集成图形设备。不重新映射控制台或更改任何一个 GPU 的电源状态。如果集成 GPU 当前处于关闭状态,屏幕将变为黑色。如果它处于打开状态,屏幕将显示 VRAM 中碰巧存在的内容。无论哪种方式,用户都必须盲目地输入命令才能切换回来。
MDIS:仅多路复用切换到独立图形设备。
对于电源状态由驱动程序的运行时 pm 控制的 GPU,ON 和 OFF 命令是空操作(请参阅下一节)。
对于无复用机器,不应使用 IGD/DIS、DIGD/DDIS 和 MIGD/MDIS 命令。
驱动程序电源控制¶
在这种使用模式下,独立 GPU 会自动根据驱动程序的运行时 pm 的决定来打开和关闭电源。在复用机器上,用户仍然可以通过 debugfs 接口影响多路复用器状态,但是 ON 和 OFF 命令对于独立 GPU 来说是空操作。
这种模式是 Nvidia HybridPower/Optimus 和 ATI PowerXpress 上的默认模式。在内核命令行上指定 nouveau.runpm=0、radeon.runpm=0 或 amdgpu.runpm=0 会禁用它。
在 GPU 挂起后,需要调用处理程序以切断 GPU 的电源。同样,在 GPU 恢复之前,需要恢复电源。这是通过 vga_switcheroo_init_domain_pm_ops()
实现的,它通过对处理程序的必要调用来增强 GPU 的挂起/恢复功能。
当音频设备恢复时,需要唤醒 GPU。这是通过一个 PCI 怪癖实现的,该怪癖调用 device_link_add()
来声明对 GPU 的依赖关系。这样,只要音频设备正在使用,GPU 就会保持唤醒状态。
在复用机器上,如果多路复用器最初切换到独立 GPU,则当 GPU 在启动后关闭电源时,用户最终会看到黑屏。作为一种解决方法,在运行时挂起时,强制将多路复用器切换到集成 GPU,请参阅 https://bugs.freedesktop.org/show_bug.cgi?id=75917
API¶
公共函数¶
-
int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, enum vga_switcheroo_handler_flags_t handler_flags)¶
注册处理程序
参数
const struct vga_switcheroo_handler *handler
处理程序回调
enum vga_switcheroo_handler_flags_t handler_flags
处理程序标志
描述
注册处理程序。如果已注册两个 VGA 客户端,则启用 vga_switcheroo。
返回值
成功时返回 0,如果已注册处理程序,则返回 -EINVAL。
-
void vga_switcheroo_unregister_handler(void)¶
注销处理程序
参数
void
无参数
描述
注销处理程序。禁用 vga_switcheroo。
-
enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void)¶
获取处理程序标志
参数
void
无参数
描述
用于客户端获取处理程序标志位掩码的助手。
返回值
处理程序标志。值为 0 表示未注册处理程序或该处理程序没有特殊功能。
-
int vga_switcheroo_register_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, bool driver_power_control)¶
注册 VGA 客户端
参数
struct pci_dev *pdev
客户端 PCI 设备
const struct vga_switcheroo_client_ops *ops
客户端回调
bool driver_power_control
电源状态是否由驱动程序的运行时 pm 控制
描述
注册 VGA 客户端 (GPU)。如果已注册另一个 GPU 和一个处理程序,则启用 vga_switcheroo。客户端的电源状态假定为 ON。在此之前,应调用 vga_switcheroo_client_probe_defer()
以确保满足所有先决条件。
返回值
成功时返回 0,内存分配错误时返回 -ENOMEM。
-
int vga_switcheroo_register_audio_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, struct pci_dev *vga_dev)¶
注册音频客户端
参数
struct pci_dev *pdev
客户端 PCI 设备
const struct vga_switcheroo_client_ops *ops
客户端回调
struct pci_dev *vga_dev
绑定到当前音频客户端的 PCI 设备
描述
注册音频客户端(GPU 上的音频设备)。 假定客户端使用运行时 PM。 事先应调用 vga_switcheroo_client_probe_defer()
以确保满足所有先决条件。
返回值
成功时返回 0,内存分配错误时返回 -ENOMEM,获取客户端 ID 错误时返回 -EINVAL。
-
bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)¶
是否延迟探测给定客户端
参数
struct pci_dev *pdev
客户端 PCI 设备
描述
确定是否未满足任何探测给定客户端的先决条件。驱动程序应在其 ->probe 回调中尽早调用此函数,如果其计算结果为 true
,则返回 -EPROBE_DEFER
。 在调用此函数之前,不应注册客户端。
返回值
如果应延迟探测,则返回 true
,否则返回 false
。
-
enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)¶
获取给定客户端的电源状态
参数
struct pci_dev *pdev
客户端 PCI 设备
描述
从 vga_switcheroo 中获取给定客户端的电源状态。 该函数仅从 hda_intel.c 中调用。
返回值
电源状态。
-
void vga_switcheroo_unregister_client(struct pci_dev *pdev)¶
注销客户端
参数
struct pci_dev *pdev
客户端 PCI 设备
描述
注销客户端。 如果这是 VGA 客户端 (GPU),则禁用 vga_switcheroo。
-
void vga_switcheroo_client_fb_set(struct pci_dev *pdev, struct fb_info *info)¶
设置给定客户端的帧缓冲
参数
struct pci_dev *pdev
客户端 PCI 设备
struct fb_info *info
帧缓冲
描述
设置给定客户端的帧缓冲。 控制台将在切换时重新映射到此。
-
int vga_switcheroo_lock_ddc(struct pci_dev *pdev)¶
暂时将 DDC 线切换到给定客户端
参数
struct pci_dev *pdev
客户端 PCI 设备
描述
暂时将 DDC 线切换到由 **pdev** 标识的客户端(但将输出保持切换到它们所在的任何位置)。 这允许非活动客户端探测 EDID。 DDC 线必须在之后通过调用 vga_switcheroo_unlock_ddc()
切换回来,即使此函数返回错误也是如此。
返回值
成功时返回先前的 DDC 所有者,或在出错时返回负整数。 具体而言,如果未注册处理程序或处理程序不支持切换 DDC 线,则返回 -ENODEV
。 此外,处理程序返回的负值会传播回调用方。 返回值仅对任何可能对其感兴趣的调用方具有信息性目的。 可以忽略返回值,而仅依赖于后续 EDID 探测的结果,如果 DDC 切换失败,则该结果将为 NULL
。
-
int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)¶
将 DDC 线切换回先前的所有者
参数
struct pci_dev *pdev
客户端 PCI 设备
描述
在调用 vga_switcheroo_lock_ddc()
后,将 DDC 线切换回先前的所有者。 即使 vga_switcheroo_lock_ddc()
返回错误,也必须调用此函数。
返回值
成功时返回先前的 DDC 所有者(即 **pdev** 的客户端标识符),或在出错时返回负整数。 具体而言,如果未注册处理程序或处理程序不支持切换 DDC 线,则返回 -ENODEV
。 此外,处理程序返回的负值会传播回调用方。 最后,不允许在未首先调用 vga_switcheroo_lock_ddc()
的情况下调用此函数,这将导致 -EINVAL
。
-
int vga_switcheroo_process_delayed_switch(void)¶
延迟切换的帮助程序
参数
void
无参数
描述
如果存在挂起的延迟切换,则进行处理。
返回值
成功时返回 0。如果没有挂起的延迟切换、客户端在此期间已注销或有其他客户端阻止切换,则返回 -EINVAL。 如果实际切换失败,则报告错误并返回 0。
-
int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain)¶
驱动程序电源控制的帮助程序
参数
struct device *dev
VGA 客户端设备
struct dev_pm_domain *domain
电源域
描述
对于其电源状态由驱动程序的运行时 pm 控制的 GPU 的帮助程序。 在 GPU 挂起后,需要调用处理程序以切断 GPU 的电源。 同样,在 GPU 恢复之前,它需要恢复电源。 为此,此帮助程序通过对处理程序的必要调用来扩充挂起/恢复函数。 它只需要在电源开关与正在断电的设备分离的平台上调用。
公共结构¶
-
struct vga_switcheroo_handler¶
处理程序回调
定义:
struct vga_switcheroo_handler {
int (*init)(void);
int (*switchto)(enum vga_switcheroo_client_id id);
int (*switch_ddc)(enum vga_switcheroo_client_id id);
int (*power_state)(enum vga_switcheroo_client_id id, enum vga_switcheroo_state state);
enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev);
};
成员
init
初始化处理程序。 可选。当启用 vga_switcheroo 时(即当两个 VGA 客户端注册时)会调用此函数。它允许处理程序执行一些依赖于 VGA 客户端存在的延迟初始化。当前只有 radeon 和 amdgpu 驱动程序使用此函数。返回值将被忽略
switchto
将输出切换到指定客户端。 必须项。 对于无多路复用器的机器,这应为空操作。 返回 0 表示成功,任何其他值表示失败(在这种情况下,切换将中止)
switch_ddc
将 DDC 线切换到指定客户端。 可选项。 成功时应返回之前的 DDC 所有者,失败时返回负整数
power_state
断开或恢复指定客户端的电源。 可选项。 返回值将被忽略
get_client_id
确定给定的 PCI 设备是集成 GPU 还是独立 GPU。 必须项
描述
处理程序回调。 多路复用器本身。switchto 和 get_client_id 方法是必须的,所有其他方法都可以设置为 NULL。
-
struct vga_switcheroo_client_ops¶
客户端回调
定义:
struct vga_switcheroo_client_ops {
void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
void (*reprobe)(struct pci_dev *dev);
bool (*can_switch)(struct pci_dev *dev);
void (*gpu_bound)(struct pci_dev *dev, enum vga_switcheroo_client_id);
};
成员
set_gpu_state
对卡执行等效的挂起/恢复操作。 必须项。 这不应切断独立 GPU 的电源,这是处理程序的工作
reprobe
轮询输出。 可选项。 这会在唤醒 GPU 并将其输出切换到它之后调用
can_switch
检查设备是否处于现在可以切换的位置。 必须项。 如果用户空间进程打开了它的一个设备文件,则客户端应返回 false
gpu_bound
当 GPU 被绑定时通知音频客户端客户端 ID。
描述
客户端回调。 客户端可以是 GPU 或 GPU 上的音频设备。set_gpu_state 和 can_switch 方法是必须的,reprobe 可以设置为 NULL。 对于音频客户端,reprobe 成员是无效的。 另一方面,gpu_bound 仅用于音频客户端,而不用于 GPU 客户端。
公共常量¶
-
enum vga_switcheroo_handler_flags_t¶
处理程序标志位掩码
常量
VGA_SWITCHEROO_CAN_SWITCH_DDC
处理程序是否能够单独切换 DDC 线。 这向客户端发出信号,指示它们应该调用
drm_get_edid_switcheroo()
来探测 EDIDVGA_SWITCHEROO_NEEDS_EDP_CONFIG
处理程序是否无法单独切换 AUX 通道。 这向客户端发出信号,指示活动的 GPU 需要训练链路并将链路参数传递给不活动的 GPU(由 vga_switcheroo 调解)。 然后,不活动的 GPU 可以跳过 AUX 握手,并使用这些预校准值设置其输出(DisplayPort 规范 v1.1a,第 2.5.3.3 节)
描述
处理程序标志位掩码。 由处理程序用于声明它们在向 vga_switcheroo 注册时的功能。
-
enum vga_switcheroo_client_id¶
客户端标识符
常量
VGA_SWITCHEROO_UNKNOWN_ID
分配给 vga 客户端的初始标识符。 确定 ID 需要处理程序,因此 GPU 在 vga_switcheroo_enable() 中以延迟方式获得其真实 ID
VGA_SWITCHEROO_IGD
集成图形设备
VGA_SWITCHEROO_DIS
独立图形设备
VGA_SWITCHEROO_MAX_CLIENTS
目前仅支持最多两个 GPU
描述
客户端标识符。 音频客户端使用相同的标识符 & 0x100。
-
enum vga_switcheroo_state¶
客户端电源状态
常量
VGA_SWITCHEROO_OFF
关闭
VGA_SWITCHEROO_ON
开启
VGA_SWITCHEROO_NOT_FOUND
客户端未在 vga_switcheroo 中注册。 仅在
vga_switcheroo_get_client_state()
中使用,而vga_switcheroo_get_client_state()
又仅从 hda_intel.c 中调用
描述
客户端电源状态。
私有结构¶
-
struct vgasr_priv¶
vga_switcheroo 私有数据
定义:
struct vgasr_priv {
bool active;
bool delayed_switch_active;
enum vga_switcheroo_client_id delayed_client_id;
struct dentry *debugfs_root;
int registered_clients;
struct list_head clients;
const struct vga_switcheroo_handler *handler;
enum vga_switcheroo_handler_flags_t handler_flags;
struct mutex mux_hw_lock;
int old_ddc_owner;
};
成员
active
是否启用 vga_switcheroo。 先决条件是注册两个 GPU 和一个处理程序
delayed_switch_active
是否正在等待延迟切换
delayed_client_id
正在等待延迟切换的客户端
debugfs_root
vga_switcheroo debugfs 接口的目录
registered_clients
注册的 GPU 数量(仅计算 vga 客户端,不计算音频客户端)
clients
注册的客户端列表
handler
注册的处理程序
handler_flags
注册的处理程序的标志
mux_hw_lock
保护多路复用器状态(尤其是在临时切换 DDC 线时)
old_ddc_owner
DDC 线在解锁时将切换回的客户端
描述
vga_switcheroo 私有数据。 目前,每个系统仅支持一个 vga_switcheroo 实例。
-
struct vga_switcheroo_client¶
注册的客户端
定义:
struct vga_switcheroo_client {
struct pci_dev *pdev;
struct fb_info *fb_info;
enum vga_switcheroo_state pwr_state;
const struct vga_switcheroo_client_ops *ops;
enum vga_switcheroo_client_id id;
bool active;
bool driver_power_control;
struct list_head list;
struct pci_dev *vga_dev;
};
成员
pdev
客户端 PCI 设备
fb_info
在切换时将控制台重新映射到的帧缓冲器
pwr_state
如果使用手动电源控制,则为当前电源状态。 对于驱动程序电源控制,请调用 vga_switcheroo_pwr_state()。
ops
客户端回调
id
客户端标识符。 确定 ID 需要处理程序,因此 GPU 最初被分配 VGA_SWITCHEROO_UNKNOWN_ID,然后在 vga_switcheroo_enable() 中获得其真实 ID
active
输出当前是否已切换到此客户端
driver_power_control
电源状态是否由驱动程序的运行时 pm 控制。 如果为 true,则向 vga_switcheroo debugfs 接口写入 ON 和 OFF 将不起作用,以免干扰运行时 pm
list
客户端列表
vga_dev
pci 设备,指示哪个 GPU 绑定到当前音频客户端
描述
注册的客户端。 客户端可以是 GPU 或 GPU 上的音频设备。 对于音频客户端,fb_info 和 active 成员是无效的。 对于 GPU 客户端,vga_dev 是无效的。
处理程序¶
apple-gmux 处理程序¶
gmux 是内置在 MacBook Pro 中的微控制器,用于支持双 GPU:pre-retina 上的 Lattice XP2,pre-T2 retina 上的 Renesas R4F2113。
在 T2 Macbooks 上,gmux 是 T2 协处理器 SMC 的一部分。 SMC 与一个 NXP PCAL6524 GPIO 扩展器具有 I2C 连接,该扩展器启用/禁用独立 GPU 的稳压器,驱动显示面板电源,并具有一个 GPIO 来切换 eDP 多路复用器。 Intel CPU 可以通过 MMIO 与 gmux 交互,类似于控制主 SMC 接口的方式。
(MacPro6,1 2013 也有一个 gmux,但不清楚为什么,因为它有双 GPU 但没有内置显示器。)
gmux 连接到南桥的 LPC 总线。 根据微控制器的不同,其 I/O 端口的访问方式也不同:访问 pre-retina gmux 的驱动程序函数以 _pio_
作为后缀,访问 pre-T2 retina gmux 的驱动程序函数以 _index_
作为后缀,而 T2 Mac 上的驱动程序函数以 _mmio_
作为后缀。
gmux 还连接到南桥的 GPIO 引脚,从而能够触发 ACPI GPE。 ACPI 名称 GMGP 保存着此 GPIO 引脚的编号。 在 MBP5 2008/09 上,它是 Nvidia MCP79 的 GPIO 引脚 22,在后续几代中,它是 Intel PCH 的 GPIO 引脚 6,在 MMIO gmux 上,它是引脚 21。
GPE 仅表示发生了中断,实际的事件类型通过读取 gmux 寄存器来识别。
除了 GMGP 名称之外,gmux 的 ACPI 设备还具有两个方法 GMSP 和 GMLV。 GMLV 可能表示“GMUX Level”,并读取 GPIO 的值,而 GMSP 可能表示“GMUX Set Polarity”,并且似乎写入 GPIO 的值。 在较新的 Macbooks 上(这是在 MacBookPro14,3 或之前引入的),ACPI GPE 方法区分 OS 类型:在 Darwin 上,仅发出通知信号,而在其他 OS 上,读取 GPIO 的值,然后反转。
由于 Linux 伪装成 Darwin,因此最终进入了仅通知代码路径。 在 MMIO gmux 上,这似乎导致我们无法清除中断,除非我们调用 GMSP(0)。 如果没有此操作,则会发生大量无法清除的 status=0 中断。 此问题似乎是 MMIO gmux 独有的。
图形多路复用器¶
在 pre-retina 上,两个 GPU 的 LVDS 输出都馈入 gmux,gmux 将其中一个多路复用到面板。 gmux 的一个诀窍是在切换期间延长其输出的消隐间隔,以使其与切换到的 GPU 同步。 这可以实现用户无法察觉的无闪烁切换 (US 8,687,007 B2)。
在Retina显示屏上,多路复用不再由gmux本身完成,而是由一个单独的芯片控制,该芯片由gmux控制。该芯片有三个供应商,分别是恩智浦 CBTL06142、德州仪器 HD3SS212 或 Pericom PI3VDP12412。面板采用eDP驱动而不是LVDS,因为Retina分辨率所需的像素时钟超过了LVDS的限制。
Retina之前的型号能够单独切换面板的DDC引脚。这由一个德州仪器 SN74LV4066A 处理,该芯片由gmux控制。因此,不活动的GPU可以在不切换整个面板的情况下探测面板的EDID。Retina型号缺少此功能,因为用于eDP多路复用的芯片无法单独切换AUX通道(请参阅相关的数据表,Pericom可以实现,但未使用)。但是,Retina面板的DPCD中设置了NO_AUX_HANDSHAKE_LINK_TRAINING位,允许不活动的GPU跳过AUX握手,并使用活动GPU预校准的链路参数设置输出。
外部DP端口仅在前两个一体式MacBook Pro型号上完全可切换,即MBP5 2008/09和MBP6 2010。这是由一个恩智浦 CBTL06141 完成的,该芯片由gmux控制。它是Retina上eDP多路复用的前身,区别在于支持2.7与5.4 Gbit/s的速度。
后续的MacBook Pro型号用组合的DP/Thunderbolt端口取代了外部DP端口,并失去了在GPU之间切换该端口的能力,将其连接到独立GPU或Thunderbolt控制器。奇怪的是,虽然整个端口不再可切换,但AUX和HPD仍然可以通过恩智浦 CBTL03062(在Retina之前的MBP8 2011和MBP9 2012上)或两个德州仪器 TS3DS10224(在Retina之前的型号上)在gmux的控制下进行切换。由于集成GPU缺少主链路,外部显示器对它来说表现为无法链路训练的幻影。
gmux接收所有显示连接器的HPD信号,并在热插拔时发送中断。在无法切换外部端口的型号上,可以唤醒独立GPU来驱动新连接的显示器。在这些型号上,切换AUX的能力可以用于提高热插拔检测的可靠性,让集成GPU在独立GPU处于休眠状态时轮询端口,但目前我们没有使用此功能。
我们的外部端口切换策略是,在能够完全切换的型号上,当向vga_switcheroo发出IGD / DIS命令时,端口与面板一起切换。因此,可以使用集成GPU在电池供电的情况下驱动例如投影仪。如果需要更高的性能,用户可以手动切换到独立GPU。
在所有较新的型号上,外部端口只能由独立GPU驱动。如果在面板切换到集成GPU时插入显示器,两个GPU都将用于最大性能。为了降低功耗,用户可以手动切换到独立GPU,从而暂停集成GPU。
gmux在启动时的初始切换状态通过EFI变量gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9
(第5个字节,1 = IGD,0 = DIS)进行用户配置。基于此设置,EFI固件会告诉gmux切换面板和外部DP连接器,并为选定的GPU分配帧缓冲区。
电源控制¶
gmux能够切断独立GPU的电源。它会自动处理用于核心电压、VRAM和PCIe的电源轨的正确拆除和启动顺序。
背光控制¶
在单GPU MacBook上,背光的PWM信号由GPU生成。相比之下,在双GPU MacBook Pro上,可以暂停任一GPU以节省能量。因此,PWM信号需要由一个单独的背光驱动器生成,该驱动器由gmux控制。最早的MBP5 2008/09型号使用德州仪器 LP8543背光驱动器。较新的型号使用德州仪器 LP8545或德州仪器 LP8548。
公共函数¶
参数
struct pnp_dev *pnp_dev
要探测的设备,如果为NULL,则使用第一个匹配的设备
enum apple_gmux_type *type_ret
返回(通过引用)设备的apple_gmux_type
描述
通过实际探测来检测是否存在支持的gmux设备。这避免了apple_gmux_present()
在某些型号上返回的误报。
返回值
如果检测到受支持的gmux ACPI设备并且内核已使用CONFIG_APPLE_GMUX配置,则返回true
,否则返回false
。
-
bool apple_gmux_present(void)¶
检查是否存在gmux ACPI设备
参数
void
无参数
描述
驱动程序可以使用它来激活特定于双GPU MacBook Pro和Mac Pro的怪癖,例如延迟探测、运行时pm和背光。
返回值
如果存在gmux ACPI设备并且内核已使用CONFIG_APPLE_GMUX配置,则返回true
,否则返回false
。