@@ -115,43 +115,57 @@ struct intel_atomic_state {
struct drm_encoder *saved_encoders;
};
-static void update_connectors_bitmask(struct drm_crtc *crtc,
+static void update_connectors_bitmask(struct intel_crtc *intel_crtc,
unsigned long *connectors_bitmask)
{
- struct drm_device *dev = crtc->dev;
- struct drm_connector *connector;
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct intel_connector *intel_connector;
unsigned int i = 0;
*connectors_bitmask = 0;
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->encoder && connector->encoder->crtc == crtc)
+ list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+ if (intel_connector->new_encoder &&
+ intel_connector->new_encoder->new_crtc == intel_crtc)
__set_bit(i, connectors_bitmask);
i++;
}
}
-static void update_encoders_bitmask(struct drm_crtc *crtc,
+static void update_encoders_bitmask(struct intel_crtc *intel_crtc,
unsigned long *encoders_bitmask)
{
- struct drm_device *dev = crtc->dev;
- struct drm_encoder *encoder;
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct intel_encoder *intel_encoder;
unsigned int i = 0;
*encoders_bitmask = 0;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc)
+ list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, base.head) {
+ if (intel_encoder->new_crtc == intel_crtc)
__set_bit(i, encoders_bitmask);
i++;
}
}
+static bool intel_encoder_in_use(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct intel_connector *intel_connector;
+
+ list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
+ if (intel_connector->new_encoder == intel_encoder)
+ return true;
+
+ return false;
+}
+
static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, int count_ids)
{
struct drm_crtc *crtc = s->crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct drm_connector *connectors[count_ids];
struct drm_connector *connector;
@@ -184,6 +198,9 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i
}
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_encoder *intel_encoder;
+
for (i = 0; i < count_ids; i++) {
if (connector == connectors[i])
break;
@@ -192,25 +209,28 @@ static int process_connectors(struct intel_crtc_state *s, const uint32_t *ids, i
/* this connector isn't in the set */
if (i == count_ids) {
/* remove the link to the encoder if this crtc was set to drive it */
- if (connector->encoder && connector->encoder->crtc == crtc)
- connector->encoder = NULL;
+ if (intel_connector->new_encoder &&
+ intel_connector->new_encoder->new_crtc == intel_crtc)
+ intel_connector->new_encoder = NULL;
continue;
}
- encoder = intel_best_encoder(connector);
+ intel_encoder = to_intel_encoder(intel_best_encoder(connector));
- connector->encoder = encoder;
- encoder->crtc = crtc;
+ intel_connector->new_encoder = intel_encoder;
+ intel_encoder->new_crtc = intel_crtc;
}
/* prune dangling encoder->crtc links pointing to this crtc */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc && !drm_helper_encoder_in_use(encoder))
- encoder->crtc = NULL;
+ struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+
+ if (intel_encoder->new_crtc == intel_crtc && !intel_encoder_in_use(intel_encoder))
+ intel_encoder->new_crtc = NULL;
}
- update_connectors_bitmask(s->crtc, &s->connectors_bitmask);
- update_encoders_bitmask(s->crtc, &s->encoders_bitmask);
+ update_connectors_bitmask(intel_crtc, &s->connectors_bitmask);
+ update_encoders_bitmask(intel_crtc, &s->encoders_bitmask);
return 0;
}
@@ -232,19 +252,6 @@ static size_t intel_atomic_state_size(const struct drm_device *dev)
num_plane * sizeof state->saved_planes[0];
}
-
-static void populate_old(struct drm_device *dev)
-{
- struct drm_encoder *encoder;
- struct drm_connector *connector;
-
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
- encoder->old_crtc = encoder->crtc;
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- connector->old_encoder = connector->encoder;
-}
-
static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
uint32_t flags, uint64_t user_data)
{
@@ -275,8 +282,6 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
state->saved_crtcs = (struct intel_crtc *)(state->saved_encoders + num_encoder);
state->saved_planes = (struct drm_plane *)(state->saved_crtcs + num_crtc);
- populate_old(dev);
-
i = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct intel_crtc_state *s = &state->crtc[i++];
@@ -297,8 +302,8 @@ static void *intel_atomic_begin(struct drm_device *dev, struct drm_file *file,
s->old.x = crtc->x;
s->old.y = crtc->y;
- update_connectors_bitmask(crtc, &s->connectors_bitmask);
- update_encoders_bitmask(crtc, &s->encoders_bitmask);
+ update_connectors_bitmask(intel_crtc, &s->connectors_bitmask);
+ update_encoders_bitmask(intel_crtc, &s->encoders_bitmask);
s->old.connectors_bitmask = s->connectors_bitmask;
s->old.encoders_bitmask = s->encoders_bitmask;
@@ -1045,39 +1050,11 @@ static void queue_remaining_events(struct drm_device *dev, struct intel_atomic_s
}
}
-static void swap_old_new(struct drm_device *dev,
- struct intel_atomic_state *s)
-{
- struct drm_encoder *encoder;
- struct drm_connector *connector;
- int i;
-
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
- swap(encoder->crtc, encoder->old_crtc);
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- swap(connector->encoder, connector->old_encoder);
-
- for (i = 0; i < dev->mode_config.num_crtc; i++) {
- struct intel_crtc_state *st = &s->crtc[i];
- struct drm_crtc *crtc = st->crtc;
-
- swap(crtc->enabled, st->old.enabled);
- }
-}
-
static int apply_config(struct drm_device *dev,
struct intel_atomic_state *s)
{
int i, ret;
- /*
- * FIXME
-` * Hackish way to make crtc_disable() see the current
- * state (actually just some select pieces of it).
- */
- swap_old_new(dev, s);
-
for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct intel_crtc_state *st = &s->crtc[i];
@@ -1097,8 +1074,7 @@ static int apply_config(struct drm_device *dev,
crtc_prepare(st, st->crtc);
}
- /* Undo the hack above. */
- swap_old_new(dev, s);
+ intel_modeset_commit_output_state(dev);
for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct intel_crtc_state *st = &s->crtc[i];
@@ -1204,6 +1180,9 @@ static void restore_state(struct drm_device *dev,
list_for_each_entry(plane, &dev->mode_config.plane_list, head)
*plane = s->saved_planes[i++];
+ /* must restore the new_crtc and new_encoder pointers as well */
+ intel_modeset_update_staged_output_state(dev);
+
/* FIXME props etc. */
/* was the hardware state clobbered? */
@@ -1318,8 +1297,9 @@ static int check_crtc(struct intel_crtc_state *s)
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+ struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
- if (encoder->crtc != crtc)
+ if (intel_encoder->new_crtc != intel_crtc)
continue;
if (!encoder_funcs->mode_fixup(encoder, &crtc->mode, &crtc->hwmode))
@@ -1693,7 +1673,6 @@ static int intel_atomic_commit(struct drm_device *dev, void *state)
update_props(dev, s);
- intel_modeset_update_staged_output_state(dev);
return 0;
}