Lines Matching +full:lvds +full:- +full:encoder
2 * Copyright © 2006-2007 Intel Corporation
59 /* Private structure for the integrated LVDS support */
82 static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder) in to_lvds_encoder() argument
84 return container_of(encoder, struct intel_lvds_encoder, base); in to_lvds_encoder()
103 static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, in intel_lvds_get_hw_state() argument
106 struct intel_display *display = to_intel_display(encoder); in intel_lvds_get_hw_state()
107 struct drm_i915_private *i915 = to_i915(encoder->base.dev); in intel_lvds_get_hw_state()
108 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_lvds_get_hw_state()
112 wakeref = intel_display_power_get_if_enabled(display, encoder->power_domain); in intel_lvds_get_hw_state()
116 ret = intel_lvds_port_enabled(i915, lvds_encoder->reg, pipe); in intel_lvds_get_hw_state()
118 intel_display_power_put(display, encoder->power_domain, wakeref); in intel_lvds_get_hw_state()
123 static void intel_lvds_get_config(struct intel_encoder *encoder, in intel_lvds_get_config() argument
126 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); in intel_lvds_get_config()
127 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_lvds_get_config()
130 crtc_state->output_types |= BIT(INTEL_OUTPUT_LVDS); in intel_lvds_get_config()
132 tmp = intel_de_read(dev_priv, lvds_encoder->reg); in intel_lvds_get_config()
142 crtc_state->hw.adjusted_mode.flags |= flags; in intel_lvds_get_config()
145 crtc_state->gmch_pfit.lvds_border_bits = in intel_lvds_get_config()
152 crtc_state->gmch_pfit.control |= tmp & PFIT_PANEL_8TO6_DITHER_ENABLE; in intel_lvds_get_config()
155 crtc_state->hw.adjusted_mode.crtc_clock = crtc_state->port_clock; in intel_lvds_get_config()
163 pps->powerdown_on_reset = intel_de_read(dev_priv, in intel_lvds_pps_get_hw_state()
167 pps->port = REG_FIELD_GET(PANEL_PORT_SELECT_MASK, val); in intel_lvds_pps_get_hw_state()
168 pps->delays.power_up = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val); in intel_lvds_pps_get_hw_state()
169 pps->delays.backlight_on = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val); in intel_lvds_pps_get_hw_state()
172 pps->delays.power_down = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val); in intel_lvds_pps_get_hw_state()
173 pps->delays.backlight_off = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val); in intel_lvds_pps_get_hw_state()
176 pps->divider = REG_FIELD_GET(PP_REFERENCE_DIVIDER_MASK, val); in intel_lvds_pps_get_hw_state()
180 * too short power-cycle delay due to the asynchronous programming of in intel_lvds_pps_get_hw_state()
184 val--; in intel_lvds_pps_get_hw_state()
186 pps->delays.power_cycle = val * 1000; in intel_lvds_pps_get_hw_state()
189 pps->delays.power_up == 0 && in intel_lvds_pps_get_hw_state()
190 pps->delays.backlight_on == 0 && in intel_lvds_pps_get_hw_state()
191 pps->delays.power_down == 0 && in intel_lvds_pps_get_hw_state()
192 pps->delays.backlight_off == 0) { in intel_lvds_pps_get_hw_state()
193 drm_dbg_kms(&dev_priv->drm, in intel_lvds_pps_get_hw_state()
197 pps->delays.power_up = 40 * 10; in intel_lvds_pps_get_hw_state()
198 pps->delays.backlight_on = 200 * 10; in intel_lvds_pps_get_hw_state()
200 pps->delays.power_down = 35 * 10; in intel_lvds_pps_get_hw_state()
201 pps->delays.backlight_off = 200 * 10; in intel_lvds_pps_get_hw_state()
204 …drm_dbg(&dev_priv->drm, "LVDS PPS:power_up %d power_down %d power_cycle %d backlight_on %d backlig… in intel_lvds_pps_get_hw_state()
206 pps->delays.power_up, pps->delays.power_down, in intel_lvds_pps_get_hw_state()
207 pps->delays.power_cycle, pps->delays.backlight_on, in intel_lvds_pps_get_hw_state()
208 pps->delays.backlight_off, pps->divider, in intel_lvds_pps_get_hw_state()
209 pps->port, pps->powerdown_on_reset); in intel_lvds_pps_get_hw_state()
218 drm_WARN_ON(&dev_priv->drm, in intel_lvds_pps_init_hw()
220 if (pps->powerdown_on_reset) in intel_lvds_pps_init_hw()
225 REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, pps->port) | in intel_lvds_pps_init_hw()
226 REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->delays.power_up) | in intel_lvds_pps_init_hw()
227 REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->delays.backlight_on)); in intel_lvds_pps_init_hw()
230 REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->delays.power_down) | in intel_lvds_pps_init_hw()
231 REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->delays.backlight_off)); in intel_lvds_pps_init_hw()
234 REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) | in intel_lvds_pps_init_hw()
236 DIV_ROUND_UP(pps->delays.power_cycle, 1000) + 1)); in intel_lvds_pps_init_hw()
240 struct intel_encoder *encoder, in intel_pre_enable_lvds() argument
245 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_pre_enable_lvds()
246 struct drm_i915_private *i915 = to_i915(encoder->base.dev); in intel_pre_enable_lvds()
247 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_pre_enable_lvds()
248 const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; in intel_pre_enable_lvds()
249 enum pipe pipe = crtc->pipe; in intel_pre_enable_lvds()
254 assert_shared_dpll_disabled(display, crtc_state->shared_dpll); in intel_pre_enable_lvds()
259 intel_lvds_pps_init_hw(i915, &lvds_encoder->init_pps); in intel_pre_enable_lvds()
261 temp = lvds_encoder->init_lvds_val; in intel_pre_enable_lvds()
274 temp |= crtc_state->gmch_pfit.lvds_border_bits; in intel_pre_enable_lvds()
277 * Set the B0-B3 data pairs corresponding to whether we're going to in intel_pre_enable_lvds()
278 * set the DPLLs for dual-channel mode or not. in intel_pre_enable_lvds()
280 if (lvds_encoder->is_dual_link) in intel_pre_enable_lvds()
286 * It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) in intel_pre_enable_lvds()
292 temp |= lvds_encoder->a3_power; in intel_pre_enable_lvds()
295 * Set the dithering flag on LVDS as needed, note that there is no in intel_pre_enable_lvds()
296 * special lvds dither control bit on pch-split platforms, dithering is in intel_pre_enable_lvds()
301 * Bspec wording suggests that LVDS port dithering only exists in intel_pre_enable_lvds()
304 if (crtc_state->dither && crtc_state->pipe_bpp == 18) in intel_pre_enable_lvds()
310 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) in intel_pre_enable_lvds()
312 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) in intel_pre_enable_lvds()
315 intel_de_write(i915, lvds_encoder->reg, temp); in intel_pre_enable_lvds()
322 struct intel_encoder *encoder, in intel_enable_lvds() argument
326 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_enable_lvds()
327 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); in intel_enable_lvds()
329 intel_de_rmw(dev_priv, lvds_encoder->reg, 0, LVDS_PORT_EN); in intel_enable_lvds()
332 intel_de_posting_read(dev_priv, lvds_encoder->reg); in intel_enable_lvds()
335 drm_err(&dev_priv->drm, in intel_enable_lvds()
342 struct intel_encoder *encoder, in intel_disable_lvds() argument
346 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_disable_lvds()
347 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); in intel_disable_lvds()
351 drm_err(&dev_priv->drm, in intel_disable_lvds()
354 intel_de_rmw(dev_priv, lvds_encoder->reg, LVDS_PORT_EN, 0); in intel_disable_lvds()
355 intel_de_posting_read(dev_priv, lvds_encoder->reg); in intel_disable_lvds()
359 struct intel_encoder *encoder, in gmch_disable_lvds() argument
366 intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state); in gmch_disable_lvds()
370 struct intel_encoder *encoder, in pch_disable_lvds() argument
378 struct intel_encoder *encoder, in pch_post_disable_lvds() argument
382 intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state); in pch_post_disable_lvds()
385 static void intel_lvds_shutdown(struct intel_encoder *encoder) in intel_lvds_shutdown() argument
387 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); in intel_lvds_shutdown()
390 drm_err(&dev_priv->drm, in intel_lvds_shutdown()
398 struct intel_display *display = to_intel_display(_connector->dev); in intel_lvds_mode_valid()
402 int max_pixclk = display->cdclk.max_dotclk_freq; in intel_lvds_mode_valid()
413 if (fixed_mode->clock > max_pixclk) in intel_lvds_mode_valid()
419 static int intel_lvds_compute_config(struct intel_encoder *encoder, in intel_lvds_compute_config() argument
423 struct drm_i915_private *i915 = to_i915(encoder->base.dev); in intel_lvds_compute_config()
424 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); in intel_lvds_compute_config()
425 struct intel_connector *connector = lvds_encoder->attached_connector; in intel_lvds_compute_config()
426 struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; in intel_lvds_compute_config()
427 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in intel_lvds_compute_config()
432 if (DISPLAY_VER(i915) < 4 && crtc->pipe == 0) { in intel_lvds_compute_config()
433 drm_err(&i915->drm, "Can't support LVDS on pipe A\n"); in intel_lvds_compute_config()
434 return -EINVAL; in intel_lvds_compute_config()
438 crtc_state->has_pch_encoder = true; in intel_lvds_compute_config()
440 return -EINVAL; in intel_lvds_compute_config()
443 if (lvds_encoder->a3_power == LVDS_A3_POWER_UP) in intel_lvds_compute_config()
448 /* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */ in intel_lvds_compute_config()
449 if (lvds_bpp != crtc_state->pipe_bpp && !crtc_state->bw_constrained) { in intel_lvds_compute_config()
450 drm_dbg_kms(&i915->drm, in intel_lvds_compute_config()
451 "forcing display bpp (was %d) to LVDS (%d)\n", in intel_lvds_compute_config()
452 crtc_state->pipe_bpp, lvds_bpp); in intel_lvds_compute_config()
453 crtc_state->pipe_bpp = lvds_bpp; in intel_lvds_compute_config()
456 crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB; in intel_lvds_compute_config()
457 crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB; in intel_lvds_compute_config()
469 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) in intel_lvds_compute_config()
470 return -EINVAL; in intel_lvds_compute_config()
491 const struct drm_edid *fixed_edid = connector->panel.fixed_edid; in intel_lvds_get_modes()
495 drm_edid_connector_update(&connector->base, fixed_edid); in intel_lvds_get_modes()
497 return drm_edid_connector_add_modes(&connector->base); in intel_lvds_get_modes()
527 DRM_INFO("Skipping LVDS initialization for %s\n", id->ident); in intel_no_lvds_dmi_callback()
531 /* These systems claim to have LVDS, but really don't */
551 .ident = "MSI IM-945GSE-A",
578 DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
586 DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
591 .ident = "AOpen i915GMm-HFS",
594 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
599 .ident = "AOpen i45GMx-I",
602 DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
607 .ident = "Aopen i945GTt-VFA",
638 .ident = "Asus AT5NM10T-I",
641 DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
646 .ident = "Hewlett-Packard HP t5740",
648 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
654 .ident = "Hewlett-Packard t5745",
656 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
662 .ident = "Hewlett-Packard st5747",
664 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
672 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
673 DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
678 .ident = "Gigabyte GA-D525TUD",
686 .ident = "Supermicro X7SPA-H",
689 DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
746 DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident); in intel_dual_link_lvds_callback()
780 struct intel_encoder *encoder; in intel_get_lvds_encoder() local
782 for_each_intel_encoder(&i915->drm, encoder) { in intel_get_lvds_encoder()
783 if (encoder->type == INTEL_OUTPUT_LVDS) in intel_get_lvds_encoder()
784 return encoder; in intel_get_lvds_encoder()
792 struct intel_encoder *encoder = intel_get_lvds_encoder(i915); in intel_is_dual_link_lvds() local
794 return encoder && to_lvds_encoder(encoder)->is_dual_link; in intel_is_dual_link_lvds()
799 struct drm_i915_private *i915 = to_i915(lvds_encoder->base.base.dev); in compute_is_dual_link_lvds()
800 struct intel_connector *connector = lvds_encoder->attached_connector; in compute_is_dual_link_lvds()
806 if (i915->display.params.lvds_channel_mode > 0) in compute_is_dual_link_lvds()
807 return i915->display.params.lvds_channel_mode == 2; in compute_is_dual_link_lvds()
809 /* single channel LVDS is limited to 112 MHz */ in compute_is_dual_link_lvds()
810 if (fixed_mode->clock > 112999) in compute_is_dual_link_lvds()
817 * BIOS should set the proper LVDS register value at boot, but in compute_is_dual_link_lvds()
819 * we need to check "the value to be set" in VBT when LVDS in compute_is_dual_link_lvds()
822 val = intel_de_read(i915, lvds_encoder->reg); in compute_is_dual_link_lvds()
828 val = connector->panel.vbt.bios_lvds_val; in compute_is_dual_link_lvds()
839 * intel_lvds_init - setup LVDS connectors on this device
842 * Create the connector, register the LVDS DDC bus, and try to figure out what
843 * modes we can display on the LVDS panel (if present).
847 struct intel_display *display = &i915->display; in intel_lvds_init()
851 struct intel_encoder *encoder; in intel_lvds_init() local
853 u32 lvds; in intel_lvds_init() local
856 /* Skip init on machines we know falsely report LVDS */ in intel_lvds_init()
858 drm_WARN(&i915->drm, !i915->display.vbt.int_lvds_support, in intel_lvds_init()
859 "Useless DMI match. Internal LVDS support disabled by VBT\n"); in intel_lvds_init()
863 if (!i915->display.vbt.int_lvds_support) { in intel_lvds_init()
864 drm_dbg_kms(&i915->drm, in intel_lvds_init()
865 "Internal LVDS support disabled by VBT\n"); in intel_lvds_init()
872 lvds_reg = LVDS; in intel_lvds_init()
874 lvds = intel_de_read(i915, lvds_reg); in intel_lvds_init()
877 if ((lvds & LVDS_DETECTED) == 0) in intel_lvds_init()
883 if ((lvds & LVDS_PORT_EN) == 0) { in intel_lvds_init()
884 drm_dbg_kms(&i915->drm, in intel_lvds_init()
885 "LVDS is not present in VBT\n"); in intel_lvds_init()
888 drm_dbg_kms(&i915->drm, in intel_lvds_init()
889 "LVDS is not present in VBT, but enabled anyway\n"); in intel_lvds_init()
902 lvds_encoder->attached_connector = connector; in intel_lvds_init()
903 encoder = &lvds_encoder->base; in intel_lvds_init()
905 drm_connector_init_with_ddc(&i915->drm, &connector->base, in intel_lvds_init()
910 drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs, in intel_lvds_init()
911 DRM_MODE_ENCODER_LVDS, "LVDS"); in intel_lvds_init()
913 encoder->enable = intel_enable_lvds; in intel_lvds_init()
914 encoder->pre_enable = intel_pre_enable_lvds; in intel_lvds_init()
915 encoder->compute_config = intel_lvds_compute_config; in intel_lvds_init()
917 encoder->disable = pch_disable_lvds; in intel_lvds_init()
918 encoder->post_disable = pch_post_disable_lvds; in intel_lvds_init()
920 encoder->disable = gmch_disable_lvds; in intel_lvds_init()
922 encoder->get_hw_state = intel_lvds_get_hw_state; in intel_lvds_init()
923 encoder->get_config = intel_lvds_get_config; in intel_lvds_init()
924 encoder->update_pipe = intel_backlight_update; in intel_lvds_init()
925 encoder->shutdown = intel_lvds_shutdown; in intel_lvds_init()
926 connector->get_hw_state = intel_connector_get_hw_state; in intel_lvds_init()
928 intel_connector_attach_encoder(connector, encoder); in intel_lvds_init()
930 encoder->type = INTEL_OUTPUT_LVDS; in intel_lvds_init()
931 encoder->power_domain = POWER_DOMAIN_PORT_OTHER; in intel_lvds_init()
932 encoder->port = PORT_NONE; in intel_lvds_init()
933 encoder->cloneable = 0; in intel_lvds_init()
935 encoder->pipe_mask = BIT(PIPE_B); in intel_lvds_init()
937 encoder->pipe_mask = ~0; in intel_lvds_init()
939 drm_connector_helper_add(&connector->base, &intel_lvds_connector_helper_funcs); in intel_lvds_init()
940 connector->base.display_info.subpixel_order = SubPixelHorizontalRGB; in intel_lvds_init()
942 lvds_encoder->reg = lvds_reg; in intel_lvds_init()
944 intel_lvds_add_properties(&connector->base); in intel_lvds_init()
946 intel_lvds_pps_get_hw_state(i915, &lvds_encoder->init_pps); in intel_lvds_init()
947 lvds_encoder->init_lvds_val = lvds; in intel_lvds_init()
950 * LVDS discovery: in intel_lvds_init()
953 * 3) check to see if LVDS is already on in intel_lvds_init()
961 mutex_lock(&i915->drm.mode_config.mutex); in intel_lvds_init()
963 drm_edid = drm_edid_read_switcheroo(&connector->base, connector->base.ddc); in intel_lvds_init()
965 drm_edid = drm_edid_read_ddc(&connector->base, connector->base.ddc); in intel_lvds_init()
967 if (drm_edid_connector_update(&connector->base, drm_edid) || in intel_lvds_init()
968 !drm_edid_connector_add_modes(&connector->base)) { in intel_lvds_init()
969 drm_edid_connector_update(&connector->base, NULL); in intel_lvds_init()
971 drm_edid = ERR_PTR(-EINVAL); in intel_lvds_init()
974 drm_edid = ERR_PTR(-ENOENT); in intel_lvds_init()
976 intel_bios_init_panel_late(display, &connector->panel, NULL, in intel_lvds_init()
992 intel_panel_add_encoder_fixed_mode(connector, encoder); in intel_lvds_init()
994 mutex_unlock(&i915->drm.mode_config.mutex); in intel_lvds_init()
1004 lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); in intel_lvds_init()
1005 drm_dbg_kms(&i915->drm, "detected %s-link lvds configuration\n", in intel_lvds_init()
1006 lvds_encoder->is_dual_link ? "dual" : "single"); in intel_lvds_init()
1008 lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK; in intel_lvds_init()
1013 drm_dbg_kms(&i915->drm, "No LVDS modes found, disabling.\n"); in intel_lvds_init()
1014 drm_connector_cleanup(&connector->base); in intel_lvds_init()
1015 drm_encoder_cleanup(&encoder->base); in intel_lvds_init()