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