PageRenderTime 25ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/gpu/vga/vga_switcheroo.c

https://bitbucket.org/ace0/linux-restore-support
C | 573 lines | 450 code | 93 blank | 30 comment | 94 complexity | f93a6b53b1f0f4d6de88db2240294b42 MD5 | raw file
  1. /*
  2. * Copyright (c) 2010 Red Hat Inc.
  3. * Author : Dave Airlie <airlied@redhat.com>
  4. *
  5. *
  6. * Licensed under GPLv2
  7. *
  8. * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
  9. Switcher interface - methods require for ATPX and DCM
  10. - switchto - this throws the output MUX switch
  11. - discrete_set_power - sets the power state for the discrete card
  12. GPU driver interface
  13. - set_gpu_state - this should do the equiv of s/r for the card
  14. - this should *not* set the discrete power state
  15. - switch_check - check if the device is in a position to switch now
  16. */
  17. #include <linux/module.h>
  18. #include <linux/dmi.h>
  19. #include <linux/seq_file.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/fs.h>
  22. #include <linux/debugfs.h>
  23. #include <linux/fb.h>
  24. #include <linux/pci.h>
  25. #include <linux/console.h>
  26. #include <linux/vga_switcheroo.h>
  27. #include <linux/vgaarb.h>
  28. struct vga_switcheroo_client {
  29. struct pci_dev *pdev;
  30. struct fb_info *fb_info;
  31. int pwr_state;
  32. const struct vga_switcheroo_client_ops *ops;
  33. int id;
  34. bool active;
  35. struct list_head list;
  36. };
  37. static DEFINE_MUTEX(vgasr_mutex);
  38. struct vgasr_priv {
  39. bool active;
  40. bool delayed_switch_active;
  41. enum vga_switcheroo_client_id delayed_client_id;
  42. struct dentry *debugfs_root;
  43. struct dentry *switch_file;
  44. int registered_clients;
  45. struct list_head clients;
  46. struct vga_switcheroo_handler *handler;
  47. };
  48. #define ID_BIT_AUDIO 0x100
  49. #define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)
  50. #define client_is_vga(c) ((c)->id == -1 || !client_is_audio(c))
  51. #define client_id(c) ((c)->id & ~ID_BIT_AUDIO)
  52. static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
  53. static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
  54. /* only one switcheroo per system */
  55. static struct vgasr_priv vgasr_priv = {
  56. .clients = LIST_HEAD_INIT(vgasr_priv.clients),
  57. };
  58. static bool vga_switcheroo_ready(void)
  59. {
  60. /* we're ready if we get two clients + handler */
  61. return !vgasr_priv.active &&
  62. vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
  63. }
  64. static void vga_switcheroo_enable(void)
  65. {
  66. int ret;
  67. struct vga_switcheroo_client *client;
  68. /* call the handler to init */
  69. if (vgasr_priv.handler->init)
  70. vgasr_priv.handler->init();
  71. list_for_each_entry(client, &vgasr_priv.clients, list) {
  72. if (client->id != -1)
  73. continue;
  74. ret = vgasr_priv.handler->get_client_id(client->pdev);
  75. if (ret < 0)
  76. return;
  77. client->id = ret;
  78. }
  79. vga_switcheroo_debugfs_init(&vgasr_priv);
  80. vgasr_priv.active = true;
  81. }
  82. int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
  83. {
  84. mutex_lock(&vgasr_mutex);
  85. if (vgasr_priv.handler) {
  86. mutex_unlock(&vgasr_mutex);
  87. return -EINVAL;
  88. }
  89. vgasr_priv.handler = handler;
  90. if (vga_switcheroo_ready()) {
  91. printk(KERN_INFO "vga_switcheroo: enabled\n");
  92. vga_switcheroo_enable();
  93. }
  94. mutex_unlock(&vgasr_mutex);
  95. return 0;
  96. }
  97. EXPORT_SYMBOL(vga_switcheroo_register_handler);
  98. void vga_switcheroo_unregister_handler(void)
  99. {
  100. mutex_lock(&vgasr_mutex);
  101. vgasr_priv.handler = NULL;
  102. if (vgasr_priv.active) {
  103. pr_info("vga_switcheroo: disabled\n");
  104. vga_switcheroo_debugfs_fini(&vgasr_priv);
  105. vgasr_priv.active = false;
  106. }
  107. mutex_unlock(&vgasr_mutex);
  108. }
  109. EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
  110. static int register_client(struct pci_dev *pdev,
  111. const struct vga_switcheroo_client_ops *ops,
  112. int id, bool active)
  113. {
  114. struct vga_switcheroo_client *client;
  115. client = kzalloc(sizeof(*client), GFP_KERNEL);
  116. if (!client)
  117. return -ENOMEM;
  118. client->pwr_state = VGA_SWITCHEROO_ON;
  119. client->pdev = pdev;
  120. client->ops = ops;
  121. client->id = id;
  122. client->active = active;
  123. mutex_lock(&vgasr_mutex);
  124. list_add_tail(&client->list, &vgasr_priv.clients);
  125. if (client_is_vga(client))
  126. vgasr_priv.registered_clients++;
  127. if (vga_switcheroo_ready()) {
  128. printk(KERN_INFO "vga_switcheroo: enabled\n");
  129. vga_switcheroo_enable();
  130. }
  131. mutex_unlock(&vgasr_mutex);
  132. return 0;
  133. }
  134. int vga_switcheroo_register_client(struct pci_dev *pdev,
  135. const struct vga_switcheroo_client_ops *ops)
  136. {
  137. return register_client(pdev, ops, -1,
  138. pdev == vga_default_device());
  139. }
  140. EXPORT_SYMBOL(vga_switcheroo_register_client);
  141. int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
  142. const struct vga_switcheroo_client_ops *ops,
  143. int id, bool active)
  144. {
  145. return register_client(pdev, ops, id | ID_BIT_AUDIO, active);
  146. }
  147. EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
  148. static struct vga_switcheroo_client *
  149. find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
  150. {
  151. struct vga_switcheroo_client *client;
  152. list_for_each_entry(client, head, list)
  153. if (client->pdev == pdev)
  154. return client;
  155. return NULL;
  156. }
  157. static struct vga_switcheroo_client *
  158. find_client_from_id(struct list_head *head, int client_id)
  159. {
  160. struct vga_switcheroo_client *client;
  161. list_for_each_entry(client, head, list)
  162. if (client->id == client_id)
  163. return client;
  164. return NULL;
  165. }
  166. static struct vga_switcheroo_client *
  167. find_active_client(struct list_head *head)
  168. {
  169. struct vga_switcheroo_client *client;
  170. list_for_each_entry(client, head, list)
  171. if (client->active && client_is_vga(client))
  172. return client;
  173. return NULL;
  174. }
  175. int vga_switcheroo_get_client_state(struct pci_dev *pdev)
  176. {
  177. struct vga_switcheroo_client *client;
  178. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  179. if (!client)
  180. return VGA_SWITCHEROO_NOT_FOUND;
  181. if (!vgasr_priv.active)
  182. return VGA_SWITCHEROO_INIT;
  183. return client->pwr_state;
  184. }
  185. EXPORT_SYMBOL(vga_switcheroo_get_client_state);
  186. void vga_switcheroo_unregister_client(struct pci_dev *pdev)
  187. {
  188. struct vga_switcheroo_client *client;
  189. mutex_lock(&vgasr_mutex);
  190. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  191. if (client) {
  192. if (client_is_vga(client))
  193. vgasr_priv.registered_clients--;
  194. list_del(&client->list);
  195. kfree(client);
  196. }
  197. if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
  198. printk(KERN_INFO "vga_switcheroo: disabled\n");
  199. vga_switcheroo_debugfs_fini(&vgasr_priv);
  200. vgasr_priv.active = false;
  201. }
  202. mutex_unlock(&vgasr_mutex);
  203. }
  204. EXPORT_SYMBOL(vga_switcheroo_unregister_client);
  205. void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
  206. struct fb_info *info)
  207. {
  208. struct vga_switcheroo_client *client;
  209. mutex_lock(&vgasr_mutex);
  210. client = find_client_from_pci(&vgasr_priv.clients, pdev);
  211. if (client)
  212. client->fb_info = info;
  213. mutex_unlock(&vgasr_mutex);
  214. }
  215. EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
  216. static int vga_switcheroo_show(struct seq_file *m, void *v)
  217. {
  218. struct vga_switcheroo_client *client;
  219. int i = 0;
  220. mutex_lock(&vgasr_mutex);
  221. list_for_each_entry(client, &vgasr_priv.clients, list) {
  222. seq_printf(m, "%d:%s%s:%c:%s:%s\n", i,
  223. client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
  224. client_is_vga(client) ? "" : "-Audio",
  225. client->active ? '+' : ' ',
  226. client->pwr_state ? "Pwr" : "Off",
  227. pci_name(client->pdev));
  228. i++;
  229. }
  230. mutex_unlock(&vgasr_mutex);
  231. return 0;
  232. }
  233. static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
  234. {
  235. return single_open(file, vga_switcheroo_show, NULL);
  236. }
  237. static int vga_switchon(struct vga_switcheroo_client *client)
  238. {
  239. if (vgasr_priv.handler->power_state)
  240. vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
  241. /* call the driver callback to turn on device */
  242. client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
  243. client->pwr_state = VGA_SWITCHEROO_ON;
  244. return 0;
  245. }
  246. static int vga_switchoff(struct vga_switcheroo_client *client)
  247. {
  248. /* call the driver callback to turn off device */
  249. client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
  250. if (vgasr_priv.handler->power_state)
  251. vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
  252. client->pwr_state = VGA_SWITCHEROO_OFF;
  253. return 0;
  254. }
  255. static void set_audio_state(int id, int state)
  256. {
  257. struct vga_switcheroo_client *client;
  258. client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
  259. if (client && client->pwr_state != state) {
  260. client->ops->set_gpu_state(client->pdev, state);
  261. client->pwr_state = state;
  262. }
  263. }
  264. /* stage one happens before delay */
  265. static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
  266. {
  267. struct vga_switcheroo_client *active;
  268. active = find_active_client(&vgasr_priv.clients);
  269. if (!active)
  270. return 0;
  271. if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
  272. vga_switchon(new_client);
  273. vga_set_default_device(new_client->pdev);
  274. return 0;
  275. }
  276. /* post delay */
  277. static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
  278. {
  279. int ret;
  280. struct vga_switcheroo_client *active;
  281. active = find_active_client(&vgasr_priv.clients);
  282. if (!active)
  283. return 0;
  284. active->active = false;
  285. set_audio_state(active->id, VGA_SWITCHEROO_OFF);
  286. if (new_client->fb_info) {
  287. struct fb_event event;
  288. console_lock();
  289. event.info = new_client->fb_info;
  290. fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
  291. console_unlock();
  292. }
  293. ret = vgasr_priv.handler->switchto(new_client->id);
  294. if (ret)
  295. return ret;
  296. if (new_client->ops->reprobe)
  297. new_client->ops->reprobe(new_client->pdev);
  298. if (active->pwr_state == VGA_SWITCHEROO_ON)
  299. vga_switchoff(active);
  300. set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
  301. new_client->active = true;
  302. return 0;
  303. }
  304. static bool check_can_switch(void)
  305. {
  306. struct vga_switcheroo_client *client;
  307. list_for_each_entry(client, &vgasr_priv.clients, list) {
  308. if (!client->ops->can_switch(client->pdev)) {
  309. printk(KERN_ERR "vga_switcheroo: client %x refused switch\n", client->id);
  310. return false;
  311. }
  312. }
  313. return true;
  314. }
  315. static ssize_t
  316. vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
  317. size_t cnt, loff_t *ppos)
  318. {
  319. char usercmd[64];
  320. const char *pdev_name;
  321. int ret;
  322. bool delay = false, can_switch;
  323. bool just_mux = false;
  324. int client_id = -1;
  325. struct vga_switcheroo_client *client = NULL;
  326. if (cnt > 63)
  327. cnt = 63;
  328. if (copy_from_user(usercmd, ubuf, cnt))
  329. return -EFAULT;
  330. mutex_lock(&vgasr_mutex);
  331. if (!vgasr_priv.active) {
  332. cnt = -EINVAL;
  333. goto out;
  334. }
  335. /* pwr off the device not in use */
  336. if (strncmp(usercmd, "OFF", 3) == 0) {
  337. list_for_each_entry(client, &vgasr_priv.clients, list) {
  338. if (client->active || client_is_audio(client))
  339. continue;
  340. set_audio_state(client->id, VGA_SWITCHEROO_OFF);
  341. if (client->pwr_state == VGA_SWITCHEROO_ON)
  342. vga_switchoff(client);
  343. }
  344. goto out;
  345. }
  346. /* pwr on the device not in use */
  347. if (strncmp(usercmd, "ON", 2) == 0) {
  348. list_for_each_entry(client, &vgasr_priv.clients, list) {
  349. if (client->active || client_is_audio(client))
  350. continue;
  351. if (client->pwr_state == VGA_SWITCHEROO_OFF)
  352. vga_switchon(client);
  353. set_audio_state(client->id, VGA_SWITCHEROO_ON);
  354. }
  355. goto out;
  356. }
  357. /* request a delayed switch - test can we switch now */
  358. if (strncmp(usercmd, "DIGD", 4) == 0) {
  359. client_id = VGA_SWITCHEROO_IGD;
  360. delay = true;
  361. }
  362. if (strncmp(usercmd, "DDIS", 4) == 0) {
  363. client_id = VGA_SWITCHEROO_DIS;
  364. delay = true;
  365. }
  366. if (strncmp(usercmd, "IGD", 3) == 0)
  367. client_id = VGA_SWITCHEROO_IGD;
  368. if (strncmp(usercmd, "DIS", 3) == 0)
  369. client_id = VGA_SWITCHEROO_DIS;
  370. if (strncmp(usercmd, "MIGD", 4) == 0) {
  371. just_mux = true;
  372. client_id = VGA_SWITCHEROO_IGD;
  373. }
  374. if (strncmp(usercmd, "MDIS", 4) == 0) {
  375. just_mux = true;
  376. client_id = VGA_SWITCHEROO_DIS;
  377. }
  378. if (client_id == -1)
  379. goto out;
  380. client = find_client_from_id(&vgasr_priv.clients, client_id);
  381. if (!client)
  382. goto out;
  383. vgasr_priv.delayed_switch_active = false;
  384. if (just_mux) {
  385. ret = vgasr_priv.handler->switchto(client_id);
  386. goto out;
  387. }
  388. if (client->active)
  389. goto out;
  390. /* okay we want a switch - test if devices are willing to switch */
  391. can_switch = check_can_switch();
  392. if (can_switch == false && delay == false)
  393. goto out;
  394. if (can_switch) {
  395. pdev_name = pci_name(client->pdev);
  396. ret = vga_switchto_stage1(client);
  397. if (ret)
  398. printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret);
  399. ret = vga_switchto_stage2(client);
  400. if (ret)
  401. printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret);
  402. } else {
  403. printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id);
  404. vgasr_priv.delayed_switch_active = true;
  405. vgasr_priv.delayed_client_id = client_id;
  406. ret = vga_switchto_stage1(client);
  407. if (ret)
  408. printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret);
  409. }
  410. out:
  411. mutex_unlock(&vgasr_mutex);
  412. return cnt;
  413. }
  414. static const struct file_operations vga_switcheroo_debugfs_fops = {
  415. .owner = THIS_MODULE,
  416. .open = vga_switcheroo_debugfs_open,
  417. .write = vga_switcheroo_debugfs_write,
  418. .read = seq_read,
  419. .llseek = seq_lseek,
  420. .release = single_release,
  421. };
  422. static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
  423. {
  424. if (priv->switch_file) {
  425. debugfs_remove(priv->switch_file);
  426. priv->switch_file = NULL;
  427. }
  428. if (priv->debugfs_root) {
  429. debugfs_remove(priv->debugfs_root);
  430. priv->debugfs_root = NULL;
  431. }
  432. }
  433. static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
  434. {
  435. /* already initialised */
  436. if (priv->debugfs_root)
  437. return 0;
  438. priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
  439. if (!priv->debugfs_root) {
  440. printk(KERN_ERR "vga_switcheroo: Cannot create /sys/kernel/debug/vgaswitcheroo\n");
  441. goto fail;
  442. }
  443. priv->switch_file = debugfs_create_file("switch", 0644,
  444. priv->debugfs_root, NULL, &vga_switcheroo_debugfs_fops);
  445. if (!priv->switch_file) {
  446. printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
  447. goto fail;
  448. }
  449. return 0;
  450. fail:
  451. vga_switcheroo_debugfs_fini(priv);
  452. return -1;
  453. }
  454. int vga_switcheroo_process_delayed_switch(void)
  455. {
  456. struct vga_switcheroo_client *client;
  457. const char *pdev_name;
  458. int ret;
  459. int err = -EINVAL;
  460. mutex_lock(&vgasr_mutex);
  461. if (!vgasr_priv.delayed_switch_active)
  462. goto err;
  463. printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id);
  464. client = find_client_from_id(&vgasr_priv.clients,
  465. vgasr_priv.delayed_client_id);
  466. if (!client || !check_can_switch())
  467. goto err;
  468. pdev_name = pci_name(client->pdev);
  469. ret = vga_switchto_stage2(client);
  470. if (ret)
  471. printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 2 %d\n", ret);
  472. vgasr_priv.delayed_switch_active = false;
  473. err = 0;
  474. err:
  475. mutex_unlock(&vgasr_mutex);
  476. return err;
  477. }
  478. EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);