mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 18:24:14 +08:00
drm/i915: Get rid of dpms handling.
This is now done completely atomically. Keep connectors_active for now, but make it mirror crtc_state->active. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
4d20cd860b
commit
4d688a2a15
@ -236,53 +236,6 @@ static void intel_enable_crt(struct intel_encoder *encoder)
|
||||
intel_crt_set_dpms(encoder, crt->connector->base.dpms);
|
||||
}
|
||||
|
||||
/* Special dpms function to support cloning between dvo/sdvo/crt. */
|
||||
static int intel_crt_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_crtc *crtc;
|
||||
int old_dpms;
|
||||
|
||||
/* PCH platforms and VLV only support on/off. */
|
||||
if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (mode == connector->dpms)
|
||||
return 0;
|
||||
|
||||
old_dpms = connector->dpms;
|
||||
connector->dpms = mode;
|
||||
|
||||
/* Only need to change hw state when actually enabled */
|
||||
crtc = encoder->base.crtc;
|
||||
if (!crtc) {
|
||||
encoder->connectors_active = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We need the pipe to run for anything but OFF. */
|
||||
if (mode == DRM_MODE_DPMS_OFF)
|
||||
encoder->connectors_active = false;
|
||||
else
|
||||
encoder->connectors_active = true;
|
||||
|
||||
/* We call connector dpms manually below in case pipe dpms doesn't
|
||||
* change due to cloning. */
|
||||
if (mode < old_dpms) {
|
||||
/* From off to on, enable the pipe first. */
|
||||
intel_crtc_update_dpms(crtc);
|
||||
|
||||
intel_crt_set_dpms(encoder, mode);
|
||||
} else {
|
||||
intel_crt_set_dpms(encoder, mode);
|
||||
|
||||
intel_crtc_update_dpms(crtc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
intel_crt_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
@ -798,7 +751,7 @@ static void intel_crt_reset(struct drm_connector *connector)
|
||||
|
||||
static const struct drm_connector_funcs intel_crt_connector_funcs = {
|
||||
.reset = intel_crt_reset,
|
||||
.dpms = intel_crt_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_crt_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = intel_crt_destroy,
|
||||
|
@ -6273,67 +6273,6 @@ free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Master function to enable/disable CRTC and corresponding power wells */
|
||||
int intel_crtc_control(struct drm_crtc *crtc, bool enable)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_crtc_state *pipe_config;
|
||||
struct drm_atomic_state *state;
|
||||
int ret;
|
||||
|
||||
if (enable == intel_crtc->active)
|
||||
return 0;
|
||||
|
||||
if (enable && !crtc->state->enable)
|
||||
return 0;
|
||||
|
||||
/* this function should be called with drm_modeset_lock_all for now */
|
||||
if (WARN_ON(!ctx))
|
||||
return -EIO;
|
||||
lockdep_assert_held(&ctx->ww_ctx);
|
||||
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
if (WARN_ON(!state))
|
||||
return -ENOMEM;
|
||||
|
||||
state->acquire_ctx = ctx;
|
||||
state->allow_modeset = true;
|
||||
|
||||
pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
|
||||
if (IS_ERR(pipe_config)) {
|
||||
ret = PTR_ERR(pipe_config);
|
||||
goto err;
|
||||
}
|
||||
pipe_config->base.active = enable;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
err:
|
||||
DRM_ERROR("Updating crtc active failed with %i\n", ret);
|
||||
drm_atomic_state_free(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the power management mode of the pipe and plane.
|
||||
*/
|
||||
void intel_crtc_update_dpms(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct intel_encoder *intel_encoder;
|
||||
bool enable = false;
|
||||
|
||||
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
|
||||
enable |= intel_encoder->connectors_active;
|
||||
|
||||
intel_crtc_control(crtc, enable);
|
||||
}
|
||||
|
||||
void intel_encoder_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
||||
@ -6342,22 +6281,6 @@ void intel_encoder_destroy(struct drm_encoder *encoder)
|
||||
kfree(intel_encoder);
|
||||
}
|
||||
|
||||
/* Simple dpms helper for encoders with just one connector, no cloning and only
|
||||
* one kind of off state. It clamps all !ON modes to fully OFF and changes the
|
||||
* state of the entire output pipe. */
|
||||
static void intel_encoder_dpms(struct intel_encoder *encoder, int mode)
|
||||
{
|
||||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
encoder->connectors_active = true;
|
||||
|
||||
intel_crtc_update_dpms(encoder->base.crtc);
|
||||
} else {
|
||||
encoder->connectors_active = false;
|
||||
|
||||
intel_crtc_update_dpms(encoder->base.crtc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cross check the actual hw state with our own modeset state tracking (and it's
|
||||
* internal consistency). */
|
||||
static void intel_connector_check_state(struct intel_connector *connector)
|
||||
@ -6390,6 +6313,8 @@ static void intel_connector_check_state(struct intel_connector *connector)
|
||||
I915_STATE_WARN(conn_state->crtc != encoder->crtc,
|
||||
"attached encoder crtc differs from connector crtc\n");
|
||||
} else {
|
||||
I915_STATE_WARN(crtc && crtc->state->active,
|
||||
"attached crtc is active, but connector isn't\n");
|
||||
I915_STATE_WARN(!crtc && connector->base.state->best_encoder,
|
||||
"best encoder set without crtc!\n");
|
||||
}
|
||||
@ -6423,26 +6348,6 @@ struct intel_connector *intel_connector_alloc(void)
|
||||
return connector;
|
||||
}
|
||||
|
||||
/* Even simpler default implementation, if there's really no special case to
|
||||
* consider. */
|
||||
int intel_connector_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
/* All the simple cases only support two dpms states. */
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (mode == connector->dpms)
|
||||
return 0;
|
||||
|
||||
connector->dpms = mode;
|
||||
|
||||
/* Only need to change hw state when actually enabled */
|
||||
if (connector->encoder)
|
||||
intel_encoder_dpms(to_intel_encoder(connector->encoder), mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Simple connector->get_hw_state implementation for encoders that support only
|
||||
* one connector and no cloning and hence the encoder state determines the state
|
||||
* of the connector. */
|
||||
|
@ -4839,7 +4839,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dp_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dp_detect,
|
||||
.force = intel_dp_force,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
|
@ -328,7 +328,7 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dp_mst_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = intel_dp_mst_set_property,
|
||||
|
@ -992,12 +992,9 @@ void intel_mark_busy(struct drm_device *dev);
|
||||
void intel_mark_idle(struct drm_device *dev);
|
||||
void intel_crtc_restore_mode(struct drm_crtc *crtc);
|
||||
int intel_display_suspend(struct drm_device *dev);
|
||||
int intel_crtc_control(struct drm_crtc *crtc, bool enable);
|
||||
void intel_crtc_update_dpms(struct drm_crtc *crtc);
|
||||
void intel_encoder_destroy(struct drm_encoder *encoder);
|
||||
int intel_connector_init(struct intel_connector *);
|
||||
struct intel_connector *intel_connector_alloc(void);
|
||||
int intel_connector_dpms(struct drm_connector *, int mode);
|
||||
bool intel_connector_get_hw_state(struct intel_connector *connector);
|
||||
bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
|
||||
struct intel_digital_port *port);
|
||||
|
@ -982,7 +982,7 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_dsi_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dsi_detect,
|
||||
.destroy = intel_dsi_connector_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
|
@ -196,50 +196,6 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
|
||||
}
|
||||
|
||||
/* Special dpms function to support cloning between dvo/sdvo/crt. */
|
||||
static int intel_dvo_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_crtc_state *config;
|
||||
|
||||
/* dvo supports only 2 dpms states. */
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (mode == connector->dpms)
|
||||
return 0;
|
||||
|
||||
connector->dpms = mode;
|
||||
|
||||
/* Only need to change hw state when actually enabled */
|
||||
crtc = intel_dvo->base.base.crtc;
|
||||
if (!crtc) {
|
||||
intel_dvo->base.connectors_active = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We call connector dpms manually below in case pipe dpms doesn't
|
||||
* change due to cloning. */
|
||||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
config = to_intel_crtc(crtc)->config;
|
||||
|
||||
intel_dvo->base.connectors_active = true;
|
||||
|
||||
intel_crtc_update_dpms(crtc);
|
||||
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
|
||||
} else {
|
||||
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
|
||||
|
||||
intel_dvo->base.connectors_active = false;
|
||||
|
||||
intel_crtc_update_dpms(crtc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
intel_dvo_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
@ -387,7 +343,7 @@ static void intel_dvo_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
|
||||
.dpms = intel_dvo_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_dvo_detect,
|
||||
.destroy = intel_dvo_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
|
@ -1909,7 +1909,7 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_hdmi_detect,
|
||||
.force = intel_hdmi_force,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
|
@ -549,7 +549,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_lvds_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = intel_lvds_set_property,
|
||||
|
@ -1508,51 +1508,6 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
|
||||
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
|
||||
}
|
||||
|
||||
/* Special dpms function to support cloning between dvo/sdvo/crt. */
|
||||
static int intel_sdvo_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
|
||||
|
||||
/* dvo supports only 2 dpms states. */
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (mode == connector->dpms)
|
||||
return 0;
|
||||
|
||||
connector->dpms = mode;
|
||||
|
||||
/* Only need to change hw state when actually enabled */
|
||||
crtc = intel_sdvo->base.base.crtc;
|
||||
if (!crtc) {
|
||||
intel_sdvo->base.connectors_active = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We set active outputs manually below in case pipe dpms doesn't change
|
||||
* due to cloning. */
|
||||
if (mode != DRM_MODE_DPMS_ON) {
|
||||
intel_sdvo_set_active_outputs(intel_sdvo, 0);
|
||||
if (0)
|
||||
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
|
||||
|
||||
intel_sdvo->base.connectors_active = false;
|
||||
|
||||
intel_crtc_update_dpms(crtc);
|
||||
} else {
|
||||
intel_sdvo->base.connectors_active = true;
|
||||
|
||||
intel_crtc_update_dpms(crtc);
|
||||
|
||||
if (0)
|
||||
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
|
||||
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
intel_sdvo_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
@ -2190,7 +2145,7 @@ done:
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
|
||||
.dpms = intel_sdvo_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_sdvo_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = intel_sdvo_set_property,
|
||||
|
@ -1509,7 +1509,7 @@ out:
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs intel_tv_connector_funcs = {
|
||||
.dpms = intel_connector_dpms,
|
||||
.dpms = drm_atomic_helper_connector_dpms,
|
||||
.detect = intel_tv_detect,
|
||||
.destroy = intel_tv_destroy,
|
||||
.set_property = intel_tv_set_property,
|
||||
|
Loading…
Reference in New Issue
Block a user