Rev 2342 | Rev 3120 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2342 | Rev 3031 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | * Eric Anholt |
26 | * Eric Anholt |
27 | */ |
27 | */ |
28 | #include |
28 | #include |
29 | #include |
29 | #include |
30 | //#include |
30 | //#include |
31 | #include "drmP.h" |
31 | #include |
32 | #include "drm.h" |
32 | #include |
33 | #include "drm_crtc.h" |
33 | #include |
34 | #include "drm_edid.h" |
34 | #include |
35 | #include "intel_drv.h" |
35 | #include "intel_drv.h" |
36 | #include "i915_drm.h" |
36 | #include |
37 | #include "i915_drv.h" |
37 | #include "i915_drv.h" |
38 | #include "intel_sdvo_regs.h" |
38 | #include "intel_sdvo_regs.h" |
Line 39... | Line 39... | ||
39 | 39 | ||
40 | unsigned int hweight16(unsigned int w) |
40 | unsigned int hweight16(unsigned int w) |
Line 47... | Line 47... | ||
47 | 47 | ||
48 | 48 | ||
49 | #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) |
49 | #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) |
50 | #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) |
50 | #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) |
Line 51... | Line 51... | ||
51 | #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) |
51 | #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) |
52 | #define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) |
52 | #define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0) |
Line 53... | Line 53... | ||
53 | 53 | ||
Line 80... | Line 80... | ||
80 | u8 slave_addr; |
80 | u8 slave_addr; |
Line 81... | Line 81... | ||
81 | 81 | ||
Line 82... | Line 82... | ||
82 | struct i2c_adapter ddc; |
82 | struct i2c_adapter ddc; |
83 | 83 | ||
Line 84... | Line 84... | ||
84 | /* Register for the SDVO device: SDVOB or SDVOC */ |
84 | /* Register for the SDVO device: SDVOB or SDVOC */ |
85 | int sdvo_reg; |
85 | uint32_t sdvo_reg; |
Line 86... | Line 86... | ||
86 | 86 | ||
Line 103... | Line 103... | ||
103 | uint16_t attached_output; |
103 | uint16_t attached_output; |
Line 104... | Line 104... | ||
104 | 104 | ||
105 | /* |
105 | /* |
106 | * Hotplug activation bits for this device |
106 | * Hotplug activation bits for this device |
107 | */ |
107 | */ |
Line 108... | Line 108... | ||
108 | uint8_t hotplug_active[2]; |
108 | uint16_t hotplug_active; |
109 | 109 | ||
110 | /** |
110 | /** |
111 | * This is used to select the color range of RBG outputs in HDMI mode. |
111 | * This is used to select the color range of RBG outputs in HDMI mode. |
Line 120... | Line 120... | ||
120 | * to decide this for us, the S-Video output on our HDMI+S-Video card |
120 | * to decide this for us, the S-Video output on our HDMI+S-Video card |
121 | * shows up as RGB1 (VGA). |
121 | * shows up as RGB1 (VGA). |
122 | */ |
122 | */ |
123 | bool is_tv; |
123 | bool is_tv; |
Line -... | Line 124... | ||
- | 124 | ||
- | 125 | /* On different gens SDVOB is at different places. */ |
|
- | 126 | bool is_sdvob; |
|
124 | 127 | ||
125 | /* This is for current tv format name */ |
128 | /* This is for current tv format name */ |
Line 126... | Line 129... | ||
126 | int tv_format_index; |
129 | int tv_format_index; |
127 | 130 | ||
Line 144... | Line 147... | ||
144 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
147 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
Line 145... | Line 148... | ||
145 | 148 | ||
146 | /* DDC bus used by this SDVO encoder */ |
149 | /* DDC bus used by this SDVO encoder */ |
Line -... | Line 150... | ||
- | 150 | uint8_t ddc_bus; |
|
147 | uint8_t ddc_bus; |
151 | |
- | 152 | /* |
|
148 | 153 | * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd |
|
149 | /* Input timings for adjusted_mode */ |
154 | */ |
Line 150... | Line 155... | ||
150 | struct intel_sdvo_dtd input_dtd; |
155 | uint8_t dtd_sdvo_flags; |
151 | }; |
156 | }; |
Line 152... | Line 157... | ||
152 | 157 | ||
153 | struct intel_sdvo_connector { |
158 | struct intel_sdvo_connector { |
Line 154... | Line 159... | ||
154 | struct intel_connector base; |
159 | struct intel_connector base; |
Line 155... | Line 160... | ||
155 | 160 | ||
156 | /* Mark the type of connector */ |
161 | /* Mark the type of connector */ |
157 | uint16_t output_flag; |
162 | uint16_t output_flag; |
158 | 163 | ||
Line 409... | Line 414... | ||
409 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), |
414 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), |
410 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), |
415 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), |
411 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
416 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
412 | }; |
417 | }; |
Line 413... | Line -... | ||
413 | - | ||
414 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
418 | |
Line 415... | Line 419... | ||
415 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
419 | #define SDVO_NAME(svdo) ((svdo)->is_sdvob ? "SDVOB" : "SDVOC") |
416 | 420 | ||
417 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
421 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
418 | const void *args, int args_len) |
422 | const void *args, int args_len) |
Line 447... | Line 451... | ||
447 | }; |
451 | }; |
Line 448... | Line 452... | ||
448 | 452 | ||
449 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
453 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
450 | const void *args, int args_len) |
454 | const void *args, int args_len) |
451 | { |
455 | { |
452 | u8 buf[args_len*2 + 2], status; |
456 | u8 *buf, status; |
453 | struct i2c_msg msgs[args_len + 3]; |
457 | struct i2c_msg *msgs; |
- | 458 | int i, ret = true; |
|
- | 459 | ||
- | 460 | /* Would be simpler to allocate both in one go ? */ |
|
- | 461 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); |
|
- | 462 | if (!buf) |
|
- | 463 | return false; |
|
- | 464 | ||
- | 465 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); |
|
- | 466 | if (!msgs) { |
|
- | 467 | kfree(buf); |
|
- | 468 | return false; |
|
Line 454... | Line 469... | ||
454 | int i, ret; |
469 | } |
Line 455... | Line 470... | ||
455 | 470 | ||
456 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
471 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
Line 483... | Line 498... | ||
483 | msgs[i+2].buf = &status; |
498 | msgs[i+2].buf = &status; |
Line 484... | Line 499... | ||
484 | 499 | ||
485 | ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); |
500 | ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); |
486 | if (ret < 0) { |
501 | if (ret < 0) { |
487 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
502 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
- | 503 | ret = false; |
|
488 | return false; |
504 | goto out; |
489 | } |
505 | } |
490 | if (ret != i+3) { |
506 | if (ret != i+3) { |
491 | /* failure in I2C transfer */ |
507 | /* failure in I2C transfer */ |
492 | DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); |
508 | DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); |
493 | return false; |
509 | ret = false; |
Line -... | Line 510... | ||
- | 510 | } |
|
- | 511 | ||
- | 512 | out: |
|
494 | } |
513 | kfree(msgs); |
495 | 514 | kfree(buf); |
|
Line 496... | Line 515... | ||
496 | return true; |
515 | return ret; |
497 | } |
516 | } |
498 | 517 | ||
Line 620... | Line 639... | ||
620 | return intel_sdvo_set_value(intel_sdvo, |
639 | return intel_sdvo_set_value(intel_sdvo, |
621 | SDVO_CMD_SET_ACTIVE_OUTPUTS, |
640 | SDVO_CMD_SET_ACTIVE_OUTPUTS, |
622 | &outputs, sizeof(outputs)); |
641 | &outputs, sizeof(outputs)); |
623 | } |
642 | } |
Line -... | Line 643... | ||
- | 643 | ||
- | 644 | static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo, |
|
- | 645 | u16 *outputs) |
|
- | 646 | { |
|
- | 647 | return intel_sdvo_get_value(intel_sdvo, |
|
- | 648 | SDVO_CMD_GET_ACTIVE_OUTPUTS, |
|
- | 649 | outputs, sizeof(*outputs)); |
|
- | 650 | } |
|
624 | 651 | ||
625 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
652 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
626 | int mode) |
653 | int mode) |
627 | { |
654 | { |
Line 737... | Line 764... | ||
737 | const struct drm_display_mode *mode) |
764 | const struct drm_display_mode *mode) |
738 | { |
765 | { |
739 | uint16_t width, height; |
766 | uint16_t width, height; |
740 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
767 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
741 | uint16_t h_sync_offset, v_sync_offset; |
768 | uint16_t h_sync_offset, v_sync_offset; |
- | 769 | int mode_clock; |
|
Line 742... | Line 770... | ||
742 | 770 | ||
743 | width = mode->crtc_hdisplay; |
771 | width = mode->hdisplay; |
Line 744... | Line 772... | ||
744 | height = mode->crtc_vdisplay; |
772 | height = mode->vdisplay; |
- | 773 | ||
745 | 774 | /* do some mode translations */ |
|
- | 775 | h_blank_len = mode->htotal - mode->hdisplay; |
|
- | 776 | h_sync_len = mode->hsync_end - mode->hsync_start; |
|
746 | /* do some mode translations */ |
777 | |
Line 747... | Line 778... | ||
747 | h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; |
778 | v_blank_len = mode->vtotal - mode->vdisplay; |
748 | h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; |
779 | v_sync_len = mode->vsync_end - mode->vsync_start; |
Line -... | Line 780... | ||
- | 780 | ||
749 | 781 | h_sync_offset = mode->hsync_start - mode->hdisplay; |
|
- | 782 | v_sync_offset = mode->vsync_start - mode->vdisplay; |
|
750 | v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; |
783 | |
Line 751... | Line -... | ||
751 | v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; |
- | |
752 | 784 | mode_clock = mode->clock; |
|
753 | h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; |
785 | mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; |
754 | v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; |
786 | mode_clock /= 10; |
755 | 787 | dtd->part1.clock = mode_clock; |
|
756 | dtd->part1.clock = mode->clock / 10; |
788 | |
Line 770... | Line 802... | ||
770 | dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | |
802 | dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | |
771 | ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | |
803 | ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | |
772 | ((v_sync_len & 0x30) >> 4); |
804 | ((v_sync_len & 0x30) >> 4); |
Line 773... | Line 805... | ||
773 | 805 | ||
- | 806 | dtd->part2.dtd_flags = 0x18; |
|
- | 807 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
|
774 | dtd->part2.dtd_flags = 0x18; |
808 | dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE; |
775 | if (mode->flags & DRM_MODE_FLAG_PHSYNC) |
809 | if (mode->flags & DRM_MODE_FLAG_PHSYNC) |
776 | dtd->part2.dtd_flags |= 0x2; |
810 | dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE; |
777 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) |
811 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) |
Line 778... | Line 812... | ||
778 | dtd->part2.dtd_flags |= 0x4; |
812 | dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; |
779 | 813 | ||
780 | dtd->part2.sdvo_flags = 0; |
814 | dtd->part2.sdvo_flags = 0; |
781 | dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; |
815 | dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; |
Line 807... | Line 841... | ||
807 | mode->vtotal += (dtd->part1.v_high & 0xf) << 8; |
841 | mode->vtotal += (dtd->part1.v_high & 0xf) << 8; |
Line 808... | Line 842... | ||
808 | 842 | ||
Line 809... | Line 843... | ||
809 | mode->clock = dtd->part1.clock * 10; |
843 | mode->clock = dtd->part1.clock * 10; |
810 | 844 | ||
- | 845 | mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
|
- | 846 | if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) |
|
811 | mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); |
847 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
812 | if (dtd->part2.dtd_flags & 0x2) |
848 | if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) |
813 | mode->flags |= DRM_MODE_FLAG_PHSYNC; |
849 | mode->flags |= DRM_MODE_FLAG_PHSYNC; |
814 | if (dtd->part2.dtd_flags & 0x4) |
850 | if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) |
Line 815... | Line 851... | ||
815 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
851 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
816 | } |
852 | } |
Line 865... | Line 901... | ||
865 | } |
901 | } |
866 | } |
902 | } |
867 | } |
903 | } |
868 | #endif |
904 | #endif |
Line 869... | Line 905... | ||
869 | 905 | ||
- | 906 | static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, |
|
- | 907 | unsigned if_index, uint8_t tx_rate, |
|
870 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
908 | uint8_t *data, unsigned length) |
871 | { |
- | |
872 | struct dip_infoframe avi_if = { |
- | |
873 | .type = DIP_TYPE_AVI, |
- | |
874 | .ver = DIP_VERSION_AVI, |
- | |
875 | .len = DIP_LEN_AVI, |
- | |
876 | }; |
- | |
877 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; |
909 | { |
878 | uint8_t set_buf_index[2] = { 1, 0 }; |
910 | uint8_t set_buf_index[2] = { if_index, 0 }; |
879 | uint64_t *data = (uint64_t *)&avi_if; |
911 | uint8_t hbuf_size, tmp[8]; |
880 | unsigned i; |
- | |
881 | - | ||
Line 882... | Line 912... | ||
882 | intel_dip_infoframe_csum(&avi_if); |
912 | int i; |
883 | 913 | ||
884 | if (!intel_sdvo_set_value(intel_sdvo, |
914 | if (!intel_sdvo_set_value(intel_sdvo, |
885 | SDVO_CMD_SET_HBUF_INDEX, |
915 | SDVO_CMD_SET_HBUF_INDEX, |
Line -... | Line 916... | ||
- | 916 | set_buf_index, 2)) |
|
- | 917 | return false; |
|
- | 918 | ||
- | 919 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, |
|
- | 920 | &hbuf_size, 1)) |
|
- | 921 | return false; |
|
- | 922 | ||
- | 923 | /* Buffer size is 0 based, hooray! */ |
|
- | 924 | hbuf_size++; |
|
- | 925 | ||
886 | set_buf_index, 2)) |
926 | DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", |
- | 927 | if_index, length, hbuf_size); |
|
- | 928 | ||
- | 929 | for (i = 0; i < hbuf_size; i += 8) { |
|
- | 930 | memset(tmp, 0, 8); |
|
887 | return false; |
931 | if (i < length) |
888 | 932 | memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); |
|
889 | for (i = 0; i < sizeof(avi_if); i += 8) { |
933 | |
890 | if (!intel_sdvo_set_value(intel_sdvo, |
934 | if (!intel_sdvo_set_value(intel_sdvo, |
891 | SDVO_CMD_SET_HBUF_DATA, |
- | |
892 | data, 8)) |
935 | SDVO_CMD_SET_HBUF_DATA, |
Line 893... | Line 936... | ||
893 | return false; |
936 | tmp, 8)) |
894 | data++; |
937 | return false; |
895 | } |
938 | } |
896 | 939 | ||
Line -... | Line 940... | ||
- | 940 | return intel_sdvo_set_value(intel_sdvo, |
|
- | 941 | SDVO_CMD_SET_HBUF_TXRATE, |
|
- | 942 | &tx_rate, 1); |
|
- | 943 | } |
|
- | 944 | ||
- | 945 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
|
- | 946 | { |
|
- | 947 | struct dip_infoframe avi_if = { |
|
- | 948 | .type = DIP_TYPE_AVI, |
|
- | 949 | .ver = DIP_VERSION_AVI, |
|
- | 950 | .len = DIP_LEN_AVI, |
|
- | 951 | }; |
|
- | 952 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
|
- | 953 | ||
- | 954 | intel_dip_infoframe_csum(&avi_if); |
|
- | 955 | ||
- | 956 | /* sdvo spec says that the ecc is handled by the hw, and it looks like |
|
- | 957 | * we must not send the ecc field, either. */ |
|
- | 958 | memcpy(sdvo_data, &avi_if, 3); |
|
- | 959 | sdvo_data[3] = avi_if.checksum; |
|
- | 960 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
|
- | 961 | ||
897 | return intel_sdvo_set_value(intel_sdvo, |
962 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
898 | SDVO_CMD_SET_HBUF_TXRATE, |
963 | SDVO_HBUF_TX_VSYNC, |
899 | &tx_rate, 1); |
964 | sdvo_data, sizeof(sdvo_data)); |
900 | } |
965 | } |
Line 914... | Line 979... | ||
914 | &format, sizeof(format)); |
979 | &format, sizeof(format)); |
915 | } |
980 | } |
Line 916... | Line 981... | ||
916 | 981 | ||
917 | static bool |
982 | static bool |
918 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
983 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
919 | struct drm_display_mode *mode) |
984 | const struct drm_display_mode *mode) |
920 | { |
985 | { |
Line 921... | Line 986... | ||
921 | struct intel_sdvo_dtd output_dtd; |
986 | struct intel_sdvo_dtd output_dtd; |
922 | 987 | ||
Line 929... | Line 994... | ||
929 | return false; |
994 | return false; |
Line 930... | Line 995... | ||
930 | 995 | ||
931 | return true; |
996 | return true; |
Line -... | Line 997... | ||
- | 997 | } |
|
- | 998 | ||
932 | } |
999 | /* Asks the sdvo controller for the preferred input mode given the output mode. |
933 | 1000 | * Unfortunately we have to set up the full output mode to do that. */ |
|
934 | static bool |
1001 | static bool |
935 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, |
1002 | intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, |
936 | struct drm_display_mode *mode, |
1003 | const struct drm_display_mode *mode, |
- | 1004 | struct drm_display_mode *adjusted_mode) |
|
- | 1005 | { |
|
937 | struct drm_display_mode *adjusted_mode) |
1006 | struct intel_sdvo_dtd input_dtd; |
938 | { |
1007 | |
939 | /* Reset the input timing to the screen. Assume always input 0. */ |
1008 | /* Reset the input timing to the screen. Assume always input 0. */ |
Line 940... | Line 1009... | ||
940 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1009 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
Line 945... | Line 1014... | ||
945 | mode->hdisplay, |
1014 | mode->hdisplay, |
946 | mode->vdisplay)) |
1015 | mode->vdisplay)) |
947 | return false; |
1016 | return false; |
Line 948... | Line 1017... | ||
948 | 1017 | ||
949 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
1018 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
950 | &intel_sdvo->input_dtd)) |
1019 | &input_dtd)) |
Line 951... | Line 1020... | ||
951 | return false; |
1020 | return false; |
- | 1021 | ||
Line 952... | Line -... | ||
952 | - | ||
953 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); |
1022 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
954 | 1023 | intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags; |
|
Line 955... | Line 1024... | ||
955 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
1024 | |
956 | return true; |
1025 | return true; |
957 | } |
1026 | } |
958 | 1027 | ||
959 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
1028 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
960 | struct drm_display_mode *mode, |
1029 | const struct drm_display_mode *mode, |
Line 970... | Line 1039... | ||
970 | */ |
1039 | */ |
971 | if (intel_sdvo->is_tv) { |
1040 | if (intel_sdvo->is_tv) { |
972 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
1041 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
973 | return false; |
1042 | return false; |
Line 974... | Line 1043... | ||
974 | 1043 | ||
975 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1044 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
976 | mode, |
1045 | mode, |
977 | adjusted_mode); |
1046 | adjusted_mode); |
978 | } else if (intel_sdvo->is_lvds) { |
1047 | } else if (intel_sdvo->is_lvds) { |
979 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1048 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
980 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1049 | intel_sdvo->sdvo_lvds_fixed_mode)) |
Line 981... | Line 1050... | ||
981 | return false; |
1050 | return false; |
982 | 1051 | ||
983 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1052 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
984 | mode, |
1053 | mode, |
Line 985... | Line 1054... | ||
985 | adjusted_mode); |
1054 | adjusted_mode); |
Line 1003... | Line 1072... | ||
1003 | struct drm_crtc *crtc = encoder->crtc; |
1072 | struct drm_crtc *crtc = encoder->crtc; |
1004 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1073 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1005 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1074 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1006 | u32 sdvox; |
1075 | u32 sdvox; |
1007 | struct intel_sdvo_in_out_map in_out; |
1076 | struct intel_sdvo_in_out_map in_out; |
1008 | struct intel_sdvo_dtd input_dtd; |
1077 | struct intel_sdvo_dtd input_dtd, output_dtd; |
1009 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
1078 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
1010 | int rate; |
1079 | int rate; |
Line 1011... | Line 1080... | ||
1011 | 1080 | ||
1012 | if (!mode) |
1081 | if (!mode) |
Line 1028... | Line 1097... | ||
1028 | /* Set the output timings to the screen */ |
1097 | /* Set the output timings to the screen */ |
1029 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1098 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1030 | intel_sdvo->attached_output)) |
1099 | intel_sdvo->attached_output)) |
1031 | return; |
1100 | return; |
Line 1032... | Line 1101... | ||
1032 | 1101 | ||
1033 | /* We have tried to get input timing in mode_fixup, and filled into |
1102 | /* lvds has a special fixed output timing. */ |
1034 | * adjusted_mode. |
- | |
1035 | */ |
1103 | if (intel_sdvo->is_lvds) |
1036 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { |
1104 | intel_sdvo_get_dtd_from_mode(&output_dtd, |
1037 | input_dtd = intel_sdvo->input_dtd; |
1105 | intel_sdvo->sdvo_lvds_fixed_mode); |
1038 | } else { |
- | |
1039 | /* Set the output timing to the screen */ |
1106 | else |
1040 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1107 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1041 | intel_sdvo->attached_output)) |
- | |
1042 | return; |
- | |
1043 | 1108 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
|
1044 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1109 | DRM_INFO("Setting output timings on %s failed\n", |
1045 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); |
- | |
Line 1046... | Line 1110... | ||
1046 | } |
1110 | SDVO_NAME(intel_sdvo)); |
1047 | 1111 | ||
1048 | /* Set the input timing to the screen. Assume always input 0. */ |
1112 | /* Set the input timing to the screen. Assume always input 0. */ |
Line 1059... | Line 1123... | ||
1059 | 1123 | ||
1060 | if (intel_sdvo->is_tv && |
1124 | if (intel_sdvo->is_tv && |
1061 | !intel_sdvo_set_tv_format(intel_sdvo)) |
1125 | !intel_sdvo_set_tv_format(intel_sdvo)) |
Line -... | Line 1126... | ||
- | 1126 | return; |
|
- | 1127 | ||
- | 1128 | /* We have tried to get input timing in mode_fixup, and filled into |
|
- | 1129 | * adjusted_mode. |
|
- | 1130 | */ |
|
- | 1131 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
|
1062 | return; |
1132 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
- | 1133 | input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; |
|
- | 1134 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
|
Line 1063... | Line 1135... | ||
1063 | 1135 | DRM_INFO("Setting input timings on %s failed\n", |
|
1064 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1136 | SDVO_NAME(intel_sdvo)); |
1065 | 1137 | ||
1066 | switch (pixel_multiplier) { |
1138 | switch (pixel_multiplier) { |
Line 1114... | Line 1186... | ||
1114 | INTEL_INFO(dev)->gen < 5) |
1186 | INTEL_INFO(dev)->gen < 5) |
1115 | sdvox |= SDVO_STALL_SELECT; |
1187 | sdvox |= SDVO_STALL_SELECT; |
1116 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1188 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1117 | } |
1189 | } |
Line 1118... | Line 1190... | ||
1118 | 1190 | ||
1119 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
1191 | static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector) |
- | 1192 | { |
|
- | 1193 | struct intel_sdvo_connector *intel_sdvo_connector = |
|
- | 1194 | to_intel_sdvo_connector(&connector->base); |
|
- | 1195 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base); |
|
- | 1196 | u16 active_outputs; |
|
- | 1197 | ||
- | 1198 | intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); |
|
- | 1199 | ||
- | 1200 | if (active_outputs & intel_sdvo_connector->output_flag) |
|
- | 1201 | return true; |
|
- | 1202 | else |
|
- | 1203 | return false; |
|
- | 1204 | } |
|
- | 1205 | ||
- | 1206 | static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, |
|
- | 1207 | enum pipe *pipe) |
|
1120 | { |
1208 | { |
1121 | struct drm_device *dev = encoder->dev; |
1209 | struct drm_device *dev = encoder->base.dev; |
1122 | struct drm_i915_private *dev_priv = dev->dev_private; |
1210 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 1211 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
|
- | 1212 | u32 tmp; |
|
- | 1213 | ||
- | 1214 | tmp = I915_READ(intel_sdvo->sdvo_reg); |
|
- | 1215 | ||
- | 1216 | if (!(tmp & SDVO_ENABLE)) |
|
- | 1217 | return false; |
|
- | 1218 | ||
- | 1219 | if (HAS_PCH_CPT(dev)) |
|
- | 1220 | *pipe = PORT_TO_PIPE_CPT(tmp); |
|
- | 1221 | else |
|
- | 1222 | *pipe = PORT_TO_PIPE(tmp); |
|
- | 1223 | ||
- | 1224 | return true; |
|
- | 1225 | } |
|
- | 1226 | ||
- | 1227 | static void intel_disable_sdvo(struct intel_encoder *encoder) |
|
- | 1228 | { |
|
1123 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1229 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
1124 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
1230 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
Line 1125... | Line -... | ||
1125 | u32 temp; |
- | |
1126 | 1231 | u32 temp; |
|
1127 | if (mode != DRM_MODE_DPMS_ON) { |
1232 | |
1128 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
1233 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
- | 1234 | if (0) |
|
Line 1129... | Line -... | ||
1129 | if (0) |
- | |
1130 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1235 | intel_sdvo_set_encoder_power_state(intel_sdvo, |
1131 | 1236 | DRM_MODE_DPMS_OFF); |
|
1132 | if (mode == DRM_MODE_DPMS_OFF) { |
1237 | |
1133 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1238 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1134 | if ((temp & SDVO_ENABLE) != 0) { |
1239 | if ((temp & SDVO_ENABLE) != 0) { |
- | 1240 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
|
- | 1241 | } |
|
- | 1242 | } |
|
- | 1243 | ||
- | 1244 | static void intel_enable_sdvo(struct intel_encoder *encoder) |
|
- | 1245 | { |
|
- | 1246 | struct drm_device *dev = encoder->base.dev; |
|
1135 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
1247 | struct drm_i915_private *dev_priv = dev->dev_private; |
1136 | } |
1248 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
1137 | } |
1249 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
1138 | } else { |
1250 | u32 temp; |
Line 1139... | Line 1251... | ||
1139 | bool input1, input2; |
1251 | bool input1, input2; |
Line 1155... | Line 1267... | ||
1155 | DRM_DEBUG_KMS("First %s output reported failure to " |
1267 | DRM_DEBUG_KMS("First %s output reported failure to " |
1156 | "sync\n", SDVO_NAME(intel_sdvo)); |
1268 | "sync\n", SDVO_NAME(intel_sdvo)); |
1157 | } |
1269 | } |
Line 1158... | Line 1270... | ||
1158 | 1270 | ||
1159 | if (0) |
1271 | if (0) |
- | 1272 | intel_sdvo_set_encoder_power_state(intel_sdvo, |
|
1160 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1273 | DRM_MODE_DPMS_ON); |
1161 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
1274 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
- | 1275 | } |
|
- | 1276 | ||
- | 1277 | static void intel_sdvo_dpms(struct drm_connector *connector, int mode) |
|
- | 1278 | { |
|
- | 1279 | struct drm_crtc *crtc; |
|
- | 1280 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
|
- | 1281 | ||
- | 1282 | /* dvo supports only 2 dpms states. */ |
|
- | 1283 | if (mode != DRM_MODE_DPMS_ON) |
|
- | 1284 | mode = DRM_MODE_DPMS_OFF; |
|
- | 1285 | ||
- | 1286 | if (mode == connector->dpms) |
|
- | 1287 | return; |
|
- | 1288 | ||
- | 1289 | connector->dpms = mode; |
|
- | 1290 | ||
- | 1291 | /* Only need to change hw state when actually enabled */ |
|
- | 1292 | crtc = intel_sdvo->base.base.crtc; |
|
- | 1293 | if (!crtc) { |
|
1162 | } |
1294 | intel_sdvo->base.connectors_active = false; |
1163 | return; |
1295 | return; |
Line -... | Line 1296... | ||
- | 1296 | } |
|
- | 1297 | ||
- | 1298 | if (mode != DRM_MODE_DPMS_ON) { |
|
- | 1299 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
|
- | 1300 | if (0) |
|
- | 1301 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
|
- | 1302 | ||
- | 1303 | intel_sdvo->base.connectors_active = false; |
|
- | 1304 | ||
- | 1305 | intel_crtc_update_dpms(crtc); |
|
- | 1306 | } else { |
|
- | 1307 | intel_sdvo->base.connectors_active = true; |
|
- | 1308 | ||
- | 1309 | intel_crtc_update_dpms(crtc); |
|
- | 1310 | ||
- | 1311 | if (0) |
|
- | 1312 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
|
- | 1313 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
|
- | 1314 | } |
|
- | 1315 | ||
- | 1316 | intel_modeset_check_state(connector->dev); |
|
1164 | } |
1317 | } |
1165 | 1318 | ||
1166 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1319 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1167 | struct drm_display_mode *mode) |
1320 | struct drm_display_mode *mode) |
Line 1223... | Line 1376... | ||
1223 | caps->output_flags); |
1376 | caps->output_flags); |
Line 1224... | Line 1377... | ||
1224 | 1377 | ||
1225 | return true; |
1378 | return true; |
Line 1226... | Line 1379... | ||
1226 | } |
1379 | } |
1227 | 1380 | ||
- | 1381 | static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) |
|
1228 | static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) |
1382 | { |
Line -... | Line 1383... | ||
- | 1383 | struct drm_device *dev = intel_sdvo->base.base.dev; |
|
- | 1384 | uint16_t hotplug; |
|
- | 1385 | ||
- | 1386 | /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise |
|
- | 1387 | * on the line. */ |
|
1229 | { |
1388 | if (IS_I945G(dev) || IS_I945GM(dev)) |
1230 | u8 response[2]; |
1389 | return 0; |
- | 1390 | ||
- | 1391 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
|
- | 1392 | &hotplug, sizeof(hotplug))) |
|
1231 | 1393 | return 0; |
|
Line 1232... | Line 1394... | ||
1232 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
1394 | |
1233 | &response, 2) && response[0]; |
1395 | return hotplug; |
1234 | } |
1396 | } |
Line 1235... | Line 1397... | ||
1235 | 1397 | ||
- | 1398 | static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) |
|
1236 | static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) |
1399 | { |
Line 1237... | Line 1400... | ||
1237 | { |
1400 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
1238 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
1401 | |
1239 | 1402 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, |
|
Line 1259... | Line 1422... | ||
1259 | intel_sdvo_get_analog_edid(struct drm_connector *connector) |
1422 | intel_sdvo_get_analog_edid(struct drm_connector *connector) |
1260 | { |
1423 | { |
1261 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1424 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
Line 1262... | Line 1425... | ||
1262 | 1425 | ||
- | 1426 | return drm_get_edid(connector, |
|
1263 | return drm_get_edid(connector, |
1427 | intel_gmbus_get_adapter(dev_priv, |
1264 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
1428 | dev_priv->crt_ddc_pin)); |
Line 1265... | Line 1429... | ||
1265 | } |
1429 | } |
1266 | 1430 | ||
1267 | enum drm_connector_status |
1431 | static enum drm_connector_status |
1268 | intel_sdvo_tmds_sink_detect(struct drm_connector *connector) |
1432 | intel_sdvo_tmds_sink_detect(struct drm_connector *connector) |
1269 | { |
1433 | { |
1270 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1434 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
Line 1310... | Line 1474... | ||
1310 | intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); |
1474 | intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); |
1311 | intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); |
1475 | intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); |
1312 | } |
1476 | } |
1313 | } else |
1477 | } else |
1314 | status = connector_status_disconnected; |
1478 | status = connector_status_disconnected; |
1315 | connector->display_info.raw_edid = NULL; |
- | |
1316 | kfree(edid); |
1479 | kfree(edid); |
1317 | } |
1480 | } |
Line 1318... | Line 1481... | ||
1318 | 1481 | ||
1319 | if (status == connector_status_connected) { |
1482 | if (status == connector_status_connected) { |
1320 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1483 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1321 | if (intel_sdvo_connector->force_audio) |
1484 | if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO) |
1322 | intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0; |
1485 | intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON); |
Line 1323... | Line 1486... | ||
1323 | } |
1486 | } |
1324 | 1487 | ||
Line 1348... | Line 1511... | ||
1348 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1511 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1349 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1512 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1350 | return connector_status_unknown; |
1513 | return connector_status_unknown; |
Line 1351... | Line 1514... | ||
1351 | 1514 | ||
1352 | /* add 30ms delay when the output type might be TV */ |
1515 | /* add 30ms delay when the output type might be TV */ |
1353 | if (intel_sdvo->caps.output_flags & |
- | |
1354 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) |
1516 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) |
Line 1355... | Line 1517... | ||
1355 | mdelay(30); |
1517 | msleep(30); |
1356 | 1518 | ||
Line 1357... | Line 1519... | ||
1357 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1519 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
Line 1385... | Line 1547... | ||
1385 | edid)) |
1547 | edid)) |
1386 | ret = connector_status_connected; |
1548 | ret = connector_status_connected; |
1387 | else |
1549 | else |
1388 | ret = connector_status_disconnected; |
1550 | ret = connector_status_disconnected; |
Line 1389... | Line -... | ||
1389 | - | ||
1390 | connector->display_info.raw_edid = NULL; |
1551 | |
1391 | kfree(edid); |
1552 | kfree(edid); |
1392 | } else |
1553 | } else |
1393 | ret = connector_status_connected; |
1554 | ret = connector_status_connected; |
Line 1431... | Line 1592... | ||
1431 | edid)) { |
1592 | edid)) { |
1432 | drm_mode_connector_update_edid_property(connector, edid); |
1593 | drm_mode_connector_update_edid_property(connector, edid); |
1433 | drm_add_edid_modes(connector, edid); |
1594 | drm_add_edid_modes(connector, edid); |
1434 | } |
1595 | } |
Line 1435... | Line -... | ||
1435 | - | ||
1436 | connector->display_info.raw_edid = NULL; |
1596 | |
1437 | kfree(edid); |
1597 | kfree(edid); |
1438 | } |
1598 | } |
Line 1439... | Line 1599... | ||
1439 | } |
1599 | } |
Line 1569... | Line 1729... | ||
1569 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
1729 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
1570 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
1730 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
1571 | intel_sdvo->sdvo_lvds_fixed_mode = |
1731 | intel_sdvo->sdvo_lvds_fixed_mode = |
1572 | drm_mode_duplicate(connector->dev, newmode); |
1732 | drm_mode_duplicate(connector->dev, newmode); |
Line 1573... | Line -... | ||
1573 | - | ||
1574 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, |
- | |
1575 | 0); |
- | |
1576 | 1733 | ||
1577 | intel_sdvo->is_lvds = true; |
1734 | intel_sdvo->is_lvds = true; |
1578 | break; |
1735 | break; |
1579 | } |
1736 | } |
Line 1649... | Line 1806... | ||
1649 | drm_sysfs_connector_remove(connector); |
1806 | drm_sysfs_connector_remove(connector); |
1650 | drm_connector_cleanup(connector); |
1807 | drm_connector_cleanup(connector); |
1651 | kfree(connector); |
1808 | kfree(connector); |
1652 | } |
1809 | } |
Line -... | Line 1810... | ||
- | 1810 | ||
- | 1811 | static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) |
|
- | 1812 | { |
|
- | 1813 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
|
- | 1814 | struct edid *edid; |
|
Line -... | Line 1815... | ||
- | 1815 | bool has_audio = false; |
|
- | 1816 | ||
Line -... | Line 1817... | ||
- | 1817 | if (!intel_sdvo->is_hdmi) |
|
- | 1818 | return false; |
|
- | 1819 | ||
- | 1820 | edid = intel_sdvo_get_edid(connector); |
|
Line -... | Line 1821... | ||
- | 1821 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) |
|
- | 1822 | has_audio = drm_detect_monitor_audio(edid); |
|
Line 1653... | Line 1823... | ||
1653 | 1823 | kfree(edid); |
|
1654 | 1824 | ||
1655 | 1825 | return has_audio; |
|
1656 | 1826 | } |
|
Line 1679... | Line 1849... | ||
1679 | if (i == intel_sdvo_connector->force_audio) |
1849 | if (i == intel_sdvo_connector->force_audio) |
1680 | return 0; |
1850 | return 0; |
Line 1681... | Line 1851... | ||
1681 | 1851 | ||
Line 1682... | Line 1852... | ||
1682 | intel_sdvo_connector->force_audio = i; |
1852 | intel_sdvo_connector->force_audio = i; |
1683 | 1853 | ||
1684 | if (i == 0) |
1854 | if (i == HDMI_AUDIO_AUTO) |
1685 | has_audio = intel_sdvo_detect_hdmi_audio(connector); |
1855 | has_audio = intel_sdvo_detect_hdmi_audio(connector); |
Line 1686... | Line 1856... | ||
1686 | else |
1856 | else |
1687 | has_audio = i > 0; |
1857 | has_audio = (i == HDMI_AUDIO_ON); |
Line 1688... | Line 1858... | ||
1688 | 1858 | ||
Line 1795... | Line 1965... | ||
1795 | 1965 | ||
1796 | 1966 | ||
1797 | done: |
1967 | done: |
1798 | if (intel_sdvo->base.base.crtc) { |
1968 | if (intel_sdvo->base.base.crtc) { |
1799 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
1969 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
1800 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
1970 | intel_set_mode(crtc, &crtc->mode, |
Line 1801... | Line 1971... | ||
1801 | crtc->y, crtc->fb); |
1971 | crtc->x, crtc->y, crtc->fb); |
1802 | } |
1972 | } |
1803 | 1973 | ||
Line 1804... | Line 1974... | ||
1804 | return 0; |
1974 | return 0; |
1805 | #undef CHECK_PROPERTY |
- | |
1806 | } |
1975 | #undef CHECK_PROPERTY |
1807 | - | ||
1808 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
1976 | } |
1809 | .dpms = intel_sdvo_dpms, |
1977 | |
1810 | .mode_fixup = intel_sdvo_mode_fixup, |
1978 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
Line 1811... | Line 1979... | ||
1811 | .prepare = intel_encoder_prepare, |
1979 | .mode_fixup = intel_sdvo_mode_fixup, |
1812 | .mode_set = intel_sdvo_mode_set, |
1980 | .mode_set = intel_sdvo_mode_set, |
1813 | .commit = intel_encoder_commit, |
1981 | .disable = intel_encoder_noop, |
1814 | }; |
1982 | }; |
1815 | 1983 | ||
1816 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
1984 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
1817 | .dpms = drm_helper_connector_dpms, |
1985 | .dpms = intel_sdvo_dpms, |
Line 1890... | Line 2058... | ||
1890 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
2058 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
1891 | struct intel_sdvo *sdvo, u32 reg) |
2059 | struct intel_sdvo *sdvo, u32 reg) |
1892 | { |
2060 | { |
1893 | struct sdvo_device_mapping *mapping; |
2061 | struct sdvo_device_mapping *mapping; |
Line 1894... | Line 2062... | ||
1894 | 2062 | ||
1895 | if (IS_SDVOB(reg)) |
2063 | if (sdvo->is_sdvob) |
1896 | mapping = &(dev_priv->sdvo_mappings[0]); |
2064 | mapping = &(dev_priv->sdvo_mappings[0]); |
1897 | else |
2065 | else |
Line 1898... | Line 2066... | ||
1898 | mapping = &(dev_priv->sdvo_mappings[1]); |
2066 | mapping = &(dev_priv->sdvo_mappings[1]); |
Line 1908... | Line 2076... | ||
1908 | struct intel_sdvo *sdvo, u32 reg) |
2076 | struct intel_sdvo *sdvo, u32 reg) |
1909 | { |
2077 | { |
1910 | struct sdvo_device_mapping *mapping; |
2078 | struct sdvo_device_mapping *mapping; |
1911 | u8 pin; |
2079 | u8 pin; |
Line 1912... | Line 2080... | ||
1912 | 2080 | ||
1913 | if (IS_SDVOB(reg)) |
2081 | if (sdvo->is_sdvob) |
1914 | mapping = &dev_priv->sdvo_mappings[0]; |
2082 | mapping = &dev_priv->sdvo_mappings[0]; |
1915 | else |
2083 | else |
Line 1916... | Line 2084... | ||
1916 | mapping = &dev_priv->sdvo_mappings[1]; |
2084 | mapping = &dev_priv->sdvo_mappings[1]; |
1917 | 2085 | ||
1918 | pin = GMBUS_PORT_DPB; |
2086 | pin = GMBUS_PORT_DPB; |
Line 1919... | Line 2087... | ||
1919 | if (mapping->initialized) |
2087 | if (mapping->initialized) |
1920 | pin = mapping->i2c_pin; |
2088 | pin = mapping->i2c_pin; |
1921 | 2089 | ||
1922 | if (pin < GMBUS_NUM_PORTS) { |
2090 | if (intel_gmbus_is_port_valid(pin)) { |
1923 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; |
2091 | sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin); |
1924 | intel_gmbus_set_speed(sdvo->i2c, GMBUS_RATE_1MHZ); |
2092 | intel_gmbus_set_speed(sdvo->i2c, GMBUS_RATE_1MHZ); |
1925 | intel_gmbus_force_bit(sdvo->i2c, true); |
2093 | intel_gmbus_force_bit(sdvo->i2c, true); |
1926 | } else { |
2094 | } else { |
Line 1927... | Line 2095... | ||
1927 | sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; |
2095 | sdvo->i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); |
1928 | } |
2096 | } |
1929 | } |
2097 | } |
1930 | 2098 | ||
1931 | static bool |
2099 | static bool |
Line 1932... | Line 2100... | ||
1932 | intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) |
2100 | intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) |
1933 | { |
2101 | { |
1934 | return intel_sdvo_check_supp_encode(intel_sdvo); |
2102 | return intel_sdvo_check_supp_encode(intel_sdvo); |
1935 | } |
2103 | } |
1936 | 2104 | ||
Line 1937... | Line 2105... | ||
1937 | static u8 |
2105 | static u8 |
1938 | intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) |
2106 | intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) |
1939 | { |
2107 | { |
1940 | struct drm_i915_private *dev_priv = dev->dev_private; |
2108 | struct drm_i915_private *dev_priv = dev->dev_private; |
1941 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
2109 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
1942 | 2110 | ||
Line 1963... | Line 2131... | ||
1963 | } |
2131 | } |
Line 1964... | Line 2132... | ||
1964 | 2132 | ||
1965 | /* No SDVO device info is found for another DVO port, |
2133 | /* No SDVO device info is found for another DVO port, |
1966 | * so use mapping assumption we had before BIOS parsing. |
2134 | * so use mapping assumption we had before BIOS parsing. |
1967 | */ |
2135 | */ |
1968 | if (IS_SDVOB(sdvo_reg)) |
2136 | if (sdvo->is_sdvob) |
1969 | return 0x70; |
2137 | return 0x70; |
1970 | else |
2138 | else |
1971 | return 0x72; |
2139 | return 0x72; |
Line 1981... | Line 2149... | ||
1981 | connector->base.base.connector_type); |
2149 | connector->base.base.connector_type); |
Line 1982... | Line 2150... | ||
1982 | 2150 | ||
1983 | drm_connector_helper_add(&connector->base.base, |
2151 | drm_connector_helper_add(&connector->base.base, |
Line 1984... | Line 2152... | ||
1984 | &intel_sdvo_connector_helper_funcs); |
2152 | &intel_sdvo_connector_helper_funcs); |
1985 | 2153 | ||
1986 | connector->base.base.interlace_allowed = 0; |
2154 | connector->base.base.interlace_allowed = 1; |
- | 2155 | connector->base.base.doublescan_allowed = 0; |
|
Line 1987... | Line 2156... | ||
1987 | connector->base.base.doublescan_allowed = 0; |
2156 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
1988 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
2157 | connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; |
1989 | 2158 | ||
Line 2022... | Line 2191... | ||
2022 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
2191 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
2023 | } |
2192 | } |
Line 2024... | Line 2193... | ||
2024 | 2193 | ||
2025 | intel_connector = &intel_sdvo_connector->base; |
2194 | intel_connector = &intel_sdvo_connector->base; |
2026 | connector = &intel_connector->base; |
2195 | connector = &intel_connector->base; |
- | 2196 | if (intel_sdvo_get_hotplug_support(intel_sdvo) & |
|
2027 | if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) { |
2197 | intel_sdvo_connector->output_flag) { |
2028 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2198 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
2029 | intel_sdvo->hotplug_active[0] |= 1 << device; |
2199 | intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag; |
2030 | /* Some SDVO devices have one-shot hotplug interrupts. |
2200 | /* Some SDVO devices have one-shot hotplug interrupts. |
2031 | * Ensure that they get re-enabled when an interrupt happens. |
2201 | * Ensure that they get re-enabled when an interrupt happens. |
2032 | */ |
2202 | */ |
2033 | intel_encoder->hot_plug = intel_sdvo_enable_hotplug; |
2203 | intel_encoder->hot_plug = intel_sdvo_enable_hotplug; |
2034 | intel_sdvo_enable_hotplug(intel_encoder); |
- | |
2035 | } |
2204 | intel_sdvo_enable_hotplug(intel_encoder); |
2036 | else |
2205 | } else { |
- | 2206 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
|
2037 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
2207 | } |
2038 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
2208 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
Line 2039... | Line 2209... | ||
2039 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2209 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2040 | 2210 | ||
2041 | if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { |
2211 | if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { |
2042 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2212 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2043 | intel_sdvo->is_hdmi = true; |
2213 | intel_sdvo->is_hdmi = true; |
2044 | } |
- | |
Line 2045... | Line 2214... | ||
2045 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2214 | } |
2046 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2215 | intel_sdvo->base.cloneable = true; |
2047 | 2216 | ||
Line 2072... | Line 2241... | ||
2072 | intel_sdvo->controlled_output |= type; |
2241 | intel_sdvo->controlled_output |= type; |
2073 | intel_sdvo_connector->output_flag = type; |
2242 | intel_sdvo_connector->output_flag = type; |
Line 2074... | Line 2243... | ||
2074 | 2243 | ||
2075 | intel_sdvo->is_tv = true; |
2244 | intel_sdvo->is_tv = true; |
2076 | intel_sdvo->base.needs_tv_clock = true; |
2245 | intel_sdvo->base.needs_tv_clock = true; |
Line 2077... | Line 2246... | ||
2077 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2246 | intel_sdvo->base.cloneable = false; |
Line 2078... | Line 2247... | ||
2078 | 2247 | ||
2079 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2248 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
Line 2115... | Line 2284... | ||
2115 | } else if (device == 1) { |
2284 | } else if (device == 1) { |
2116 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
2285 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
2117 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2286 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2118 | } |
2287 | } |
Line 2119... | Line 2288... | ||
2119 | 2288 | ||
2120 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
- | |
Line 2121... | Line 2289... | ||
2121 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2289 | intel_sdvo->base.cloneable = true; |
2122 | 2290 | ||
2123 | intel_sdvo_connector_init(intel_sdvo_connector, |
2291 | intel_sdvo_connector_init(intel_sdvo_connector, |
2124 | intel_sdvo); |
2292 | intel_sdvo); |
Line 2148... | Line 2316... | ||
2148 | } else if (device == 1) { |
2316 | } else if (device == 1) { |
2149 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
2317 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
2150 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2318 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2151 | } |
2319 | } |
Line 2152... | Line 2320... | ||
2152 | 2320 | ||
2153 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
2321 | /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ |
Line 2154... | Line 2322... | ||
2154 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
2322 | intel_sdvo->base.cloneable = false; |
2155 | 2323 | ||
2156 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2324 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
Line 2188... | Line 2356... | ||
2188 | 2356 | ||
2189 | if (flags & SDVO_OUTPUT_CVBS0) |
2357 | if (flags & SDVO_OUTPUT_CVBS0) |
2190 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
2358 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
Line -... | Line 2359... | ||
- | 2359 | return false; |
|
- | 2360 | ||
- | 2361 | if (flags & SDVO_OUTPUT_YPRPB0) |
|
- | 2362 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_YPRPB0)) |
|
2191 | return false; |
2363 | return false; |
2192 | 2364 | ||
2193 | if (flags & SDVO_OUTPUT_RGB0) |
2365 | if (flags & SDVO_OUTPUT_RGB0) |
Line 2194... | Line 2366... | ||
2194 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
2366 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
Line 2273... | Line 2445... | ||
2273 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ |
2445 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ |
2274 | return false; \ |
2446 | return false; \ |
2275 | intel_sdvo_connector->max_##name = data_value[0]; \ |
2447 | intel_sdvo_connector->max_##name = data_value[0]; \ |
2276 | intel_sdvo_connector->cur_##name = response; \ |
2448 | intel_sdvo_connector->cur_##name = response; \ |
2277 | intel_sdvo_connector->name = \ |
2449 | intel_sdvo_connector->name = \ |
2278 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ |
2450 | drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ |
2279 | if (!intel_sdvo_connector->name) return false; \ |
2451 | if (!intel_sdvo_connector->name) return false; \ |
2280 | intel_sdvo_connector->name->values[0] = 0; \ |
- | |
2281 | intel_sdvo_connector->name->values[1] = data_value[0]; \ |
- | |
2282 | drm_connector_attach_property(connector, \ |
2452 | drm_connector_attach_property(connector, \ |
2283 | intel_sdvo_connector->name, \ |
2453 | intel_sdvo_connector->name, \ |
2284 | intel_sdvo_connector->cur_##name); \ |
2454 | intel_sdvo_connector->cur_##name); \ |
2285 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ |
2455 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ |
2286 | data_value[0], data_value[1], response); \ |
2456 | data_value[0], data_value[1], response); \ |
Line 2310... | Line 2480... | ||
2310 | 2480 | ||
2311 | intel_sdvo_connector->max_hscan = data_value[0]; |
2481 | intel_sdvo_connector->max_hscan = data_value[0]; |
2312 | intel_sdvo_connector->left_margin = data_value[0] - response; |
2482 | intel_sdvo_connector->left_margin = data_value[0] - response; |
2313 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; |
2483 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; |
2314 | intel_sdvo_connector->left = |
2484 | intel_sdvo_connector->left = |
2315 | drm_property_create(dev, DRM_MODE_PROP_RANGE, |
- | |
2316 | "left_margin", 2); |
2485 | drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); |
2317 | if (!intel_sdvo_connector->left) |
2486 | if (!intel_sdvo_connector->left) |
Line 2318... | Line -... | ||
2318 | return false; |
- | |
2319 | - | ||
2320 | intel_sdvo_connector->left->values[0] = 0; |
2487 | return false; |
2321 | intel_sdvo_connector->left->values[1] = data_value[0]; |
2488 | |
2322 | drm_connector_attach_property(connector, |
2489 | drm_connector_attach_property(connector, |
Line 2323... | Line 2490... | ||
2323 | intel_sdvo_connector->left, |
2490 | intel_sdvo_connector->left, |
2324 | intel_sdvo_connector->left_margin); |
2491 | intel_sdvo_connector->left_margin); |
2325 | - | ||
2326 | intel_sdvo_connector->right = |
2492 | |
2327 | drm_property_create(dev, DRM_MODE_PROP_RANGE, |
2493 | intel_sdvo_connector->right = |
Line 2328... | Line -... | ||
2328 | "right_margin", 2); |
- | |
2329 | if (!intel_sdvo_connector->right) |
- | |
2330 | return false; |
2494 | drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); |
2331 | 2495 | if (!intel_sdvo_connector->right) |
|
2332 | intel_sdvo_connector->right->values[0] = 0; |
2496 | return false; |
2333 | intel_sdvo_connector->right->values[1] = data_value[0]; |
2497 | |
2334 | drm_connector_attach_property(connector, |
2498 | drm_connector_attach_property(connector, |
Line 2352... | Line 2516... | ||
2352 | 2516 | ||
2353 | intel_sdvo_connector->max_vscan = data_value[0]; |
2517 | intel_sdvo_connector->max_vscan = data_value[0]; |
2354 | intel_sdvo_connector->top_margin = data_value[0] - response; |
2518 | intel_sdvo_connector->top_margin = data_value[0] - response; |
2355 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; |
2519 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; |
2356 | intel_sdvo_connector->top = |
2520 | intel_sdvo_connector->top = |
2357 | drm_property_create(dev, DRM_MODE_PROP_RANGE, |
2521 | drm_property_create_range(dev, 0, |
2358 | "top_margin", 2); |
2522 | "top_margin", 0, data_value[0]); |
2359 | if (!intel_sdvo_connector->top) |
2523 | if (!intel_sdvo_connector->top) |
Line 2360... | Line -... | ||
2360 | return false; |
- | |
2361 | - | ||
2362 | intel_sdvo_connector->top->values[0] = 0; |
2524 | return false; |
2363 | intel_sdvo_connector->top->values[1] = data_value[0]; |
2525 | |
2364 | drm_connector_attach_property(connector, |
2526 | drm_connector_attach_property(connector, |
Line 2365... | Line 2527... | ||
2365 | intel_sdvo_connector->top, |
2527 | intel_sdvo_connector->top, |
2366 | intel_sdvo_connector->top_margin); |
2528 | intel_sdvo_connector->top_margin); |
2367 | 2529 | ||
2368 | intel_sdvo_connector->bottom = |
2530 | intel_sdvo_connector->bottom = |
2369 | drm_property_create(dev, DRM_MODE_PROP_RANGE, |
2531 | drm_property_create_range(dev, 0, |
Line 2370... | Line -... | ||
2370 | "bottom_margin", 2); |
- | |
2371 | if (!intel_sdvo_connector->bottom) |
- | |
2372 | return false; |
2532 | "bottom_margin", 0, data_value[0]); |
2373 | 2533 | if (!intel_sdvo_connector->bottom) |
|
2374 | intel_sdvo_connector->bottom->values[0] = 0; |
2534 | return false; |
2375 | intel_sdvo_connector->bottom->values[1] = data_value[0]; |
2535 | |
2376 | drm_connector_attach_property(connector, |
2536 | drm_connector_attach_property(connector, |
Line 2399... | Line 2559... | ||
2399 | return false; |
2559 | return false; |
Line 2400... | Line 2560... | ||
2400 | 2560 | ||
2401 | intel_sdvo_connector->max_dot_crawl = 1; |
2561 | intel_sdvo_connector->max_dot_crawl = 1; |
2402 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2562 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2403 | intel_sdvo_connector->dot_crawl = |
2563 | intel_sdvo_connector->dot_crawl = |
2404 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); |
2564 | drm_property_create_range(dev, 0, "dot_crawl", 0, 1); |
2405 | if (!intel_sdvo_connector->dot_crawl) |
2565 | if (!intel_sdvo_connector->dot_crawl) |
Line 2406... | Line -... | ||
2406 | return false; |
- | |
2407 | - | ||
2408 | intel_sdvo_connector->dot_crawl->values[0] = 0; |
2566 | return false; |
2409 | intel_sdvo_connector->dot_crawl->values[1] = 1; |
2567 | |
2410 | drm_connector_attach_property(connector, |
2568 | drm_connector_attach_property(connector, |
2411 | intel_sdvo_connector->dot_crawl, |
2569 | intel_sdvo_connector->dot_crawl, |
2412 | intel_sdvo_connector->cur_dot_crawl); |
2570 | intel_sdvo_connector->cur_dot_crawl); |
Line 2483... | Line 2641... | ||
2483 | 2641 | ||
2484 | static bool |
2642 | static bool |
2485 | intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, |
2643 | intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, |
2486 | struct drm_device *dev) |
2644 | struct drm_device *dev) |
2487 | { |
2645 | { |
2488 | // sdvo->ddc.owner = THIS_MODULE; |
2646 | sdvo->ddc.owner = THIS_MODULE; |
2489 | sdvo->ddc.class = I2C_CLASS_DDC; |
2647 | sdvo->ddc.class = I2C_CLASS_DDC; |
2490 | snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); |
2648 | snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); |
2491 | sdvo->ddc.dev.parent = &dev->pdev->dev; |
2649 | sdvo->ddc.dev.parent = &dev->pdev->dev; |
2492 | sdvo->ddc.algo_data = sdvo; |
2650 | sdvo->ddc.algo_data = sdvo; |
Line 2493... | Line 2651... | ||
2493 | sdvo->ddc.algo = &intel_sdvo_ddc_proxy; |
2651 | sdvo->ddc.algo = &intel_sdvo_ddc_proxy; |
2494 | 2652 | ||
Line 2495... | Line 2653... | ||
2495 | return 1; //i2c_add_adapter(&sdvo->ddc) == 0; |
2653 | return 1; //i2c_add_adapter(&sdvo->ddc) == 0; |
2496 | } |
2654 | } |
2497 | 2655 | ||
2498 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2656 | bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) |
2499 | { |
2657 | { |
- | 2658 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
2500 | struct drm_i915_private *dev_priv = dev->dev_private; |
2659 | struct intel_encoder *intel_encoder; |
Line 2501... | Line 2660... | ||
2501 | struct intel_encoder *intel_encoder; |
2660 | struct intel_sdvo *intel_sdvo; |
2502 | struct intel_sdvo *intel_sdvo; |
2661 | u32 hotplug_mask; |
2503 | int i; |
2662 | int i; |
Line 2504... | Line 2663... | ||
2504 | 2663 | ||
- | 2664 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
|
2505 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
2665 | if (!intel_sdvo) |
2506 | if (!intel_sdvo) |
2666 | return false; |
2507 | return false; |
2667 | |
2508 | 2668 | intel_sdvo->sdvo_reg = sdvo_reg; |
|
2509 | intel_sdvo->sdvo_reg = sdvo_reg; |
2669 | intel_sdvo->is_sdvob = is_sdvob; |
2510 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1; |
2670 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1; |
Line 2522... | Line 2682... | ||
2522 | /* Read the regs to test if we can talk to the device */ |
2682 | /* Read the regs to test if we can talk to the device */ |
2523 | for (i = 0; i < 0x40; i++) { |
2683 | for (i = 0; i < 0x40; i++) { |
2524 | u8 byte; |
2684 | u8 byte; |
Line 2525... | Line 2685... | ||
2525 | 2685 | ||
2526 | if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) { |
2686 | if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) { |
2527 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2687 | DRM_DEBUG_KMS("No SDVO device found on %s\n", |
2528 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2688 | SDVO_NAME(intel_sdvo)); |
2529 | goto err; |
2689 | goto err; |
2530 | } |
2690 | } |
Line -... | Line 2691... | ||
- | 2691 | } |
|
- | 2692 | ||
- | 2693 | hotplug_mask = 0; |
|
- | 2694 | if (IS_G4X(dev)) { |
|
2531 | } |
2695 | hotplug_mask = intel_sdvo->is_sdvob ? |
- | 2696 | SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; |
|
2532 | 2697 | } else if (IS_GEN4(dev)) { |
|
2533 | if (IS_SDVOB(sdvo_reg)) |
2698 | hotplug_mask = intel_sdvo->is_sdvob ? |
- | 2699 | SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; |
|
2534 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2700 | } else { |
- | 2701 | hotplug_mask = intel_sdvo->is_sdvob ? |
|
Line 2535... | Line 2702... | ||
2535 | else |
2702 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; |
Line -... | Line 2703... | ||
- | 2703 | } |
|
- | 2704 | ||
- | 2705 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
|
- | 2706 | ||
2536 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2707 | intel_encoder->disable = intel_disable_sdvo; |
2537 | 2708 | intel_encoder->enable = intel_enable_sdvo; |
|
2538 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2709 | intel_encoder->get_hw_state = intel_sdvo_get_hw_state; |
Line 2539... | Line -... | ||
2539 | - | ||
2540 | /* In default case sdvo lvds is false */ |
- | |
2541 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
- | |
2542 | goto err; |
- | |
2543 | - | ||
2544 | /* Set up hotplug command - note paranoia about contents of reply. |
- | |
2545 | * We assume that the hardware is in a sane state, and only touch |
- | |
2546 | * the bits we think we understand. |
- | |
2547 | */ |
2710 | |
2548 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, |
2711 | /* In default case sdvo lvds is false */ |
2549 | &intel_sdvo->hotplug_active, 2); |
2712 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2550 | intel_sdvo->hotplug_active[0] &= ~0x3; |
2713 | goto err; |
2551 | 2714 | ||
2552 | if (intel_sdvo_output_setup(intel_sdvo, |
2715 | if (intel_sdvo_output_setup(intel_sdvo, |
Line -... | Line 2716... | ||
- | 2716 | intel_sdvo->caps.output_flags) != true) { |
|
- | 2717 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
|
- | 2718 | SDVO_NAME(intel_sdvo)); |
|
- | 2719 | goto err; |
|
- | 2720 | } |
|
- | 2721 | ||
2553 | intel_sdvo->caps.output_flags) != true) { |
2722 | /* Only enable the hotplug irq if we need it, to work around noisy |
Line 2554... | Line 2723... | ||
2554 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2723 | * hotplug lines. |
2555 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2724 | */ |
2556 | goto err; |
2725 | if (intel_sdvo->hotplug_active) |