diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lvds.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..3f445a80c552 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
@@ -252,14 +253,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
252 | 253 | ||
253 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
255 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
256 | return false; | 257 | return false; |
257 | } | 258 | } |
258 | 259 | ||
259 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
260 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
261 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
262 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
263 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
264 | return false; | 265 | return false; |
265 | } | 266 | } |
@@ -779,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
779 | }, | 780 | }, |
780 | { | 781 | { |
781 | .callback = intel_no_lvds_dmi_callback, | 782 | .callback = intel_no_lvds_dmi_callback, |
783 | .ident = "AOpen Mini PC MP915", | ||
784 | .matches = { | ||
785 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
786 | DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), | ||
787 | }, | ||
788 | }, | ||
789 | { | ||
790 | .callback = intel_no_lvds_dmi_callback, | ||
782 | .ident = "Aopen i945GTt-VFA", | 791 | .ident = "Aopen i945GTt-VFA", |
783 | .matches = { | 792 | .matches = { |
784 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 793 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
@@ -788,6 +797,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
788 | { } /* terminating entry */ | 797 | { } /* terminating entry */ |
789 | }; | 798 | }; |
790 | 799 | ||
800 | #ifdef CONFIG_ACPI | ||
801 | /* | ||
802 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
803 | * @handle: ACPI device handle | ||
804 | * @level : depth in the ACPI namespace tree | ||
805 | * @context: the number of LID device when we find the device | ||
806 | * @rv: a return value to fill if desired (Not use) | ||
807 | */ | ||
808 | static acpi_status | ||
809 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
810 | void **return_value) | ||
811 | { | ||
812 | struct acpi_device *acpi_dev; | ||
813 | int *lid_present = context; | ||
814 | |||
815 | acpi_dev = NULL; | ||
816 | /* Get the acpi device for device handle */ | ||
817 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
818 | /* If there is no ACPI device for handle, return */ | ||
819 | return AE_OK; | ||
820 | } | ||
821 | |||
822 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
823 | *lid_present = 1; | ||
824 | |||
825 | return AE_OK; | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
830 | * device tree. | ||
831 | */ | ||
832 | static int intel_lid_present(void) | ||
833 | { | ||
834 | int lid_present = 0; | ||
835 | |||
836 | if (acpi_disabled) { | ||
837 | /* If ACPI is disabled, there is no ACPI device tree to | ||
838 | * check, so assume the LID device would have been present. | ||
839 | */ | ||
840 | return 1; | ||
841 | } | ||
842 | |||
843 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
844 | ACPI_UINT32_MAX, | ||
845 | check_lid_device, &lid_present, NULL); | ||
846 | |||
847 | return lid_present; | ||
848 | } | ||
849 | #else | ||
850 | static int intel_lid_present(void) | ||
851 | { | ||
852 | /* In the absence of ACPI built in, assume that the LID device would | ||
853 | * have been present. | ||
854 | */ | ||
855 | return 1; | ||
856 | } | ||
857 | #endif | ||
858 | |||
791 | /** | 859 | /** |
792 | * intel_lvds_init - setup LVDS connectors on this device | 860 | * intel_lvds_init - setup LVDS connectors on this device |
793 | * @dev: drm device | 861 | * @dev: drm device |
@@ -811,9 +879,23 @@ void intel_lvds_init(struct drm_device *dev) | |||
811 | if (dmi_check_system(intel_no_lvds)) | 879 | if (dmi_check_system(intel_no_lvds)) |
812 | return; | 880 | return; |
813 | 881 | ||
882 | /* Assume that any device without an ACPI LID device also doesn't | ||
883 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
884 | * to get a reliable indicator, but that code isn't written yet. | ||
885 | * | ||
886 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
887 | * they're using SDVO LVDS. | ||
888 | */ | ||
889 | if (!intel_lid_present()) | ||
890 | return; | ||
891 | |||
814 | if (IS_IGDNG(dev)) { | 892 | if (IS_IGDNG(dev)) { |
815 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 893 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
816 | return; | 894 | return; |
895 | if (dev_priv->edp_support) { | ||
896 | DRM_DEBUG("disable LVDS for eDP support\n"); | ||
897 | return; | ||
898 | } | ||
817 | gpio = PCH_GPIOC; | 899 | gpio = PCH_GPIOC; |
818 | } | 900 | } |
819 | 901 | ||