diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 109 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 1 |
8 files changed, 119 insertions, 13 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a768871734..8fab7890a363 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, | |||
2294 | } | 2294 | } |
2295 | } | 2295 | } |
2296 | 2296 | ||
2297 | if (connector->funcs->set_property) | 2297 | /* Do DPMS ourselves */ |
2298 | if (property == connector->dev->mode_config.dpms_property) { | ||
2299 | if (connector->funcs->dpms) | ||
2300 | (*connector->funcs->dpms)(connector, (int) out_resp->value); | ||
2301 | ret = 0; | ||
2302 | } else if (connector->funcs->set_property) | ||
2298 | ret = connector->funcs->set_property(connector, property, out_resp->value); | 2303 | ret = connector->funcs->set_property(connector, property, out_resp->value); |
2299 | 2304 | ||
2300 | /* store the property value if succesful */ | 2305 | /* store the property value if succesful */ |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 45890447feec..a6f73f1e99d9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -199,6 +199,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | /** | 201 | /** |
202 | * drm_helper_encoder_in_use - check if a given encoder is in use | ||
203 | * @encoder: encoder to check | ||
204 | * | ||
205 | * LOCKING: | ||
206 | * Caller must hold mode config lock. | ||
207 | * | ||
208 | * Walk @encoders's DRM device's mode_config and see if it's in use. | ||
209 | * | ||
210 | * RETURNS: | ||
211 | * True if @encoder is part of the mode_config, false otherwise. | ||
212 | */ | ||
213 | bool drm_helper_encoder_in_use(struct drm_encoder *encoder) | ||
214 | { | ||
215 | struct drm_connector *connector; | ||
216 | struct drm_device *dev = encoder->dev; | ||
217 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
218 | if (connector->encoder == encoder) | ||
219 | return true; | ||
220 | return false; | ||
221 | } | ||
222 | EXPORT_SYMBOL(drm_helper_encoder_in_use); | ||
223 | |||
224 | /** | ||
202 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config | 225 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config |
203 | * @crtc: CRTC to check | 226 | * @crtc: CRTC to check |
204 | * | 227 | * |
@@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) | |||
216 | struct drm_device *dev = crtc->dev; | 239 | struct drm_device *dev = crtc->dev; |
217 | /* FIXME: Locking around list access? */ | 240 | /* FIXME: Locking around list access? */ |
218 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | 241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) |
219 | if (encoder->crtc == crtc) | 242 | if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) |
220 | return true; | 243 | return true; |
221 | return false; | 244 | return false; |
222 | } | 245 | } |
@@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
240 | 263 | ||
241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 264 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
242 | encoder_funcs = encoder->helper_private; | 265 | encoder_funcs = encoder->helper_private; |
243 | if (!encoder->crtc) | 266 | if (!drm_helper_encoder_in_use(encoder)) |
244 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | 267 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); |
245 | } | 268 | } |
246 | 269 | ||
@@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
935 | } | 958 | } |
936 | EXPORT_SYMBOL(drm_helper_initial_config); | 959 | EXPORT_SYMBOL(drm_helper_initial_config); |
937 | 960 | ||
961 | static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) | ||
962 | { | ||
963 | int dpms = DRM_MODE_DPMS_OFF; | ||
964 | struct drm_connector *connector; | ||
965 | struct drm_device *dev = encoder->dev; | ||
966 | |||
967 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
968 | if (connector->encoder == encoder) | ||
969 | if (connector->dpms < dpms) | ||
970 | dpms = connector->dpms; | ||
971 | return dpms; | ||
972 | } | ||
973 | |||
974 | static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) | ||
975 | { | ||
976 | int dpms = DRM_MODE_DPMS_OFF; | ||
977 | struct drm_connector *connector; | ||
978 | struct drm_device *dev = crtc->dev; | ||
979 | |||
980 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
981 | if (connector->encoder && connector->encoder->crtc == crtc) | ||
982 | if (connector->dpms < dpms) | ||
983 | dpms = connector->dpms; | ||
984 | return dpms; | ||
985 | } | ||
986 | |||
987 | /** | ||
988 | * drm_helper_connector_dpms | ||
989 | * @connector affected connector | ||
990 | * @mode DPMS mode | ||
991 | * | ||
992 | * Calls the low-level connector DPMS function, then | ||
993 | * calls appropriate encoder and crtc DPMS functions as well | ||
994 | */ | ||
995 | void drm_helper_connector_dpms(struct drm_connector *connector, int mode) | ||
996 | { | ||
997 | struct drm_encoder *encoder = connector->encoder; | ||
998 | struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; | ||
999 | int old_dpms; | ||
1000 | |||
1001 | if (mode == connector->dpms) | ||
1002 | return; | ||
1003 | |||
1004 | old_dpms = connector->dpms; | ||
1005 | connector->dpms = mode; | ||
1006 | |||
1007 | /* from off to on, do crtc then encoder */ | ||
1008 | if (mode < old_dpms) { | ||
1009 | if (crtc) { | ||
1010 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1011 | if (crtc_funcs->dpms) | ||
1012 | (*crtc_funcs->dpms) (crtc, | ||
1013 | drm_helper_choose_crtc_dpms(crtc)); | ||
1014 | } | ||
1015 | if (encoder) { | ||
1016 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1017 | if (encoder_funcs->dpms) | ||
1018 | (*encoder_funcs->dpms) (encoder, | ||
1019 | drm_helper_choose_encoder_dpms(encoder)); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | /* from on to off, do encoder then crtc */ | ||
1024 | if (mode > old_dpms) { | ||
1025 | if (encoder) { | ||
1026 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1027 | if (encoder_funcs->dpms) | ||
1028 | (*encoder_funcs->dpms) (encoder, | ||
1029 | drm_helper_choose_encoder_dpms(encoder)); | ||
1030 | } | ||
1031 | if (crtc) { | ||
1032 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1033 | if (crtc_funcs->dpms) | ||
1034 | (*crtc_funcs->dpms) (crtc, | ||
1035 | drm_helper_choose_crtc_dpms(crtc)); | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | return; | ||
1040 | } | ||
1041 | EXPORT_SYMBOL(drm_helper_connector_dpms); | ||
1042 | |||
938 | /** | 1043 | /** |
939 | * drm_hotplug_stage_two | 1044 | * drm_hotplug_stage_two |
940 | * @dev DRM device | 1045 | * @dev DRM device |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 640f5158effc..79acc4f4c1f8 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -381,11 +381,6 @@ static int intel_crt_set_property(struct drm_connector *connector, | |||
381 | struct drm_property *property, | 381 | struct drm_property *property, |
382 | uint64_t value) | 382 | uint64_t value) |
383 | { | 383 | { |
384 | struct drm_device *dev = connector->dev; | ||
385 | |||
386 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
387 | intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
388 | |||
389 | return 0; | 384 | return 0; |
390 | } | 385 | } |
391 | 386 | ||
@@ -402,6 +397,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { | |||
402 | }; | 397 | }; |
403 | 398 | ||
404 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 399 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
400 | .dpms = drm_helper_connector_dpms, | ||
405 | .detect = intel_crt_detect, | 401 | .detect = intel_crt_detect, |
406 | .fill_modes = drm_helper_probe_single_connector_modes, | 402 | .fill_modes = drm_helper_probe_single_connector_modes, |
407 | .destroy = intel_crt_destroy, | 403 | .destroy = intel_crt_destroy, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 8b8d6e65cd3f..1ee3007d6ec0 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -316,6 +316,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | |||
316 | }; | 316 | }; |
317 | 317 | ||
318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
319 | .dpms = drm_helper_connector_dpms, | ||
319 | .save = intel_dvo_save, | 320 | .save = intel_dvo_save, |
320 | .restore = intel_dvo_restore, | 321 | .restore = intel_dvo_restore, |
321 | .detect = intel_dvo_detect, | 322 | .detect = intel_dvo_detect, |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d0983bb93a18..7d6bdd705326 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -219,6 +219,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | |||
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
222 | .dpms = drm_helper_connector_dpms, | ||
222 | .save = intel_hdmi_save, | 223 | .save = intel_hdmi_save, |
223 | .restore = intel_hdmi_restore, | 224 | .restore = intel_hdmi_restore, |
224 | .detect = intel_hdmi_detect, | 225 | .detect = intel_hdmi_detect, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 53731f0ffcb5..c92a64ac8549 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -343,11 +343,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
343 | struct drm_property *property, | 343 | struct drm_property *property, |
344 | uint64_t value) | 344 | uint64_t value) |
345 | { | 345 | { |
346 | struct drm_device *dev = connector->dev; | ||
347 | |||
348 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
349 | intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
350 | |||
351 | return 0; | 346 | return 0; |
352 | } | 347 | } |
353 | 348 | ||
@@ -366,6 +361,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs | |||
366 | }; | 361 | }; |
367 | 362 | ||
368 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 363 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
364 | .dpms = drm_helper_connector_dpms, | ||
369 | .save = intel_lvds_save, | 365 | .save = intel_lvds_save, |
370 | .restore = intel_lvds_restore, | 366 | .restore = intel_lvds_restore, |
371 | .detect = intel_lvds_detect, | 367 | .detect = intel_lvds_detect, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f3ef6bfd8ffc..3093b4d4a4dd 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1616,6 +1616,7 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | |||
1616 | }; | 1616 | }; |
1617 | 1617 | ||
1618 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 1618 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
1619 | .dpms = drm_helper_connector_dpms, | ||
1619 | .save = intel_sdvo_save, | 1620 | .save = intel_sdvo_save, |
1620 | .restore = intel_sdvo_restore, | 1621 | .restore = intel_sdvo_restore, |
1621 | .detect = intel_sdvo_detect, | 1622 | .detect = intel_sdvo_detect, |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d2c32983242d..98ac0546b7bd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1626,6 +1626,7 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { | |||
1626 | }; | 1626 | }; |
1627 | 1627 | ||
1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
1629 | .dpms = drm_helper_connector_dpms, | ||
1629 | .save = intel_tv_save, | 1630 | .save = intel_tv_save, |
1630 | .restore = intel_tv_restore, | 1631 | .restore = intel_tv_restore, |
1631 | .detect = intel_tv_detect, | 1632 | .detect = intel_tv_detect, |