]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpu/vga/vga_switcheroo.c
gpu/vga_switcheroo: add driver control power feature. (v3)
[karo-tx-linux.git] / drivers / gpu / vga / vga_switcheroo.c
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
10  Switcher interface - methods require for ATPX and DCM
11  - switchto - this throws the output MUX switch
12  - discrete_set_power - sets the power state for the discrete card
13
14  GPU driver interface
15  - set_gpu_state - this should do the equiv of s/r for the card
16                   - this should *not* set the discrete power state
17  - switch_check  - check if the device is in a position to switch now
18  */
19
20 #include <linux/module.h>
21 #include <linux/seq_file.h>
22 #include <linux/uaccess.h>
23 #include <linux/fs.h>
24 #include <linux/debugfs.h>
25 #include <linux/fb.h>
26
27 #include <linux/pci.h>
28 #include <linux/console.h>
29 #include <linux/vga_switcheroo.h>
30 #include <linux/pm_runtime.h>
31
32 #include <linux/vgaarb.h>
33
34 struct vga_switcheroo_client {
35         struct pci_dev *pdev;
36         struct fb_info *fb_info;
37         int pwr_state;
38         const struct vga_switcheroo_client_ops *ops;
39         int id;
40         bool active;
41         bool driver_power_control;
42         struct list_head list;
43 };
44
45 static DEFINE_MUTEX(vgasr_mutex);
46
47 struct vgasr_priv {
48
49         bool active;
50         bool delayed_switch_active;
51         enum vga_switcheroo_client_id delayed_client_id;
52
53         struct dentry *debugfs_root;
54         struct dentry *switch_file;
55
56         int registered_clients;
57         struct list_head clients;
58
59         struct vga_switcheroo_handler *handler;
60 };
61
62 #define ID_BIT_AUDIO            0x100
63 #define client_is_audio(c)      ((c)->id & ID_BIT_AUDIO)
64 #define client_is_vga(c)        ((c)->id == -1 || !client_is_audio(c))
65 #define client_id(c)            ((c)->id & ~ID_BIT_AUDIO)
66
67 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
68 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
69
70 /* only one switcheroo per system */
71 static struct vgasr_priv vgasr_priv = {
72         .clients = LIST_HEAD_INIT(vgasr_priv.clients),
73 };
74
75 static bool vga_switcheroo_ready(void)
76 {
77         /* we're ready if we get two clients + handler */
78         return !vgasr_priv.active &&
79                vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
80 }
81
82 static void vga_switcheroo_enable(void)
83 {
84         int ret;
85         struct vga_switcheroo_client *client;
86
87         /* call the handler to init */
88         if (vgasr_priv.handler->init)
89                 vgasr_priv.handler->init();
90
91         list_for_each_entry(client, &vgasr_priv.clients, list) {
92                 if (client->id != -1)
93                         continue;
94                 ret = vgasr_priv.handler->get_client_id(client->pdev);
95                 if (ret < 0)
96                         return;
97
98                 client->id = ret;
99         }
100         vga_switcheroo_debugfs_init(&vgasr_priv);
101         vgasr_priv.active = true;
102 }
103
104 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
105 {
106         mutex_lock(&vgasr_mutex);
107         if (vgasr_priv.handler) {
108                 mutex_unlock(&vgasr_mutex);
109                 return -EINVAL;
110         }
111
112         vgasr_priv.handler = handler;
113         if (vga_switcheroo_ready()) {
114                 printk(KERN_INFO "vga_switcheroo: enabled\n");
115                 vga_switcheroo_enable();
116         }
117         mutex_unlock(&vgasr_mutex);
118         return 0;
119 }
120 EXPORT_SYMBOL(vga_switcheroo_register_handler);
121
122 void vga_switcheroo_unregister_handler(void)
123 {
124         mutex_lock(&vgasr_mutex);
125         vgasr_priv.handler = NULL;
126         if (vgasr_priv.active) {
127                 pr_info("vga_switcheroo: disabled\n");
128                 vga_switcheroo_debugfs_fini(&vgasr_priv);
129                 vgasr_priv.active = false;
130         }
131         mutex_unlock(&vgasr_mutex);
132 }
133 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
134
135 static int register_client(struct pci_dev *pdev,
136                            const struct vga_switcheroo_client_ops *ops,
137                            int id, bool active, bool driver_power_control)
138 {
139         struct vga_switcheroo_client *client;
140
141         client = kzalloc(sizeof(*client), GFP_KERNEL);
142         if (!client)
143                 return -ENOMEM;
144
145         client->pwr_state = VGA_SWITCHEROO_ON;
146         client->pdev = pdev;
147         client->ops = ops;
148         client->id = id;
149         client->active = active;
150         client->driver_power_control = driver_power_control;
151
152         mutex_lock(&vgasr_mutex);
153         list_add_tail(&client->list, &vgasr_priv.clients);
154         if (client_is_vga(client))
155                 vgasr_priv.registered_clients++;
156
157         if (vga_switcheroo_ready()) {
158                 printk(KERN_INFO "vga_switcheroo: enabled\n");
159                 vga_switcheroo_enable();
160         }
161         mutex_unlock(&vgasr_mutex);
162         return 0;
163 }
164
165 int vga_switcheroo_register_client(struct pci_dev *pdev,
166                                    const struct vga_switcheroo_client_ops *ops,
167                                    bool driver_power_control)
168 {
169         return register_client(pdev, ops, -1,
170                                pdev == vga_default_device(), driver_power_control);
171 }
172 EXPORT_SYMBOL(vga_switcheroo_register_client);
173
174 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
175                                          const struct vga_switcheroo_client_ops *ops,
176                                          int id, bool active)
177 {
178         return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
179 }
180 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
181
182 static struct vga_switcheroo_client *
183 find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
184 {
185         struct vga_switcheroo_client *client;
186         list_for_each_entry(client, head, list)
187                 if (client->pdev == pdev)
188                         return client;
189         return NULL;
190 }
191
192 static struct vga_switcheroo_client *
193 find_client_from_id(struct list_head *head, int client_id)
194 {
195         struct vga_switcheroo_client *client;
196         list_for_each_entry(client, head, list)
197                 if (client->id == client_id)
198                         return client;
199         return NULL;
200 }
201
202 static struct vga_switcheroo_client *
203 find_active_client(struct list_head *head)
204 {
205         struct vga_switcheroo_client *client;
206         list_for_each_entry(client, head, list)
207                 if (client->active && client_is_vga(client))
208                         return client;
209         return NULL;
210 }
211
212 int vga_switcheroo_get_client_state(struct pci_dev *pdev)
213 {
214         struct vga_switcheroo_client *client;
215
216         client = find_client_from_pci(&vgasr_priv.clients, pdev);
217         if (!client)
218                 return VGA_SWITCHEROO_NOT_FOUND;
219         if (!vgasr_priv.active)
220                 return VGA_SWITCHEROO_INIT;
221         return client->pwr_state;
222 }
223 EXPORT_SYMBOL(vga_switcheroo_get_client_state);
224
225 void vga_switcheroo_unregister_client(struct pci_dev *pdev)
226 {
227         struct vga_switcheroo_client *client;
228
229         mutex_lock(&vgasr_mutex);
230         client = find_client_from_pci(&vgasr_priv.clients, pdev);
231         if (client) {
232                 if (client_is_vga(client))
233                         vgasr_priv.registered_clients--;
234                 list_del(&client->list);
235                 kfree(client);
236         }
237         if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
238                 printk(KERN_INFO "vga_switcheroo: disabled\n");
239                 vga_switcheroo_debugfs_fini(&vgasr_priv);
240                 vgasr_priv.active = false;
241         }
242         mutex_unlock(&vgasr_mutex);
243 }
244 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
245
246 void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
247                                  struct fb_info *info)
248 {
249         struct vga_switcheroo_client *client;
250
251         mutex_lock(&vgasr_mutex);
252         client = find_client_from_pci(&vgasr_priv.clients, pdev);
253         if (client)
254                 client->fb_info = info;
255         mutex_unlock(&vgasr_mutex);
256 }
257 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
258
259 static int vga_switcheroo_show(struct seq_file *m, void *v)
260 {
261         struct vga_switcheroo_client *client;
262         int i = 0;
263         mutex_lock(&vgasr_mutex);
264         list_for_each_entry(client, &vgasr_priv.clients, list) {
265                 seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
266                            client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
267                            client_is_vga(client) ? "" : "-Audio",
268                            client->active ? '+' : ' ',
269                            client->driver_power_control ? "Dyn" : "",
270                            client->pwr_state ? "Pwr" : "Off",
271                            pci_name(client->pdev));
272                 i++;
273         }
274         mutex_unlock(&vgasr_mutex);
275         return 0;
276 }
277
278 static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
279 {
280         return single_open(file, vga_switcheroo_show, NULL);
281 }
282
283 static int vga_switchon(struct vga_switcheroo_client *client)
284 {
285         if (client->driver_power_control)
286                 return 0;
287         if (vgasr_priv.handler->power_state)
288                 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
289         /* call the driver callback to turn on device */
290         client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
291         client->pwr_state = VGA_SWITCHEROO_ON;
292         return 0;
293 }
294
295 static int vga_switchoff(struct vga_switcheroo_client *client)
296 {
297         if (client->driver_power_control)
298                 return 0;
299         /* call the driver callback to turn off device */
300         client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
301         if (vgasr_priv.handler->power_state)
302                 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
303         client->pwr_state = VGA_SWITCHEROO_OFF;
304         return 0;
305 }
306
307 static void set_audio_state(int id, int state)
308 {
309         struct vga_switcheroo_client *client;
310
311         client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
312         if (client && client->pwr_state != state) {
313                 client->ops->set_gpu_state(client->pdev, state);
314                 client->pwr_state = state;
315         }
316 }
317
318 /* stage one happens before delay */
319 static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
320 {
321         struct vga_switcheroo_client *active;
322
323         active = find_active_client(&vgasr_priv.clients);
324         if (!active)
325                 return 0;
326
327         if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
328                 vga_switchon(new_client);
329
330         vga_set_default_device(new_client->pdev);
331         return 0;
332 }
333
334 /* post delay */
335 static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
336 {
337         int ret;
338         struct vga_switcheroo_client *active;
339
340         active = find_active_client(&vgasr_priv.clients);
341         if (!active)
342                 return 0;
343
344         active->active = false;
345
346         set_audio_state(active->id, VGA_SWITCHEROO_OFF);
347
348         if (new_client->fb_info) {
349                 struct fb_event event;
350                 console_lock();
351                 event.info = new_client->fb_info;
352                 fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
353                 console_unlock();
354         }
355
356         ret = vgasr_priv.handler->switchto(new_client->id);
357         if (ret)
358                 return ret;
359
360         if (new_client->ops->reprobe)
361                 new_client->ops->reprobe(new_client->pdev);
362
363         if (active->pwr_state == VGA_SWITCHEROO_ON)
364                 vga_switchoff(active);
365
366         set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
367
368         new_client->active = true;
369         return 0;
370 }
371
372 static bool check_can_switch(void)
373 {
374         struct vga_switcheroo_client *client;
375
376         list_for_each_entry(client, &vgasr_priv.clients, list) {
377                 if (!client->ops->can_switch(client->pdev)) {
378                         printk(KERN_ERR "vga_switcheroo: client %x refused switch\n", client->id);
379                         return false;
380                 }
381         }
382         return true;
383 }
384
385 static ssize_t
386 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
387                              size_t cnt, loff_t *ppos)
388 {
389         char usercmd[64];
390         int ret;
391         bool delay = false, can_switch;
392         bool just_mux = false;
393         int client_id = -1;
394         struct vga_switcheroo_client *client = NULL;
395
396         if (cnt > 63)
397                 cnt = 63;
398
399         if (copy_from_user(usercmd, ubuf, cnt))
400                 return -EFAULT;
401
402         mutex_lock(&vgasr_mutex);
403
404         if (!vgasr_priv.active) {
405                 cnt = -EINVAL;
406                 goto out;
407         }
408
409         /* pwr off the device not in use */
410         if (strncmp(usercmd, "OFF", 3) == 0) {
411                 list_for_each_entry(client, &vgasr_priv.clients, list) {
412                         if (client->active || client_is_audio(client))
413                                 continue;
414                         if (client->driver_power_control)
415                                 continue;
416                         set_audio_state(client->id, VGA_SWITCHEROO_OFF);
417                         if (client->pwr_state == VGA_SWITCHEROO_ON)
418                                 vga_switchoff(client);
419                 }
420                 goto out;
421         }
422         /* pwr on the device not in use */
423         if (strncmp(usercmd, "ON", 2) == 0) {
424                 list_for_each_entry(client, &vgasr_priv.clients, list) {
425                         if (client->active || client_is_audio(client))
426                                 continue;
427                         if (client->driver_power_control)
428                                 continue;
429                         if (client->pwr_state == VGA_SWITCHEROO_OFF)
430                                 vga_switchon(client);
431                         set_audio_state(client->id, VGA_SWITCHEROO_ON);
432                 }
433                 goto out;
434         }
435
436         /* request a delayed switch - test can we switch now */
437         if (strncmp(usercmd, "DIGD", 4) == 0) {
438                 client_id = VGA_SWITCHEROO_IGD;
439                 delay = true;
440         }
441
442         if (strncmp(usercmd, "DDIS", 4) == 0) {
443                 client_id = VGA_SWITCHEROO_DIS;
444                 delay = true;
445         }
446
447         if (strncmp(usercmd, "IGD", 3) == 0)
448                 client_id = VGA_SWITCHEROO_IGD;
449
450         if (strncmp(usercmd, "DIS", 3) == 0)
451                 client_id = VGA_SWITCHEROO_DIS;
452
453         if (strncmp(usercmd, "MIGD", 4) == 0) {
454                 just_mux = true;
455                 client_id = VGA_SWITCHEROO_IGD;
456         }
457         if (strncmp(usercmd, "MDIS", 4) == 0) {
458                 just_mux = true;
459                 client_id = VGA_SWITCHEROO_DIS;
460         }
461
462         if (client_id == -1)
463                 goto out;
464         client = find_client_from_id(&vgasr_priv.clients, client_id);
465         if (!client)
466                 goto out;
467
468         vgasr_priv.delayed_switch_active = false;
469
470         if (just_mux) {
471                 ret = vgasr_priv.handler->switchto(client_id);
472                 goto out;
473         }
474
475         if (client->active)
476                 goto out;
477
478         /* okay we want a switch - test if devices are willing to switch */
479         can_switch = check_can_switch();
480
481         if (can_switch == false && delay == false)
482                 goto out;
483
484         if (can_switch) {
485                 ret = vga_switchto_stage1(client);
486                 if (ret)
487                         printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret);
488
489                 ret = vga_switchto_stage2(client);
490                 if (ret)
491                         printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret);
492
493         } else {
494                 printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id);
495                 vgasr_priv.delayed_switch_active = true;
496                 vgasr_priv.delayed_client_id = client_id;
497
498                 ret = vga_switchto_stage1(client);
499                 if (ret)
500                         printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret);
501         }
502
503 out:
504         mutex_unlock(&vgasr_mutex);
505         return cnt;
506 }
507
508 static const struct file_operations vga_switcheroo_debugfs_fops = {
509         .owner = THIS_MODULE,
510         .open = vga_switcheroo_debugfs_open,
511         .write = vga_switcheroo_debugfs_write,
512         .read = seq_read,
513         .llseek = seq_lseek,
514         .release = single_release,
515 };
516
517 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
518 {
519         if (priv->switch_file) {
520                 debugfs_remove(priv->switch_file);
521                 priv->switch_file = NULL;
522         }
523         if (priv->debugfs_root) {
524                 debugfs_remove(priv->debugfs_root);
525                 priv->debugfs_root = NULL;
526         }
527 }
528
529 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
530 {
531         /* already initialised */
532         if (priv->debugfs_root)
533                 return 0;
534         priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
535
536         if (!priv->debugfs_root) {
537                 printk(KERN_ERR "vga_switcheroo: Cannot create /sys/kernel/debug/vgaswitcheroo\n");
538                 goto fail;
539         }
540
541         priv->switch_file = debugfs_create_file("switch", 0644,
542                                                 priv->debugfs_root, NULL, &vga_switcheroo_debugfs_fops);
543         if (!priv->switch_file) {
544                 printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
545                 goto fail;
546         }
547         return 0;
548 fail:
549         vga_switcheroo_debugfs_fini(priv);
550         return -1;
551 }
552
553 int vga_switcheroo_process_delayed_switch(void)
554 {
555         struct vga_switcheroo_client *client;
556         int ret;
557         int err = -EINVAL;
558
559         mutex_lock(&vgasr_mutex);
560         if (!vgasr_priv.delayed_switch_active)
561                 goto err;
562
563         printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id);
564
565         client = find_client_from_id(&vgasr_priv.clients,
566                                      vgasr_priv.delayed_client_id);
567         if (!client || !check_can_switch())
568                 goto err;
569
570         ret = vga_switchto_stage2(client);
571         if (ret)
572                 printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 2 %d\n", ret);
573
574         vgasr_priv.delayed_switch_active = false;
575         err = 0;
576 err:
577         mutex_unlock(&vgasr_mutex);
578         return err;
579 }
580 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
581
582 static void vga_switcheroo_power_switch(struct pci_dev *pdev, enum vga_switcheroo_state state)
583 {
584         struct vga_switcheroo_client *client;
585
586         if (!vgasr_priv.handler->power_state)
587                 return;
588
589         client = find_client_from_pci(&vgasr_priv.clients, pdev);
590         if (!client)
591                 return;
592
593         if (!client->driver_power_control)
594                 return;
595
596         vgasr_priv.handler->power_state(client->id, state);
597 }
598
599 /* force a PCI device to a certain state - mainly to turn off audio clients */
600
601 void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic)
602 {
603         struct vga_switcheroo_client *client;
604
605         client = find_client_from_pci(&vgasr_priv.clients, pdev);
606         if (!client)
607                 return;
608
609         if (!client->driver_power_control)
610                 return;
611
612         client->pwr_state = dynamic;
613         set_audio_state(client->id, dynamic);
614 }
615 EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
616
617 /* switcheroo power domain */
618 static int vga_switcheroo_runtime_suspend(struct device *dev)
619 {
620         struct pci_dev *pdev = to_pci_dev(dev);
621         int ret;
622
623         ret = dev->bus->pm->runtime_suspend(dev);
624         if (ret)
625                 return ret;
626
627         vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
628         return 0;
629 }
630
631 static int vga_switcheroo_runtime_resume(struct device *dev)
632 {
633         struct pci_dev *pdev = to_pci_dev(dev);
634         int ret;
635
636         vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
637         ret = dev->bus->pm->runtime_resume(dev);
638         if (ret)
639                 return ret;
640
641         return 0;
642 }
643
644 /* this version is for the case where the power switch is separate
645    to the device being powered down. */
646 int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain)
647 {
648         /* copy over all the bus versions */
649         if (dev->bus && dev->bus->pm) {
650                 domain->ops = *dev->bus->pm;
651                 domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
652                 domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
653
654                 dev->pm_domain = domain;
655                 return 0;
656         }
657         dev->pm_domain = NULL;
658         return -EINVAL;
659 }
660 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
661
662 static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
663 {
664         struct pci_dev *pdev = to_pci_dev(dev);
665         int ret;
666         struct vga_switcheroo_client *client, *found = NULL;
667
668         /* we need to check if we have to switch back on the video
669            device so the audio device can come back */
670         list_for_each_entry(client, &vgasr_priv.clients, list) {
671                 if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) && client_is_vga(client)) {
672                         found = client;
673                         ret = pm_runtime_get_sync(&client->pdev->dev);
674                         if (ret) {
675                                 if (ret != 1)
676                                         return ret;
677                         }
678                         break;
679                 }
680         }
681         ret = dev->bus->pm->runtime_resume(dev);
682
683         /* put the reference for the gpu */
684         if (found) {
685                 pm_runtime_mark_last_busy(&found->pdev->dev);
686                 pm_runtime_put_autosuspend(&found->pdev->dev);
687         }
688         return ret;
689 }
690
691 int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain)
692 {
693         /* copy over all the bus versions */
694         if (dev->bus && dev->bus->pm) {
695                 domain->ops = *dev->bus->pm;
696                 domain->ops.runtime_resume = vga_switcheroo_runtime_resume_hdmi_audio;
697
698                 dev->pm_domain = domain;
699                 return 0;
700         }
701         dev->pm_domain = NULL;
702         return -EINVAL;
703 }
704 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);