Rev 3243 | Rev 3746 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3243 | Rev 3480 | ||
---|---|---|---|
Line 46... | Line 46... | ||
46 | { |
46 | { |
47 | struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); |
47 | struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); |
48 | struct drm_i915_private *dev_priv = dev->dev_private; |
48 | struct drm_i915_private *dev_priv = dev->dev_private; |
49 | uint32_t enabled_bits; |
49 | uint32_t enabled_bits; |
Line 50... | Line 50... | ||
50 | 50 | ||
Line 51... | Line 51... | ||
51 | enabled_bits = IS_HASWELL(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; |
51 | enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; |
52 | 52 | ||
53 | WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits, |
53 | WARN(I915_READ(intel_hdmi->sdvox_reg) & enabled_bits, |
Line 329... | Line 329... | ||
329 | } |
329 | } |
Line 330... | Line 330... | ||
330 | 330 | ||
331 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
331 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
332 | struct drm_display_mode *adjusted_mode) |
332 | struct drm_display_mode *adjusted_mode) |
- | 333 | { |
|
333 | { |
334 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
334 | struct dip_infoframe avi_if = { |
335 | struct dip_infoframe avi_if = { |
335 | .type = DIP_TYPE_AVI, |
336 | .type = DIP_TYPE_AVI, |
336 | .ver = DIP_VERSION_AVI, |
337 | .ver = DIP_VERSION_AVI, |
337 | .len = DIP_LEN_AVI, |
338 | .len = DIP_LEN_AVI, |
Line 338... | Line 339... | ||
338 | }; |
339 | }; |
339 | 340 | ||
Line -... | Line 341... | ||
- | 341 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) |
|
- | 342 | avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; |
|
- | 343 | ||
- | 344 | if (intel_hdmi->rgb_quant_range_selectable) { |
|
- | 345 | if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE) |
|
- | 346 | avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; |
|
- | 347 | else |
|
340 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) |
348 | avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; |
Line 341... | Line 349... | ||
341 | avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; |
349 | } |
342 | 350 | ||
Line 343... | Line 351... | ||
343 | avi_if.body.avi.VIC = drm_mode_cea_vic(adjusted_mode); |
351 | avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); |
Line 362... | Line 370... | ||
362 | 370 | ||
363 | static void g4x_set_infoframes(struct drm_encoder *encoder, |
371 | static void g4x_set_infoframes(struct drm_encoder *encoder, |
364 | struct drm_display_mode *adjusted_mode) |
372 | struct drm_display_mode *adjusted_mode) |
365 | { |
373 | { |
- | 374 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
|
366 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
375 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
367 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
376 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; |
368 | u32 reg = VIDEO_DIP_CTL; |
377 | u32 reg = VIDEO_DIP_CTL; |
369 | u32 val = I915_READ(reg); |
378 | u32 val = I915_READ(reg); |
Line 370... | Line 379... | ||
370 | u32 port; |
379 | u32 port; |
Line 389... | Line 398... | ||
389 | I915_WRITE(reg, val); |
398 | I915_WRITE(reg, val); |
390 | POSTING_READ(reg); |
399 | POSTING_READ(reg); |
391 | return; |
400 | return; |
392 | } |
401 | } |
Line 393... | Line 402... | ||
393 | 402 | ||
394 | switch (intel_hdmi->sdvox_reg) { |
403 | switch (intel_dig_port->port) { |
395 | case SDVOB: |
404 | case PORT_B: |
396 | port = VIDEO_DIP_PORT_B; |
405 | port = VIDEO_DIP_PORT_B; |
397 | break; |
406 | break; |
398 | case SDVOC: |
407 | case PORT_C: |
399 | port = VIDEO_DIP_PORT_C; |
408 | port = VIDEO_DIP_PORT_C; |
400 | break; |
409 | break; |
401 | default: |
410 | default: |
402 | BUG(); |
411 | BUG(); |
Line 426... | Line 435... | ||
426 | static void ibx_set_infoframes(struct drm_encoder *encoder, |
435 | static void ibx_set_infoframes(struct drm_encoder *encoder, |
427 | struct drm_display_mode *adjusted_mode) |
436 | struct drm_display_mode *adjusted_mode) |
428 | { |
437 | { |
429 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
438 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
430 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
439 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
- | 440 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
|
431 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
441 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; |
432 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
442 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
433 | u32 val = I915_READ(reg); |
443 | u32 val = I915_READ(reg); |
434 | u32 port; |
444 | u32 port; |
Line 435... | Line 445... | ||
435 | 445 | ||
Line 445... | Line 455... | ||
445 | I915_WRITE(reg, val); |
455 | I915_WRITE(reg, val); |
446 | POSTING_READ(reg); |
456 | POSTING_READ(reg); |
447 | return; |
457 | return; |
448 | } |
458 | } |
Line 449... | Line 459... | ||
449 | 459 | ||
450 | switch (intel_hdmi->sdvox_reg) { |
460 | switch (intel_dig_port->port) { |
451 | case HDMIB: |
461 | case PORT_B: |
452 | port = VIDEO_DIP_PORT_B; |
462 | port = VIDEO_DIP_PORT_B; |
453 | break; |
463 | break; |
454 | case HDMIC: |
464 | case PORT_C: |
455 | port = VIDEO_DIP_PORT_C; |
465 | port = VIDEO_DIP_PORT_C; |
456 | break; |
466 | break; |
457 | case HDMID: |
467 | case PORT_D: |
458 | port = VIDEO_DIP_PORT_D; |
468 | port = VIDEO_DIP_PORT_D; |
459 | break; |
469 | break; |
460 | default: |
470 | default: |
461 | BUG(); |
471 | BUG(); |
Line 764... | Line 774... | ||
764 | 774 | ||
765 | bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, |
775 | bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, |
766 | const struct drm_display_mode *mode, |
776 | const struct drm_display_mode *mode, |
767 | struct drm_display_mode *adjusted_mode) |
777 | struct drm_display_mode *adjusted_mode) |
768 | { |
- | |
769 | return true; |
- | |
770 | } |
- | |
771 | - | ||
772 | static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi) |
- | |
773 | { |
778 | { |
774 | struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); |
- | |
775 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
Line 776... | Line 779... | ||
776 | uint32_t bit; |
779 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
777 | 780 | ||
778 | switch (intel_hdmi->sdvox_reg) { |
781 | if (intel_hdmi->color_range_auto) { |
779 | case SDVOB: |
- | |
780 | bit = HDMIB_HOTPLUG_LIVE_STATUS; |
782 | /* See CEA-861-E - 5.1 Default Encoding Parameters */ |
781 | break; |
783 | if (intel_hdmi->has_hdmi_sink && |
782 | case SDVOC: |
784 | drm_match_cea_mode(adjusted_mode) > 1) |
783 | bit = HDMIC_HOTPLUG_LIVE_STATUS; |
- | |
784 | break; |
785 | intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; |
785 | default: |
- | |
786 | bit = 0; |
786 | else |
Line -... | Line 787... | ||
- | 787 | intel_hdmi->color_range = 0; |
|
787 | break; |
788 | } |
- | 789 | ||
- | 790 | if (intel_hdmi->color_range) |
|
788 | } |
791 | adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE; |
Line 789... | Line 792... | ||
789 | 792 | ||
790 | return I915_READ(PORT_HOTPLUG_STAT) & bit; |
793 | return true; |
791 | } |
794 | } |
- | 795 | ||
792 | 796 | static enum drm_connector_status |
|
793 | static enum drm_connector_status |
797 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
794 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
798 | { |
795 | { |
799 | struct drm_device *dev = connector->dev; |
796 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
800 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
797 | struct intel_digital_port *intel_dig_port = |
801 | struct intel_digital_port *intel_dig_port = |
798 | hdmi_to_dig_port(intel_hdmi); |
802 | hdmi_to_dig_port(intel_hdmi); |
Line 799... | Line -... | ||
799 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
- | |
800 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
- | |
801 | struct edid *edid; |
- | |
802 | enum drm_connector_status status = connector_status_disconnected; |
803 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
803 | 804 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 805 | struct edid *edid; |
|
804 | if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi)) |
806 | enum drm_connector_status status = connector_status_disconnected; |
805 | return status; |
807 | |
806 | 808 | intel_hdmi->has_hdmi_sink = false; |
|
Line 807... | Line 809... | ||
807 | intel_hdmi->has_hdmi_sink = false; |
809 | intel_hdmi->has_audio = false; |
Line 815... | Line 817... | ||
815 | status = connector_status_connected; |
817 | status = connector_status_connected; |
816 | if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) |
818 | if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) |
817 | intel_hdmi->has_hdmi_sink = |
819 | intel_hdmi->has_hdmi_sink = |
818 | drm_detect_hdmi_monitor(edid); |
820 | drm_detect_hdmi_monitor(edid); |
819 | intel_hdmi->has_audio = drm_detect_monitor_audio(edid); |
821 | intel_hdmi->has_audio = drm_detect_monitor_audio(edid); |
- | 822 | intel_hdmi->rgb_quant_range_selectable = |
|
- | 823 | drm_rgb_quant_range_selectable(edid); |
|
820 | } |
824 | } |
821 | kfree(edid); |
825 | kfree(edid); |
822 | } |
826 | } |
Line 823... | Line 827... | ||
823 | 827 | ||
Line 877... | Line 881... | ||
877 | int ret; |
881 | int ret; |
Line 878... | Line 882... | ||
878 | 882 | ||
879 | ret = drm_object_property_set_value(&connector->base, property, val); |
883 | ret = drm_object_property_set_value(&connector->base, property, val); |
880 | if (ret) |
884 | if (ret) |
881 | return ret; |
885 | return ret; |
882 | #if 0 |
886 | |
883 | if (property == dev_priv->force_audio_property) { |
887 | if (property == dev_priv->force_audio_property) { |
884 | enum hdmi_force_audio i = val; |
888 | enum hdmi_force_audio i = val; |
Line 885... | Line 889... | ||
885 | bool has_audio; |
889 | bool has_audio; |
Line 898... | Line 902... | ||
898 | intel_hdmi->has_hdmi_sink = 0; |
902 | intel_hdmi->has_hdmi_sink = 0; |
Line 899... | Line 903... | ||
899 | 903 | ||
900 | intel_hdmi->has_audio = has_audio; |
904 | intel_hdmi->has_audio = has_audio; |
901 | goto done; |
905 | goto done; |
902 | } |
- | |
Line 903... | Line 906... | ||
903 | #endif |
906 | } |
- | 907 | ||
- | 908 | if (property == dev_priv->broadcast_rgb_property) { |
|
904 | 909 | switch (val) { |
|
905 | if (property == dev_priv->broadcast_rgb_property) { |
910 | case INTEL_BROADCAST_RGB_AUTO: |
- | 911 | intel_hdmi->color_range_auto = true; |
|
- | 912 | break; |
|
- | 913 | case INTEL_BROADCAST_RGB_FULL: |
|
906 | if (val == !!intel_hdmi->color_range) |
914 | intel_hdmi->color_range_auto = false; |
- | 915 | intel_hdmi->color_range = 0; |
|
- | 916 | break; |
|
907 | return 0; |
917 | case INTEL_BROADCAST_RGB_LIMITED: |
- | 918 | intel_hdmi->color_range_auto = false; |
|
- | 919 | intel_hdmi->color_range = SDVO_COLOR_RANGE_16_235; |
|
- | 920 | break; |
|
- | 921 | default: |
|
908 | 922 | return -EINVAL; |
|
909 | intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; |
923 | } |
Line 910... | Line 924... | ||
910 | goto done; |
924 | goto done; |
Line 911... | Line 925... | ||
911 | } |
925 | } |
912 | 926 | ||
913 | return -EINVAL; |
927 | return -EINVAL; |
914 | - | ||
915 | done: |
- | |
916 | if (intel_dig_port->base.base.crtc) { |
- | |
Line 917... | Line 928... | ||
917 | struct drm_crtc *crtc = intel_dig_port->base.base.crtc; |
928 | |
918 | intel_set_mode(crtc, &crtc->mode, |
929 | done: |
Line 919... | Line 930... | ||
919 | crtc->x, crtc->y, crtc->fb); |
930 | if (intel_dig_port->base.base.crtc) |
Line 930... | Line 941... | ||
930 | } |
941 | } |
Line 931... | Line 942... | ||
931 | 942 | ||
932 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
943 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
933 | .mode_fixup = intel_hdmi_mode_fixup, |
944 | .mode_fixup = intel_hdmi_mode_fixup, |
934 | .mode_set = intel_hdmi_mode_set, |
- | |
935 | .disable = intel_encoder_noop, |
945 | .mode_set = intel_hdmi_mode_set, |
Line 936... | Line 946... | ||
936 | }; |
946 | }; |
937 | 947 | ||
938 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
948 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
Line 956... | Line 966... | ||
956 | static void |
966 | static void |
957 | intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) |
967 | intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) |
958 | { |
968 | { |
959 | intel_attach_force_audio_property(connector); |
969 | intel_attach_force_audio_property(connector); |
960 | intel_attach_broadcast_rgb_property(connector); |
970 | intel_attach_broadcast_rgb_property(connector); |
- | 971 | intel_hdmi->color_range_auto = true; |
|
961 | } |
972 | } |
Line 962... | Line 973... | ||
962 | 973 | ||
963 | void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, |
974 | void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, |
964 | struct intel_connector *intel_connector) |
975 | struct intel_connector *intel_connector) |
Line 979... | Line 990... | ||
979 | connector->doublescan_allowed = 0; |
990 | connector->doublescan_allowed = 0; |
Line 980... | Line 991... | ||
980 | 991 | ||
981 | switch (port) { |
992 | switch (port) { |
982 | case PORT_B: |
993 | case PORT_B: |
983 | intel_hdmi->ddc_bus = GMBUS_PORT_DPB; |
994 | intel_hdmi->ddc_bus = GMBUS_PORT_DPB; |
984 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; |
995 | dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS; |
985 | break; |
996 | break; |
986 | case PORT_C: |
997 | case PORT_C: |
987 | intel_hdmi->ddc_bus = GMBUS_PORT_DPC; |
998 | intel_hdmi->ddc_bus = GMBUS_PORT_DPC; |
988 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; |
999 | dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS; |
989 | break; |
1000 | break; |
990 | case PORT_D: |
1001 | case PORT_D: |
991 | intel_hdmi->ddc_bus = GMBUS_PORT_DPD; |
1002 | intel_hdmi->ddc_bus = GMBUS_PORT_DPD; |
992 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; |
1003 | dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS; |
993 | break; |
1004 | break; |
994 | case PORT_A: |
1005 | case PORT_A: |
995 | /* Internal port only for eDP. */ |
1006 | /* Internal port only for eDP. */ |
996 | default: |
1007 | default: |
Line 1012... | Line 1023... | ||
1012 | } else { |
1023 | } else { |
1013 | intel_hdmi->write_infoframe = cpt_write_infoframe; |
1024 | intel_hdmi->write_infoframe = cpt_write_infoframe; |
1014 | intel_hdmi->set_infoframes = cpt_set_infoframes; |
1025 | intel_hdmi->set_infoframes = cpt_set_infoframes; |
1015 | } |
1026 | } |
Line 1016... | Line 1027... | ||
1016 | 1027 | ||
1017 | if (IS_HASWELL(dev)) |
1028 | if (HAS_DDI(dev)) |
1018 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
1029 | intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; |
1019 | else |
1030 | else |
Line 1020... | Line 1031... | ||
1020 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
1031 | intel_connector->get_hw_state = intel_connector_get_hw_state; |