diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_opregion.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_opregion.c | 113 |
1 files changed, 58 insertions, 55 deletions
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 97d5329079fe..3cb13237ba58 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -36,12 +36,11 @@ | |||
36 | #define PCI_LBPC 0xf4 | 36 | #define PCI_LBPC 0xf4 |
37 | #define PCI_ASLS 0xfc | 37 | #define PCI_ASLS 0xfc |
38 | 38 | ||
39 | #define OPREGION_SZ (8*1024) | ||
40 | #define OPREGION_HEADER_OFFSET 0 | 39 | #define OPREGION_HEADER_OFFSET 0 |
41 | #define OPREGION_ACPI_OFFSET 0x100 | 40 | #define OPREGION_ACPI_OFFSET 0x100 |
42 | #define OPREGION_SWSCI_OFFSET 0x200 | 41 | #define OPREGION_SWSCI_OFFSET 0x200 |
43 | #define OPREGION_ASLE_OFFSET 0x300 | 42 | #define OPREGION_ASLE_OFFSET 0x300 |
44 | #define OPREGION_VBT_OFFSET 0x1000 | 43 | #define OPREGION_VBT_OFFSET 0x400 |
45 | 44 | ||
46 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | 45 | #define OPREGION_SIGNATURE "IntelGraphicsMem" |
47 | #define MBOX_ACPI (1<<0) | 46 | #define MBOX_ACPI (1<<0) |
@@ -143,6 +142,7 @@ struct opregion_asle { | |||
143 | #define ACPI_DIGITAL_OUTPUT (3<<8) | 142 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
144 | #define ACPI_LVDS_OUTPUT (4<<8) | 143 | #define ACPI_LVDS_OUTPUT (4<<8) |
145 | 144 | ||
145 | #ifdef CONFIG_ACPI | ||
146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
147 | { | 147 | { |
148 | struct drm_i915_private *dev_priv = dev->dev_private; | 148 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -465,7 +465,58 @@ blind_set: | |||
465 | goto end; | 465 | goto end; |
466 | } | 466 | } |
467 | 467 | ||
468 | int intel_opregion_init(struct drm_device *dev, int resume) | 468 | void intel_opregion_init(struct drm_device *dev) |
469 | { | ||
470 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
471 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
472 | |||
473 | if (!opregion->header) | ||
474 | return; | ||
475 | |||
476 | if (opregion->acpi) { | ||
477 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
478 | intel_didl_outputs(dev); | ||
479 | |||
480 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
481 | * Right now, all the events are handled by the ACPI video module. | ||
482 | * We don't actually need to do anything with them. */ | ||
483 | opregion->acpi->csts = 0; | ||
484 | opregion->acpi->drdy = 1; | ||
485 | |||
486 | system_opregion = opregion; | ||
487 | register_acpi_notifier(&intel_opregion_notifier); | ||
488 | } | ||
489 | |||
490 | if (opregion->asle) | ||
491 | intel_opregion_enable_asle(dev); | ||
492 | } | ||
493 | |||
494 | void intel_opregion_fini(struct drm_device *dev) | ||
495 | { | ||
496 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
497 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
498 | |||
499 | if (!opregion->header) | ||
500 | return; | ||
501 | |||
502 | if (opregion->acpi) { | ||
503 | opregion->acpi->drdy = 0; | ||
504 | |||
505 | system_opregion = NULL; | ||
506 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
507 | } | ||
508 | |||
509 | /* just clear all opregion memory pointers now */ | ||
510 | iounmap(opregion->header); | ||
511 | opregion->header = NULL; | ||
512 | opregion->acpi = NULL; | ||
513 | opregion->swsci = NULL; | ||
514 | opregion->asle = NULL; | ||
515 | opregion->vbt = NULL; | ||
516 | } | ||
517 | #endif | ||
518 | |||
519 | int intel_opregion_setup(struct drm_device *dev) | ||
469 | { | 520 | { |
470 | struct drm_i915_private *dev_priv = dev->dev_private; | 521 | struct drm_i915_private *dev_priv = dev->dev_private; |
471 | struct intel_opregion *opregion = &dev_priv->opregion; | 522 | struct intel_opregion *opregion = &dev_priv->opregion; |
@@ -480,29 +531,23 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
480 | return -ENOTSUPP; | 531 | return -ENOTSUPP; |
481 | } | 532 | } |
482 | 533 | ||
483 | base = ioremap(asls, OPREGION_SZ); | 534 | base = ioremap(asls, OPREGION_SIZE); |
484 | if (!base) | 535 | if (!base) |
485 | return -ENOMEM; | 536 | return -ENOMEM; |
486 | 537 | ||
487 | opregion->header = base; | 538 | if (memcmp(base, OPREGION_SIGNATURE, 16)) { |
488 | if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { | ||
489 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); | 539 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); |
490 | err = -EINVAL; | 540 | err = -EINVAL; |
491 | goto err_out; | 541 | goto err_out; |
492 | } | 542 | } |
543 | opregion->header = base; | ||
544 | opregion->vbt = base + OPREGION_VBT_OFFSET; | ||
493 | 545 | ||
494 | mboxes = opregion->header->mboxes; | 546 | mboxes = opregion->header->mboxes; |
495 | if (mboxes & MBOX_ACPI) { | 547 | if (mboxes & MBOX_ACPI) { |
496 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); | 548 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); |
497 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | 549 | opregion->acpi = base + OPREGION_ACPI_OFFSET; |
498 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
499 | intel_didl_outputs(dev); | ||
500 | } else { | ||
501 | DRM_DEBUG_DRIVER("Public ACPI methods not supported\n"); | ||
502 | err = -ENOTSUPP; | ||
503 | goto err_out; | ||
504 | } | 550 | } |
505 | opregion->enabled = 1; | ||
506 | 551 | ||
507 | if (mboxes & MBOX_SWSCI) { | 552 | if (mboxes & MBOX_SWSCI) { |
508 | DRM_DEBUG_DRIVER("SWSCI supported\n"); | 553 | DRM_DEBUG_DRIVER("SWSCI supported\n"); |
@@ -511,53 +556,11 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
511 | if (mboxes & MBOX_ASLE) { | 556 | if (mboxes & MBOX_ASLE) { |
512 | DRM_DEBUG_DRIVER("ASLE supported\n"); | 557 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
513 | opregion->asle = base + OPREGION_ASLE_OFFSET; | 558 | opregion->asle = base + OPREGION_ASLE_OFFSET; |
514 | intel_opregion_enable_asle(dev); | ||
515 | } | 559 | } |
516 | 560 | ||
517 | if (!resume) | ||
518 | acpi_video_register(); | ||
519 | |||
520 | |||
521 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
522 | * Right now, all the events are handled by the ACPI video module. | ||
523 | * We don't actually need to do anything with them. */ | ||
524 | opregion->acpi->csts = 0; | ||
525 | opregion->acpi->drdy = 1; | ||
526 | |||
527 | system_opregion = opregion; | ||
528 | register_acpi_notifier(&intel_opregion_notifier); | ||
529 | |||
530 | return 0; | 561 | return 0; |
531 | 562 | ||
532 | err_out: | 563 | err_out: |
533 | iounmap(opregion->header); | 564 | iounmap(opregion->header); |
534 | opregion->header = NULL; | ||
535 | acpi_video_register(); | ||
536 | return err; | 565 | return err; |
537 | } | 566 | } |
538 | |||
539 | void intel_opregion_free(struct drm_device *dev, int suspend) | ||
540 | { | ||
541 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
542 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
543 | |||
544 | if (!opregion->enabled) | ||
545 | return; | ||
546 | |||
547 | if (!suspend) | ||
548 | acpi_video_unregister(); | ||
549 | |||
550 | opregion->acpi->drdy = 0; | ||
551 | |||
552 | system_opregion = NULL; | ||
553 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
554 | |||
555 | /* just clear all opregion memory pointers now */ | ||
556 | iounmap(opregion->header); | ||
557 | opregion->header = NULL; | ||
558 | opregion->acpi = NULL; | ||
559 | opregion->swsci = NULL; | ||
560 | opregion->asle = NULL; | ||
561 | |||
562 | opregion->enabled = 0; | ||
563 | } | ||