32 #include <linux/i2c.h>
33 #include <linux/slab.h>
38 #include <drm/i915_drm.h>
67 static bool intel_lvds_get_hw_state(
struct intel_encoder *encoder,
123 DRM_DEBUG_KMS(
"applying panel-fitter: %x, %x\n",
135 DRM_ERROR(
"timed out waiting for panel to power on\n");
140 static void intel_disable_lvds(
struct intel_encoder *encoder)
143 struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->
base);
161 DRM_ERROR(
"timed out waiting for panel to power off\n");
172 static int intel_lvds_mode_valid(
struct drm_connector *connector,
175 struct intel_lvds *intel_lvds = intel_attached_lvds(connector);
190 u32 border, sync_pos, blank_width, sync_width;
195 sync_pos = (blank_width - sync_width + 1) / 2;
197 border = (mode->
hdisplay - width + 1) / 2;
198 border += border & 1;
214 u32 border, sync_pos, blank_width, sync_width;
219 sync_pos = (blank_width - sync_width + 1) / 2;
221 border = (mode->
vdisplay - height + 1) / 2;
241 #define FACTOR (1 << ACCURACY)
243 return (FACTOR * ratio + FACTOR/2) /
FACTOR;
246 static bool intel_lvds_mode_fixup(
struct drm_encoder *encoder,
252 struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
253 struct intel_crtc *intel_crtc = intel_lvds->
base.new_crtc;
254 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
258 if (
INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
259 DRM_ERROR(
"Can't support LVDS on pipe A\n");
276 mode, adjusted_mode);
301 switch (intel_lvds->fitting_mode) {
307 centre_horizontally(adjusted_mode, mode->
hdisplay);
308 centre_vertically(adjusted_mode, mode->
vdisplay);
315 u32 scaled_width = adjusted_mode->hdisplay * mode->
vdisplay;
316 u32 scaled_height = mode->
hdisplay * adjusted_mode->vdisplay;
319 if (scaled_width > scaled_height)
321 else if (scaled_width < scaled_height)
323 else if (adjusted_mode->hdisplay != mode->
hdisplay)
326 u32 scaled_width = adjusted_mode->hdisplay * mode->
vdisplay;
327 u32 scaled_height = mode->
hdisplay * adjusted_mode->vdisplay;
333 if (scaled_width > scaled_height) {
334 centre_horizontally(adjusted_mode, scaled_height / mode->
vdisplay);
337 if (mode->
vdisplay != adjusted_mode->vdisplay) {
338 u32 bits = panel_fitter_scaling(mode->
vdisplay, adjusted_mode->vdisplay);
345 }
else if (scaled_width < scaled_height) {
346 centre_vertically(adjusted_mode, scaled_width / mode->
hdisplay);
349 if (mode->
hdisplay != adjusted_mode->hdisplay) {
350 u32 bits = panel_fitter_scaling(mode->
hdisplay, adjusted_mode->hdisplay);
371 if (mode->
vdisplay != adjusted_mode->vdisplay ||
372 mode->
hdisplay != adjusted_mode->hdisplay) {
416 static void intel_lvds_mode_set(
struct drm_encoder *encoder,
450 static int intel_lvds_get_modes(
struct drm_connector *connector)
452 struct intel_lvds *intel_lvds = intel_attached_lvds(connector);
456 if (intel_lvds->
edid)
467 static int intel_no_modeset_on_lid_dmi_callback(
const struct dmi_system_id *
id)
469 DRM_INFO(
"Skipping forced modeset for %s\n", id->
ident);
474 static const struct dmi_system_id intel_no_modeset_on_lid[] = {
476 .callback = intel_no_modeset_on_lid_dmi_callback,
477 .ident =
"Toshiba Tecra A11",
504 if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
512 connector->
status = connector->
funcs->detect(connector,
542 static void intel_lvds_destroy(
struct drm_connector *connector)
556 static int intel_lvds_set_property(
struct drm_connector *connector,
560 struct intel_lvds *intel_lvds = intel_attached_lvds(connector);
563 if (property == dev->mode_config.scaling_mode_property) {
567 DRM_DEBUG_KMS(
"no scaling not supported\n");
582 crtc->
x, crtc->
y, crtc->
fb);
590 .mode_fixup = intel_lvds_mode_fixup,
591 .mode_set = intel_lvds_mode_set,
596 .get_modes = intel_lvds_get_modes,
597 .mode_valid = intel_lvds_mode_valid,
603 .detect = intel_lvds_detect,
605 .set_property = intel_lvds_set_property,
606 .destroy = intel_lvds_destroy,
615 DRM_INFO(
"Skipping LVDS initialization for %s\n", id->
ident);
622 .callback = intel_no_lvds_dmi_callback,
623 .ident =
"Apple Mac Mini (Core series)",
630 .callback = intel_no_lvds_dmi_callback,
631 .ident =
"Apple Mac Mini (Core 2 series)",
638 .callback = intel_no_lvds_dmi_callback,
639 .ident =
"MSI IM-945GSE-A",
646 .callback = intel_no_lvds_dmi_callback,
647 .ident =
"Dell Studio Hybrid",
654 .callback = intel_no_lvds_dmi_callback,
655 .ident =
"Dell OptiPlex FX170",
662 .callback = intel_no_lvds_dmi_callback,
663 .ident =
"AOpen Mini PC",
670 .callback = intel_no_lvds_dmi_callback,
671 .ident =
"AOpen Mini PC MP915",
678 .callback = intel_no_lvds_dmi_callback,
679 .ident =
"AOpen i915GMm-HFS",
686 .callback = intel_no_lvds_dmi_callback,
687 .ident =
"AOpen i45GMx-I",
694 .callback = intel_no_lvds_dmi_callback,
695 .ident =
"Aopen i945GTt-VFA",
701 .callback = intel_no_lvds_dmi_callback,
702 .ident =
"Clientron U800",
709 .callback = intel_no_lvds_dmi_callback,
710 .ident =
"Clientron E830",
717 .callback = intel_no_lvds_dmi_callback,
718 .ident =
"Asus EeeBox PC EB1007",
725 .callback = intel_no_lvds_dmi_callback,
726 .ident =
"Asus AT5NM10T-I",
733 .callback = intel_no_lvds_dmi_callback,
734 .ident =
"Hewlett-Packard HP t5740e Thin Client",
741 .callback = intel_no_lvds_dmi_callback,
742 .ident =
"Hewlett-Packard t5745",
749 .callback = intel_no_lvds_dmi_callback,
750 .ident =
"Hewlett-Packard st5747",
757 .callback = intel_no_lvds_dmi_callback,
758 .ident =
"MSI Wind Box DC500",
765 .callback = intel_no_lvds_dmi_callback,
766 .ident =
"ZOTAC ZBOXSD-ID12/ID13",
773 .callback = intel_no_lvds_dmi_callback,
774 .ident =
"Gigabyte GA-D525TUD",
781 .callback = intel_no_lvds_dmi_callback,
782 .ident =
"Supermicro X7SPA-H",
799 static void intel_find_lvds_downclock(
struct drm_device *dev,
807 temp_downclock = fixed_mode->
clock;
824 if (scan->
clock < temp_downclock) {
829 temp_downclock = scan->
clock;
833 if (temp_downclock < fixed_mode->
clock && i915_lvds_downclock) {
837 DRM_DEBUG_KMS(
"LVDS downclock is found in EDID. "
838 "Normal clock %dKhz, downclock %dKhz\n",
839 fixed_mode->
clock, temp_downclock);
850 static bool lvds_is_present_in_vbt(
struct drm_device *dev,
893 static bool intel_lvds_supported(
struct drm_device *dev)
915 struct intel_lvds *intel_lvds;
926 if (!intel_lvds_supported(dev))
934 if (!lvds_is_present_in_vbt(dev, &pin)) {
935 DRM_DEBUG_KMS(
"LVDS is not present in VBT\n");
942 if (dev_priv->
edp.support) {
943 DRM_DEBUG_KMS(
"disable LVDS for eDP support\n");
948 intel_lvds = kzalloc(
sizeof(
struct intel_lvds),
GFP_KERNEL);
953 intel_connector = kzalloc(
sizeof(
struct intel_connector),
GFP_KERNEL);
954 if (!intel_connector) {
963 intel_encoder = &intel_lvds->
base;
964 encoder = &intel_encoder->
base;
965 connector = &intel_connector->
base;
972 intel_encoder->
enable = intel_enable_lvds;
973 intel_encoder->
disable = intel_disable_lvds;
982 intel_encoder->
crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
984 intel_encoder->
crtc_mask = (1 << 0) | (1 << 1);
988 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
989 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
1001 dev->mode_config.scaling_mode_property,
1021 if (intel_lvds->
edid) {
1023 intel_lvds->
edid)) {
1031 if (!intel_lvds->
edid) {
1046 intel_find_lvds_downclock(dev,
1076 crtc = intel_get_crtc_for_pipe(dev, pipe);
1078 if (crtc && (lvds & LVDS_PORT_EN)) {
1103 dev_priv->
lid_notifier.notifier_call = intel_lid_notify;
1105 DRM_DEBUG_KMS(
"lid notifier registration failed\n");
1117 DRM_DEBUG_KMS(
"No LVDS modes found, disabling.\n");
1121 kfree(intel_connector);