aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2018-09-17 11:15:03 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2018-09-18 14:05:06 -0400
commitaa2b88074a569ac6c626c36f31b566158a4939ff (patch)
treea13228c7c01bea30824a92a98b78a04a8cbc7e5e
parent1ee516ffa73107f96c1355cce5880b6c38d22d51 (diff)
drm/i915/sdvo: Fix multi function encoder stuff
SDVO encoders can have multiple different types of outputs hanging off them. Currently the code tries to muck around with various is_foo flags in the encoder to figure out which type its driving. That doesn't work with atomic and other stuff, so let's nuke those flags and just look at which type of connector we're actually dealing with. The is_hdmi we'll need as that's not discoverable via the output flags, but we'll just move it under the connector. We'll also move the sdvo fixed mode handling out from the .get_modes() hook into the sdvo lvds init function so that we can bail out properly if there is no fixed mode to be found. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180917151504.8754-1-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c101
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 812fe7b06f87..701372e512a8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -99,32 +99,13 @@ struct intel_sdvo {
99 */ 99 */
100 uint16_t hotplug_active; 100 uint16_t hotplug_active;
101 101
102 /**
103 * This is set if we're going to treat the device as TV-out.
104 *
105 * While we have these nice friendly flags for output types that ought
106 * to decide this for us, the S-Video output on our HDMI+S-Video card
107 * shows up as RGB1 (VGA).
108 */
109 bool is_tv;
110
111 enum port port; 102 enum port port;
112 103
113 /**
114 * This is set if we treat the device as HDMI, instead of DVI.
115 */
116 bool is_hdmi;
117 bool has_hdmi_monitor; 104 bool has_hdmi_monitor;
118 bool has_hdmi_audio; 105 bool has_hdmi_audio;
119 bool rgb_quant_range_selectable; 106 bool rgb_quant_range_selectable;
120 107
121 /** 108 /**
122 * This is set if we detect output of sdvo device as LVDS and
123 * have a valid fixed mode to use with the panel.
124 */
125 bool is_lvds;
126
127 /**
128 * This is sdvo fixed pannel mode pointer 109 * This is sdvo fixed pannel mode pointer
129 */ 110 */
130 struct drm_display_mode *sdvo_lvds_fixed_mode; 111 struct drm_display_mode *sdvo_lvds_fixed_mode;
@@ -172,6 +153,11 @@ struct intel_sdvo_connector {
172 153
173 /* this is to get the range of margin.*/ 154 /* this is to get the range of margin.*/
174 u32 max_hscan, max_vscan; 155 u32 max_hscan, max_vscan;
156
157 /**
158 * This is set if we treat the device as HDMI, instead of DVI.
159 */
160 bool is_hdmi;
175}; 161};
176 162
177struct intel_sdvo_connector_state { 163struct intel_sdvo_connector_state {
@@ -766,6 +752,7 @@ static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
766 752
767static bool 753static bool
768intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, 754intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
755 struct intel_sdvo_connector *intel_sdvo_connector,
769 uint16_t clock, 756 uint16_t clock,
770 uint16_t width, 757 uint16_t width,
771 uint16_t height) 758 uint16_t height)
@@ -778,7 +765,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
778 args.height = height; 765 args.height = height;
779 args.interlace = 0; 766 args.interlace = 0;
780 767
781 if (intel_sdvo->is_lvds && 768 if (IS_LVDS(intel_sdvo_connector) &&
782 (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || 769 (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
783 intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) 770 intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
784 args.scaled = 1; 771 args.scaled = 1;
@@ -1067,6 +1054,7 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
1067 */ 1054 */
1068static bool 1055static bool
1069intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, 1056intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
1057 struct intel_sdvo_connector *intel_sdvo_connector,
1070 const struct drm_display_mode *mode, 1058 const struct drm_display_mode *mode,
1071 struct drm_display_mode *adjusted_mode) 1059 struct drm_display_mode *adjusted_mode)
1072{ 1060{
@@ -1077,6 +1065,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
1077 return false; 1065 return false;
1078 1066
1079 if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, 1067 if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
1068 intel_sdvo_connector,
1080 mode->clock / 10, 1069 mode->clock / 10,
1081 mode->hdisplay, 1070 mode->hdisplay,
1082 mode->vdisplay)) 1071 mode->vdisplay))
@@ -1127,6 +1116,8 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1127 struct intel_sdvo *intel_sdvo = to_sdvo(encoder); 1116 struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
1128 struct intel_sdvo_connector_state *intel_sdvo_state = 1117 struct intel_sdvo_connector_state *intel_sdvo_state =
1129 to_intel_sdvo_connector_state(conn_state); 1118 to_intel_sdvo_connector_state(conn_state);
1119 struct intel_sdvo_connector *intel_sdvo_connector =
1120 to_intel_sdvo_connector(conn_state->connector);
1130 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 1121 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
1131 struct drm_display_mode *mode = &pipe_config->base.mode; 1122 struct drm_display_mode *mode = &pipe_config->base.mode;
1132 1123
@@ -1142,20 +1133,22 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1142 * timings, even though this isn't really the right place in 1133 * timings, even though this isn't really the right place in
1143 * the sequence to do it. Oh well. 1134 * the sequence to do it. Oh well.
1144 */ 1135 */
1145 if (intel_sdvo->is_tv) { 1136 if (IS_TV(intel_sdvo_connector)) {
1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) 1137 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
1147 return false; 1138 return false;
1148 1139
1149 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1140 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1141 intel_sdvo_connector,
1150 mode, 1142 mode,
1151 adjusted_mode); 1143 adjusted_mode);
1152 pipe_config->sdvo_tv_clock = true; 1144 pipe_config->sdvo_tv_clock = true;
1153 } else if (intel_sdvo->is_lvds) { 1145 } else if (IS_LVDS(intel_sdvo_connector)) {
1154 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, 1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1155 intel_sdvo->sdvo_lvds_fixed_mode)) 1147 intel_sdvo->sdvo_lvds_fixed_mode))
1156 return false; 1148 return false;
1157 1149
1158 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1150 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1151 intel_sdvo_connector,
1159 mode, 1152 mode,
1160 adjusted_mode); 1153 adjusted_mode);
1161 } 1154 }
@@ -1194,11 +1187,11 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1194 } 1187 }
1195 1188
1196 /* Clock computation needs to happen after pixel multiplier. */ 1189 /* Clock computation needs to happen after pixel multiplier. */
1197 if (intel_sdvo->is_tv) 1190 if (IS_TV(intel_sdvo_connector))
1198 i9xx_adjust_sdvo_tv_clock(pipe_config); 1191 i9xx_adjust_sdvo_tv_clock(pipe_config);
1199 1192
1200 /* Set user selected PAR to incoming mode's member */ 1193 /* Set user selected PAR to incoming mode's member */
1201 if (intel_sdvo->is_hdmi) 1194 if (intel_sdvo_connector->is_hdmi)
1202 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio; 1195 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio;
1203 1196
1204 return true; 1197 return true;
@@ -1275,6 +1268,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1275 const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; 1268 const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
1276 const struct intel_sdvo_connector_state *sdvo_state = 1269 const struct intel_sdvo_connector_state *sdvo_state =
1277 to_intel_sdvo_connector_state(conn_state); 1270 to_intel_sdvo_connector_state(conn_state);
1271 const struct intel_sdvo_connector *intel_sdvo_connector =
1272 to_intel_sdvo_connector(conn_state->connector);
1278 const struct drm_display_mode *mode = &crtc_state->base.mode; 1273 const struct drm_display_mode *mode = &crtc_state->base.mode;
1279 struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); 1274 struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
1280 u32 sdvox; 1275 u32 sdvox;
@@ -1304,7 +1299,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1304 return; 1299 return;
1305 1300
1306 /* lvds has a special fixed output timing. */ 1301 /* lvds has a special fixed output timing. */
1307 if (intel_sdvo->is_lvds) 1302 if (IS_LVDS(intel_sdvo_connector))
1308 intel_sdvo_get_dtd_from_mode(&output_dtd, 1303 intel_sdvo_get_dtd_from_mode(&output_dtd,
1309 intel_sdvo->sdvo_lvds_fixed_mode); 1304 intel_sdvo->sdvo_lvds_fixed_mode);
1310 else 1305 else
@@ -1325,13 +1320,13 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1325 } else 1320 } else
1326 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); 1321 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
1327 1322
1328 if (intel_sdvo->is_tv && 1323 if (IS_TV(intel_sdvo_connector) &&
1329 !intel_sdvo_set_tv_format(intel_sdvo, conn_state)) 1324 !intel_sdvo_set_tv_format(intel_sdvo, conn_state))
1330 return; 1325 return;
1331 1326
1332 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); 1327 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
1333 1328
1334 if (intel_sdvo->is_tv || intel_sdvo->is_lvds) 1329 if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector))
1335 input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; 1330 input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
1336 if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) 1331 if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
1337 DRM_INFO("Setting input timings on %s failed\n", 1332 DRM_INFO("Setting input timings on %s failed\n",
@@ -1630,6 +1625,8 @@ intel_sdvo_mode_valid(struct drm_connector *connector,
1630 struct drm_display_mode *mode) 1625 struct drm_display_mode *mode)
1631{ 1626{
1632 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1627 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1628 struct intel_sdvo_connector *intel_sdvo_connector =
1629 to_intel_sdvo_connector(connector);
1633 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; 1630 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
1634 1631
1635 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 1632 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -1644,7 +1641,7 @@ intel_sdvo_mode_valid(struct drm_connector *connector,
1644 if (mode->clock > max_dotclk) 1641 if (mode->clock > max_dotclk)
1645 return MODE_CLOCK_HIGH; 1642 return MODE_CLOCK_HIGH;
1646 1643
1647 if (intel_sdvo->is_lvds) { 1644 if (IS_LVDS(intel_sdvo_connector)) {
1648 if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) 1645 if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
1649 return MODE_PANEL; 1646 return MODE_PANEL;
1650 1647
@@ -1759,6 +1756,8 @@ static enum drm_connector_status
1759intel_sdvo_tmds_sink_detect(struct drm_connector *connector) 1756intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1760{ 1757{
1761 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1758 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1759 struct intel_sdvo_connector *intel_sdvo_connector =
1760 to_intel_sdvo_connector(connector);
1762 enum drm_connector_status status; 1761 enum drm_connector_status status;
1763 struct edid *edid; 1762 struct edid *edid;
1764 1763
@@ -1797,7 +1796,7 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1797 /* DDC bus is shared, match EDID to connector type */ 1796 /* DDC bus is shared, match EDID to connector type */
1798 if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1797 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
1799 status = connector_status_connected; 1798 status = connector_status_connected;
1800 if (intel_sdvo->is_hdmi) { 1799 if (intel_sdvo_connector->is_hdmi) {
1801 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1800 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1802 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1801 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1803 intel_sdvo->rgb_quant_range_selectable = 1802 intel_sdvo->rgb_quant_range_selectable =
@@ -1875,17 +1874,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1875 ret = connector_status_connected; 1874 ret = connector_status_connected;
1876 } 1875 }
1877 1876
1878 /* May update encoder flag for like clock for SDVO TV, etc.*/
1879 if (ret == connector_status_connected) {
1880 intel_sdvo->is_tv = false;
1881 intel_sdvo->is_lvds = false;
1882
1883 if (response & SDVO_TV_MASK)
1884 intel_sdvo->is_tv = true;
1885 if (response & SDVO_LVDS_MASK)
1886 intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
1887 }
1888
1889 return ret; 1877 return ret;
1890} 1878}
1891 1879
@@ -2054,16 +2042,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
2054 * arranged in priority order. 2042 * arranged in priority order.
2055 */ 2043 */
2056 intel_ddc_get_modes(connector, &intel_sdvo->ddc); 2044 intel_ddc_get_modes(connector, &intel_sdvo->ddc);
2057
2058 list_for_each_entry(newmode, &connector->probed_modes, head) {
2059 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
2060 intel_sdvo->sdvo_lvds_fixed_mode =
2061 drm_mode_duplicate(connector->dev, newmode);
2062
2063 intel_sdvo->is_lvds = true;
2064 break;
2065 }
2066 }
2067} 2045}
2068 2046
2069static int intel_sdvo_get_modes(struct drm_connector *connector) 2047static int intel_sdvo_get_modes(struct drm_connector *connector)
@@ -2555,7 +2533,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2555 if (INTEL_GEN(dev_priv) >= 4 && 2533 if (INTEL_GEN(dev_priv) >= 4 &&
2556 intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { 2534 intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
2557 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; 2535 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
2558 intel_sdvo->is_hdmi = true; 2536 intel_sdvo_connector->is_hdmi = true;
2559 } 2537 }
2560 2538
2561 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { 2539 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
@@ -2563,7 +2541,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2563 return false; 2541 return false;
2564 } 2542 }
2565 2543
2566 if (intel_sdvo->is_hdmi) 2544 if (intel_sdvo_connector->is_hdmi)
2567 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector); 2545 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
2568 2546
2569 return true; 2547 return true;
@@ -2591,8 +2569,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
2591 intel_sdvo->controlled_output |= type; 2569 intel_sdvo->controlled_output |= type;
2592 intel_sdvo_connector->output_flag = type; 2570 intel_sdvo_connector->output_flag = type;
2593 2571
2594 intel_sdvo->is_tv = true;
2595
2596 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { 2572 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2597 kfree(intel_sdvo_connector); 2573 kfree(intel_sdvo_connector);
2598 return false; 2574 return false;
@@ -2654,6 +2630,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2654 struct drm_connector *connector; 2630 struct drm_connector *connector;
2655 struct intel_connector *intel_connector; 2631 struct intel_connector *intel_connector;
2656 struct intel_sdvo_connector *intel_sdvo_connector; 2632 struct intel_sdvo_connector *intel_sdvo_connector;
2633 struct drm_display_mode *mode;
2657 2634
2658 DRM_DEBUG_KMS("initialising LVDS device %d\n", device); 2635 DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
2659 2636
@@ -2682,6 +2659,19 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2682 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) 2659 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
2683 goto err; 2660 goto err;
2684 2661
2662 intel_sdvo_get_lvds_modes(connector);
2663
2664 list_for_each_entry(mode, &connector->probed_modes, head) {
2665 if (mode->type & DRM_MODE_TYPE_PREFERRED) {
2666 intel_sdvo->sdvo_lvds_fixed_mode =
2667 drm_mode_duplicate(connector->dev, mode);
2668 break;
2669 }
2670 }
2671
2672 if (!intel_sdvo->sdvo_lvds_fixed_mode)
2673 goto err;
2674
2685 return true; 2675 return true;
2686 2676
2687err: 2677err:
@@ -2692,9 +2682,6 @@ err:
2692static bool 2682static bool
2693intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) 2683intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
2694{ 2684{
2695 intel_sdvo->is_tv = false;
2696 intel_sdvo->is_lvds = false;
2697
2698 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ 2685 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
2699 2686
2700 if (flags & SDVO_OUTPUT_TMDS0) 2687 if (flags & SDVO_OUTPUT_TMDS0)