Commit a3a0544b authored by Dave Airlie's avatar Dave Airlie Committed by Dave Airlie

drm/kms: add explicit encoder disable function and detach harder.

For shared tv-out and VGA encoders, we really need to know if
the encoder is just being switched off temporarily in blanking
or if we are really disabling it hard.

Also we need to try harder to disconnect encoders from unused
connectors so we can share more efficently.

(shared encoders stuff is coming in radeon tv-out support)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent ed017d9f
...@@ -260,14 +260,28 @@ EXPORT_SYMBOL(drm_helper_crtc_in_use); ...@@ -260,14 +260,28 @@ EXPORT_SYMBOL(drm_helper_crtc_in_use);
void drm_helper_disable_unused_functions(struct drm_device *dev) void drm_helper_disable_unused_functions(struct drm_device *dev)
{ {
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_connector *connector;
struct drm_encoder_helper_funcs *encoder_funcs; struct drm_encoder_helper_funcs *encoder_funcs;
struct drm_crtc *crtc; struct drm_crtc *crtc;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
continue;
if (connector->status == connector_status_disconnected)
connector->encoder = NULL;
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder_funcs = encoder->helper_private; encoder_funcs = encoder->helper_private;
if (!drm_helper_encoder_in_use(encoder)) if (!drm_helper_encoder_in_use(encoder)) {
if (encoder_funcs->disable)
(*encoder_funcs->disable)(encoder);
else
(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
} }
/* disconnector encoder from any connector */
encoder->crtc = NULL;
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
...@@ -411,7 +425,7 @@ static int drm_pick_crtcs(struct drm_device *dev, ...@@ -411,7 +425,7 @@ static int drm_pick_crtcs(struct drm_device *dev,
c = 0; c = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if ((connector->encoder->possible_crtcs & (1 << c)) == 0) { if ((encoder->possible_crtcs & (1 << c)) == 0) {
c++; c++;
continue; continue;
} }
...@@ -496,8 +510,10 @@ static void drm_setup_crtcs(struct drm_device *dev) ...@@ -496,8 +510,10 @@ static void drm_setup_crtcs(struct drm_device *dev)
mode->name, crtc->base.id); mode->name, crtc->base.id);
crtc->desired_mode = mode; crtc->desired_mode = mode;
connector->encoder->crtc = crtc; connector->encoder->crtc = crtc;
} else } else {
connector->encoder->crtc = NULL; connector->encoder->crtc = NULL;
connector->encoder = NULL;
}
i++; i++;
} }
......
...@@ -79,6 +79,8 @@ struct drm_encoder_helper_funcs { ...@@ -79,6 +79,8 @@ struct drm_encoder_helper_funcs {
/* detect for DAC style encoders */ /* detect for DAC style encoders */
enum drm_connector_status (*detect)(struct drm_encoder *encoder, enum drm_connector_status (*detect)(struct drm_encoder *encoder,
struct drm_connector *connector); struct drm_connector *connector);
/* disable encoder when not in use - more explicit than dpms off */
void (*disable)(struct drm_encoder *encoder);
}; };
struct drm_connector_helper_funcs { struct drm_connector_helper_funcs {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment