aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/vga
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/vga')
-rw-r--r--drivers/gpu/vga/vgaarb.c113
1 files changed, 99 insertions, 14 deletions
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index be8d4cb5861c..8a1021f2e319 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -61,7 +61,7 @@ struct vga_device {
61 unsigned int mem_lock_cnt; /* legacy MEM lock count */ 61 unsigned int mem_lock_cnt; /* legacy MEM lock count */
62 unsigned int io_norm_cnt; /* normal IO count */ 62 unsigned int io_norm_cnt; /* normal IO count */
63 unsigned int mem_norm_cnt; /* normal MEM count */ 63 unsigned int mem_norm_cnt; /* normal MEM count */
64 64 bool bridge_has_one_vga;
65 /* allow IRQ enable/disable hook */ 65 /* allow IRQ enable/disable hook */
66 void *cookie; 66 void *cookie;
67 void (*irq_set_state)(void *cookie, bool enable); 67 void (*irq_set_state)(void *cookie, bool enable);
@@ -165,6 +165,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
165 unsigned int wants, legacy_wants, match; 165 unsigned int wants, legacy_wants, match;
166 struct vga_device *conflict; 166 struct vga_device *conflict;
167 unsigned int pci_bits; 167 unsigned int pci_bits;
168 u32 flags = 0;
169
168 /* Account for "normal" resources to lock. If we decode the legacy, 170 /* Account for "normal" resources to lock. If we decode the legacy,
169 * counterpart, we need to request it as well 171 * counterpart, we need to request it as well
170 */ 172 */
@@ -237,16 +239,23 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
237 /* looks like he doesn't have a lock, we can steal 239 /* looks like he doesn't have a lock, we can steal
238 * them from him 240 * them from him
239 */ 241 */
240 vga_irq_set_state(conflict, false);
241 242
243 flags = 0;
242 pci_bits = 0; 244 pci_bits = 0;
243 if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
244 pci_bits |= PCI_COMMAND_MEMORY;
245 if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
246 pci_bits |= PCI_COMMAND_IO;
247 245
248 pci_set_vga_state(conflict->pdev, false, pci_bits, 246 if (!conflict->bridge_has_one_vga) {
249 change_bridge); 247 vga_irq_set_state(conflict, false);
248 flags |= PCI_VGA_STATE_CHANGE_DECODES;
249 if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
250 pci_bits |= PCI_COMMAND_MEMORY;
251 if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
252 pci_bits |= PCI_COMMAND_IO;
253 }
254
255 if (change_bridge)
256 flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
257
258 pci_set_vga_state(conflict->pdev, false, pci_bits, flags);
250 conflict->owns &= ~lwants; 259 conflict->owns &= ~lwants;
251 /* If he also owned non-legacy, that is no longer the case */ 260 /* If he also owned non-legacy, that is no longer the case */
252 if (lwants & VGA_RSRC_LEGACY_MEM) 261 if (lwants & VGA_RSRC_LEGACY_MEM)
@@ -261,14 +270,24 @@ enable_them:
261 * also have in "decodes". We can lock resources we don't decode but 270 * also have in "decodes". We can lock resources we don't decode but
262 * not own them. 271 * not own them.
263 */ 272 */
273 flags = 0;
264 pci_bits = 0; 274 pci_bits = 0;
265 if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
266 pci_bits |= PCI_COMMAND_MEMORY;
267 if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
268 pci_bits |= PCI_COMMAND_IO;
269 pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK));
270 275
271 vga_irq_set_state(vgadev, true); 276 if (!vgadev->bridge_has_one_vga) {
277 flags |= PCI_VGA_STATE_CHANGE_DECODES;
278 if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
279 pci_bits |= PCI_COMMAND_MEMORY;
280 if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
281 pci_bits |= PCI_COMMAND_IO;
282 }
283 if (!!(wants & VGA_RSRC_LEGACY_MASK))
284 flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
285
286 pci_set_vga_state(vgadev->pdev, true, pci_bits, flags);
287
288 if (!vgadev->bridge_has_one_vga) {
289 vga_irq_set_state(vgadev, true);
290 }
272 vgadev->owns |= (wants & vgadev->decodes); 291 vgadev->owns |= (wants & vgadev->decodes);
273lock_them: 292lock_them:
274 vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); 293 vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
@@ -421,6 +440,62 @@ bail:
421} 440}
422EXPORT_SYMBOL(vga_put); 441EXPORT_SYMBOL(vga_put);
423 442
443/* Rules for using a bridge to control a VGA descendant decoding:
444 if a bridge has only one VGA descendant then it can be used
445 to control the VGA routing for that device.
446 It should always use the bridge closest to the device to control it.
447 If a bridge has a direct VGA descendant, but also have a sub-bridge
448 VGA descendant then we cannot use that bridge to control the direct VGA descendant.
449 So for every device we register, we need to iterate all its parent bridges
450 so we can invalidate any devices using them properly.
451*/
452static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)
453{
454 struct vga_device *same_bridge_vgadev;
455 struct pci_bus *new_bus, *bus;
456 struct pci_dev *new_bridge, *bridge;
457
458 vgadev->bridge_has_one_vga = true;
459
460 if (list_empty(&vga_list))
461 return;
462
463 /* okay iterate the new devices bridge hierarachy */
464 new_bus = vgadev->pdev->bus;
465 while (new_bus) {
466 new_bridge = new_bus->self;
467
468 if (new_bridge) {
469 /* go through list of devices already registered */
470 list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
471 bus = same_bridge_vgadev->pdev->bus;
472 bridge = bus->self;
473
474 /* see if the share a bridge with this device */
475 if (new_bridge == bridge) {
476 /* if their direct parent bridge is the same
477 as any bridge of this device then it can't be used
478 for that device */
479 same_bridge_vgadev->bridge_has_one_vga = false;
480 }
481
482 /* now iterate the previous devices bridge hierarchy */
483 /* if the new devices parent bridge is in the other devices
484 hierarchy then we can't use it to control this device */
485 while (bus) {
486 bridge = bus->self;
487 if (bridge) {
488 if (bridge == vgadev->pdev->bus->self)
489 vgadev->bridge_has_one_vga = false;
490 }
491 bus = bus->parent;
492 }
493 }
494 }
495 new_bus = new_bus->parent;
496 }
497}
498
424/* 499/*
425 * Currently, we assume that the "initial" setup of the system is 500 * Currently, we assume that the "initial" setup of the system is
426 * not sane, that is we come up with conflicting devices and let 501 * not sane, that is we come up with conflicting devices and let
@@ -500,6 +575,8 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
500 vga_default = pci_dev_get(pdev); 575 vga_default = pci_dev_get(pdev);
501#endif 576#endif
502 577
578 vga_arbiter_check_bridge_sharing(vgadev);
579
503 /* Add to the list */ 580 /* Add to the list */
504 list_add(&vgadev->list, &vga_list); 581 list_add(&vgadev->list, &vga_list);
505 vga_count++; 582 vga_count++;
@@ -1222,6 +1299,7 @@ static int __init vga_arb_device_init(void)
1222{ 1299{
1223 int rc; 1300 int rc;
1224 struct pci_dev *pdev; 1301 struct pci_dev *pdev;
1302 struct vga_device *vgadev;
1225 1303
1226 rc = misc_register(&vga_arb_device); 1304 rc = misc_register(&vga_arb_device);
1227 if (rc < 0) 1305 if (rc < 0)
@@ -1238,6 +1316,13 @@ static int __init vga_arb_device_init(void)
1238 vga_arbiter_add_pci_device(pdev); 1316 vga_arbiter_add_pci_device(pdev);
1239 1317
1240 pr_info("vgaarb: loaded\n"); 1318 pr_info("vgaarb: loaded\n");
1319
1320 list_for_each_entry(vgadev, &vga_list, list) {
1321 if (vgadev->bridge_has_one_vga)
1322 pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev));
1323 else
1324 pr_info("vgaarb: no bridge control possible %s\n", pci_name(vgadev->pdev));
1325 }
1241 return rc; 1326 return rc;
1242} 1327}
1243subsys_initcall(vga_arb_device_init); 1328subsys_initcall(vga_arb_device_init);