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 31 #include <linux/vgaarb.h> 32 33 struct vga_switcheroo_client { 34 struct pci_dev *pdev; 35 struct fb_info *fb_info; 36 int pwr_state; 37 const struct vga_switcheroo_client_ops *ops; 38 int id; 39 bool active; 40 struct list_head list; 41 }; 42 43 static DEFINE_MUTEX(vgasr_mutex); 44 45 struct vgasr_priv { 46 47 bool active; 48 bool delayed_switch_active; 49 enum vga_switcheroo_client_id delayed_client_id; 50 51 struct dentry *debugfs_root; 52 struct dentry *switch_file; 53 54 int registered_clients; 55 struct list_head clients; 56 57 struct vga_switcheroo_handler *handler; 58 }; 59 60 #define ID_BIT_AUDIO 0x100 61 #define client_is_audio(c) ((c)->id & ID_BIT_AUDIO) 62 #define client_is_vga(c) ((c)->id == -1 || !client_is_audio(c)) 63 #define client_id(c) ((c)->id & ~ID_BIT_AUDIO) 64 65 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv); 66 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv); 67 68 /* only one switcheroo per system */ 69 static struct vgasr_priv vgasr_priv = { 70 .clients = LIST_HEAD_INIT(vgasr_priv.clients), 71 }; 72 73 static bool vga_switcheroo_ready(void) 74 { 75 /* we're ready if we get two clients + handler */ 76 return !vgasr_priv.active && 77 vgasr_priv.registered_clients == 2 && vgasr_priv.handler; 78 } 79 80 static void vga_switcheroo_enable(void) 81 { 82 int ret; 83 struct vga_switcheroo_client *client; 84 85 /* call the handler to init */ 86 if (vgasr_priv.handler->init) 87 vgasr_priv.handler->init(); 88 89 list_for_each_entry(client, &vgasr_priv.clients, list) { 90 if (client->id != -1) 91 continue; 92 ret = vgasr_priv.handler->get_client_id(client->pdev); 93 if (ret < 0) 94 return; 95 96 client->id = ret; 97 } 98 vga_switcheroo_debugfs_init(&vgasr_priv); 99 vgasr_priv.active = true; 100 } 101 102 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) 103 { 104 mutex_lock(&vgasr_mutex); 105 if (vgasr_priv.handler) { 106 mutex_unlock(&vgasr_mutex); 107 return -EINVAL; 108 } 109 110 vgasr_priv.handler = handler; 111 if (vga_switcheroo_ready()) { 112 printk(KERN_INFO "vga_switcheroo: enabled\n"); 113 vga_switcheroo_enable(); 114 } 115 mutex_unlock(&vgasr_mutex); 116 return 0; 117 } 118 EXPORT_SYMBOL(vga_switcheroo_register_handler); 119 120 void vga_switcheroo_unregister_handler(void) 121 { 122 mutex_lock(&vgasr_mutex); 123 vgasr_priv.handler = NULL; 124 if (vgasr_priv.active) { 125 pr_info("vga_switcheroo: disabled\n"); 126 vga_switcheroo_debugfs_fini(&vgasr_priv); 127 vgasr_priv.active = false; 128 } 129 mutex_unlock(&vgasr_mutex); 130 } 131 EXPORT_SYMBOL(vga_switcheroo_unregister_handler); 132 133 static int register_client(struct pci_dev *pdev, 134 const struct vga_switcheroo_client_ops *ops, 135 int id, bool active) 136 { 137 struct vga_switcheroo_client *client; 138 139 client = kzalloc(sizeof(*client), GFP_KERNEL); 140 if (!client) 141 return -ENOMEM; 142 143 client->pwr_state = VGA_SWITCHEROO_ON; 144 client->pdev = pdev; 145 client->ops = ops; 146 client->id = id; 147 client->active = active; 148 149 mutex_lock(&vgasr_mutex); 150 list_add_tail(&client->list, &vgasr_priv.clients); 151 if (client_is_vga(client)) 152 vgasr_priv.registered_clients++; 153 154 if (vga_switcheroo_ready()) { 155 printk(KERN_INFO "vga_switcheroo: enabled\n"); 156 vga_switcheroo_enable(); 157 } 158 mutex_unlock(&vgasr_mutex); 159 return 0; 160 } 161 162 int vga_switcheroo_register_client(struct pci_dev *pdev, 163 const struct vga_switcheroo_client_ops *ops) 164 { 165 return register_client(pdev, ops, -1, 166 pdev == vga_default_device()); 167 } 168 EXPORT_SYMBOL(vga_switcheroo_register_client); 169 170 int vga_switcheroo_register_audio_client(struct pci_dev *pdev, 171 const struct vga_switcheroo_client_ops *ops, 172 int id, bool active) 173 { 174 return register_client(pdev, ops, id | ID_BIT_AUDIO, active); 175 } 176 EXPORT_SYMBOL(vga_switcheroo_register_audio_client); 177 178 static struct vga_switcheroo_client * 179 find_client_from_pci(struct list_head *head, struct pci_dev *pdev) 180 { 181 struct vga_switcheroo_client *client; 182 list_for_each_entry(client, head, list) 183 if (client->pdev == pdev) 184 return client; 185 return NULL; 186 } 187 188 static struct vga_switcheroo_client * 189 find_client_from_id(struct list_head *head, int client_id) 190 { 191 struct vga_switcheroo_client *client; 192 list_for_each_entry(client, head, list) 193 if (client->id == client_id) 194 return client; 195 return NULL; 196 } 197 198 static struct vga_switcheroo_client * 199 find_active_client(struct list_head *head) 200 { 201 struct vga_switcheroo_client *client; 202 list_for_each_entry(client, head, list) 203 if (client->active && client_is_vga(client)) 204 return client; 205 return NULL; 206 } 207 208 int vga_switcheroo_get_client_state(struct pci_dev *pdev) 209 { 210 struct vga_switcheroo_client *client; 211 212 client = find_client_from_pci(&vgasr_priv.clients, pdev); 213 if (!client) 214 return VGA_SWITCHEROO_NOT_FOUND; 215 if (!vgasr_priv.active) 216 return VGA_SWITCHEROO_INIT; 217 return client->pwr_state; 218 } 219 EXPORT_SYMBOL(vga_switcheroo_get_client_state); 220 221 void vga_switcheroo_unregister_client(struct pci_dev *pdev) 222 { 223 struct vga_switcheroo_client *client; 224 225 mutex_lock(&vgasr_mutex); 226 client = find_client_from_pci(&vgasr_priv.clients, pdev); 227 if (client) { 228 if (client_is_vga(client)) 229 vgasr_priv.registered_clients--; 230 list_del(&client->list); 231 kfree(client); 232 } 233 if (vgasr_priv.active && vgasr_priv.registered_clients < 2) { 234 printk(KERN_INFO "vga_switcheroo: disabled\n"); 235 vga_switcheroo_debugfs_fini(&vgasr_priv); 236 vgasr_priv.active = false; 237 } 238 mutex_unlock(&vgasr_mutex); 239 } 240 EXPORT_SYMBOL(vga_switcheroo_unregister_client); 241 242 void vga_switcheroo_client_fb_set(struct pci_dev *pdev, 243 struct fb_info *info) 244 { 245 struct vga_switcheroo_client *client; 246 247 mutex_lock(&vgasr_mutex); 248 client = find_client_from_pci(&vgasr_priv.clients, pdev); 249 if (client) 250 client->fb_info = info; 251 mutex_unlock(&vgasr_mutex); 252 } 253 EXPORT_SYMBOL(vga_switcheroo_client_fb_set); 254 255 static int vga_switcheroo_show(struct seq_file *m, void *v) 256 { 257 struct vga_switcheroo_client *client; 258 int i = 0; 259 mutex_lock(&vgasr_mutex); 260 list_for_each_entry(client, &vgasr_priv.clients, list) { 261 seq_printf(m, "%d:%s%s:%c:%s:%s\n", i, 262 client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD", 263 client_is_vga(client) ? "" : "-Audio", 264 client->active ? '+' : ' ', 265 client->pwr_state ? "Pwr" : "Off", 266 pci_name(client->pdev)); 267 i++; 268 } 269 mutex_unlock(&vgasr_mutex); 270 return 0; 271 } 272 273 static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file) 274 { 275 return single_open(file, vga_switcheroo_show, NULL); 276 } 277 278 static int vga_switchon(struct vga_switcheroo_client *client) 279 { 280 if (vgasr_priv.handler->power_state) 281 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON); 282 /* call the driver callback to turn on device */ 283 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON); 284 client->pwr_state = VGA_SWITCHEROO_ON; 285 return 0; 286 } 287 288 static int vga_switchoff(struct vga_switcheroo_client *client) 289 { 290 /* call the driver callback to turn off device */ 291 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF); 292 if (vgasr_priv.handler->power_state) 293 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF); 294 client->pwr_state = VGA_SWITCHEROO_OFF; 295 return 0; 296 } 297 298 static void set_audio_state(int id, int state) 299 { 300 struct vga_switcheroo_client *client; 301 302 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO); 303 if (client && client->pwr_state != state) { 304 client->ops->set_gpu_state(client->pdev, state); 305 client->pwr_state = state; 306 } 307 } 308 309 /* stage one happens before delay */ 310 static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) 311 { 312 struct vga_switcheroo_client *active; 313 314 active = find_active_client(&vgasr_priv.clients); 315 if (!active) 316 return 0; 317 318 if (new_client->pwr_state == VGA_SWITCHEROO_OFF) 319 vga_switchon(new_client); 320 321 vga_set_default_device(new_client->pdev); 322 return 0; 323 } 324 325 /* post delay */ 326 static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) 327 { 328 int ret; 329 struct vga_switcheroo_client *active; 330 331 active = find_active_client(&vgasr_priv.clients); 332 if (!active) 333 return 0; 334 335 active->active = false; 336 337 set_audio_state(active->id, VGA_SWITCHEROO_OFF); 338 339 if (new_client->fb_info) { 340 struct fb_event event; 341 console_lock(); 342 event.info = new_client->fb_info; 343 fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); 344 console_unlock(); 345 } 346 347 ret = vgasr_priv.handler->switchto(new_client->id); 348 if (ret) 349 return ret; 350 351 if (new_client->ops->reprobe) 352 new_client->ops->reprobe(new_client->pdev); 353 354 if (active->pwr_state == VGA_SWITCHEROO_ON) 355 vga_switchoff(active); 356 357 set_audio_state(new_client->id, VGA_SWITCHEROO_ON); 358 359 new_client->active = true; 360 return 0; 361 } 362 363 static bool check_can_switch(void) 364 { 365 struct vga_switcheroo_client *client; 366 367 list_for_each_entry(client, &vgasr_priv.clients, list) { 368 if (!client->ops->can_switch(client->pdev)) { 369 printk(KERN_ERR "vga_switcheroo: client %x refused switch\n", client->id); 370 return false; 371 } 372 } 373 return true; 374 } 375 376 static ssize_t 377 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, 378 size_t cnt, loff_t *ppos) 379 { 380 char usercmd[64]; 381 int ret; 382 bool delay = false, can_switch; 383 bool just_mux = false; 384 int client_id = -1; 385 struct vga_switcheroo_client *client = NULL; 386 387 if (cnt > 63) 388 cnt = 63; 389 390 if (copy_from_user(usercmd, ubuf, cnt)) 391 return -EFAULT; 392 393 mutex_lock(&vgasr_mutex); 394 395 if (!vgasr_priv.active) { 396 cnt = -EINVAL; 397 goto out; 398 } 399 400 /* pwr off the device not in use */ 401 if (strncmp(usercmd, "OFF", 3) == 0) { 402 list_for_each_entry(client, &vgasr_priv.clients, list) { 403 if (client->active || client_is_audio(client)) 404 continue; 405 set_audio_state(client->id, VGA_SWITCHEROO_OFF); 406 if (client->pwr_state == VGA_SWITCHEROO_ON) 407 vga_switchoff(client); 408 } 409 goto out; 410 } 411 /* pwr on the device not in use */ 412 if (strncmp(usercmd, "ON", 2) == 0) { 413 list_for_each_entry(client, &vgasr_priv.clients, list) { 414 if (client->active || client_is_audio(client)) 415 continue; 416 if (client->pwr_state == VGA_SWITCHEROO_OFF) 417 vga_switchon(client); 418 set_audio_state(client->id, VGA_SWITCHEROO_ON); 419 } 420 goto out; 421 } 422 423 /* request a delayed switch - test can we switch now */ 424 if (strncmp(usercmd, "DIGD", 4) == 0) { 425 client_id = VGA_SWITCHEROO_IGD; 426 delay = true; 427 } 428 429 if (strncmp(usercmd, "DDIS", 4) == 0) { 430 client_id = VGA_SWITCHEROO_DIS; 431 delay = true; 432 } 433 434 if (strncmp(usercmd, "IGD", 3) == 0) 435 client_id = VGA_SWITCHEROO_IGD; 436 437 if (strncmp(usercmd, "DIS", 3) == 0) 438 client_id = VGA_SWITCHEROO_DIS; 439 440 if (strncmp(usercmd, "MIGD", 4) == 0) { 441 just_mux = true; 442 client_id = VGA_SWITCHEROO_IGD; 443 } 444 if (strncmp(usercmd, "MDIS", 4) == 0) { 445 just_mux = true; 446 client_id = VGA_SWITCHEROO_DIS; 447 } 448 449 if (client_id == -1) 450 goto out; 451 client = find_client_from_id(&vgasr_priv.clients, client_id); 452 if (!client) 453 goto out; 454 455 vgasr_priv.delayed_switch_active = false; 456 457 if (just_mux) { 458 ret = vgasr_priv.handler->switchto(client_id); 459 goto out; 460 } 461 462 if (client->active) 463 goto out; 464 465 /* okay we want a switch - test if devices are willing to switch */ 466 can_switch = check_can_switch(); 467 468 if (can_switch == false && delay == false) 469 goto out; 470 471 if (can_switch) { 472 ret = vga_switchto_stage1(client); 473 if (ret) 474 printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret); 475 476 ret = vga_switchto_stage2(client); 477 if (ret) 478 printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret); 479 480 } else { 481 printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id); 482 vgasr_priv.delayed_switch_active = true; 483 vgasr_priv.delayed_client_id = client_id; 484 485 ret = vga_switchto_stage1(client); 486 if (ret) 487 printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret); 488 } 489 490 out: 491 mutex_unlock(&vgasr_mutex); 492 return cnt; 493 } 494 495 static const struct file_operations vga_switcheroo_debugfs_fops = { 496 .owner = THIS_MODULE, 497 .open = vga_switcheroo_debugfs_open, 498 .write = vga_switcheroo_debugfs_write, 499 .read = seq_read, 500 .llseek = seq_lseek, 501 .release = single_release, 502 }; 503 504 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv) 505 { 506 if (priv->switch_file) { 507 debugfs_remove(priv->switch_file); 508 priv->switch_file = NULL; 509 } 510 if (priv->debugfs_root) { 511 debugfs_remove(priv->debugfs_root); 512 priv->debugfs_root = NULL; 513 } 514 } 515 516 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv) 517 { 518 /* already initialised */ 519 if (priv->debugfs_root) 520 return 0; 521 priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL); 522 523 if (!priv->debugfs_root) { 524 printk(KERN_ERR "vga_switcheroo: Cannot create /sys/kernel/debug/vgaswitcheroo\n"); 525 goto fail; 526 } 527 528 priv->switch_file = debugfs_create_file("switch", 0644, 529 priv->debugfs_root, NULL, &vga_switcheroo_debugfs_fops); 530 if (!priv->switch_file) { 531 printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n"); 532 goto fail; 533 } 534 return 0; 535 fail: 536 vga_switcheroo_debugfs_fini(priv); 537 return -1; 538 } 539 540 int vga_switcheroo_process_delayed_switch(void) 541 { 542 struct vga_switcheroo_client *client; 543 int ret; 544 int err = -EINVAL; 545 546 mutex_lock(&vgasr_mutex); 547 if (!vgasr_priv.delayed_switch_active) 548 goto err; 549 550 printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id); 551 552 client = find_client_from_id(&vgasr_priv.clients, 553 vgasr_priv.delayed_client_id); 554 if (!client || !check_can_switch()) 555 goto err; 556 557 ret = vga_switchto_stage2(client); 558 if (ret) 559 printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 2 %d\n", ret); 560 561 vgasr_priv.delayed_switch_active = false; 562 err = 0; 563 err: 564 mutex_unlock(&vgasr_mutex); 565 return err; 566 } 567 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch); 568