Skip to content

Commit 8c7b5cc

Browse files
Ander Conselvan de Oliveiradanvet
authored andcommitted
drm/i915: Use atomic helpers for computing changed flags
Replace the drivers own logic for computing mode_changed, active_changed and planes_changed flags with the check_modeset() atomic helper. Since that function needs to compare the crtc's new mode with the current, this patch also moves the set up of crtc_state->mode earlier in the call chain. Note that for the call to check_plane() to work properly, we need to check new plane state against new crtc state. But since we still use the plane update helper, which doesn't have a full atomic state, we need to hack around that in intel_plane_atomic_check(). Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 840bfe9 commit 8c7b5cc

File tree

2 files changed

+52
-161
lines changed

2 files changed

+52
-161
lines changed

drivers/gpu/drm/i915/intel_atomic_plane.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
111111
{
112112
struct drm_crtc *crtc = state->crtc;
113113
struct intel_crtc *intel_crtc;
114+
struct intel_crtc_state *crtc_state;
114115
struct intel_plane *intel_plane = to_intel_plane(plane);
115116
struct intel_plane_state *intel_state = to_intel_plane_state(state);
116117

@@ -126,6 +127,17 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
126127
if (!crtc)
127128
return 0;
128129

130+
/* FIXME: temporary hack necessary while we still use the plane update
131+
* helper. */
132+
if (state->state) {
133+
crtc_state =
134+
intel_atomic_get_crtc_state(state->state, intel_crtc);
135+
if (IS_ERR(crtc_state))
136+
return PTR_ERR(crtc_state);
137+
} else {
138+
crtc_state = intel_crtc->config;
139+
}
140+
129141
/*
130142
* The original src/dest coordinates are stored in state->base, but
131143
* we want to keep another copy internal to our driver that we can
@@ -144,9 +156,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
144156
intel_state->clip.x1 = 0;
145157
intel_state->clip.y1 = 0;
146158
intel_state->clip.x2 =
147-
intel_crtc->active ? intel_crtc->config->pipe_src_w : 0;
159+
crtc_state->base.active ? crtc_state->pipe_src_w : 0;
148160
intel_state->clip.y2 =
149-
intel_crtc->active ? intel_crtc->config->pipe_src_h : 0;
161+
crtc_state->base.active ? crtc_state->pipe_src_h : 0;
150162

151163
/*
152164
* Disabling a plane is always okay; we just need to update

drivers/gpu/drm/i915/intel_display.c

Lines changed: 38 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
8282
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
8383
struct intel_crtc_state *pipe_config);
8484

85-
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
85+
static int intel_set_mode(struct drm_crtc *crtc,
8686
struct drm_atomic_state *state);
8787
static int intel_framebuffer_init(struct drm_device *dev,
8888
struct intel_framebuffer *ifb,
@@ -9892,7 +9892,9 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
98929892
if (ret)
98939893
goto fail;
98949894

9895-
if (intel_set_mode(crtc, mode, state)) {
9895+
drm_mode_copy(&crtc_state->base.mode, mode);
9896+
9897+
if (intel_set_mode(crtc, state)) {
98969898
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
98979899
if (old->release_fb)
98989900
old->release_fb->funcs->destroy(old->release_fb);
@@ -9966,7 +9968,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
99669968
if (ret)
99679969
goto fail;
99689970

9969-
intel_set_mode(crtc, NULL, state);
9971+
intel_set_mode(crtc, state);
99709972

99719973
drm_atomic_state_free(state);
99729974

@@ -11476,7 +11478,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
1147611478

1147711479
static int
1147811480
intel_modeset_pipe_config(struct drm_crtc *crtc,
11479-
struct drm_display_mode *mode,
1148011481
struct drm_atomic_state *state,
1148111482
struct intel_crtc_state *pipe_config)
1148211483
{
@@ -11499,10 +11500,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
1149911500

1150011501
clear_intel_crtc_state(pipe_config);
1150111502

11502-
pipe_config->base.crtc = crtc;
11503-
drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
11504-
drm_mode_copy(&pipe_config->base.mode, mode);
11505-
1150611503
pipe_config->cpu_transcoder =
1150711504
(enum transcoder) to_intel_crtc(crtc)->pipe;
1150811505
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
@@ -12199,27 +12196,8 @@ static void update_scanline_offset(struct intel_crtc *crtc)
1219912196
crtc->scanline_offset = 1;
1220012197
}
1220112198

12202-
static void
12203-
intel_atomic_modeset_compute_changed_flags(struct drm_atomic_state *state,
12204-
struct drm_crtc *modeset_crtc)
12205-
{
12206-
struct drm_crtc_state *crtc_state;
12207-
struct drm_crtc *crtc;
12208-
int i;
12209-
12210-
for_each_crtc_in_state(state, crtc, crtc_state, i) {
12211-
if (crtc_state->enable != crtc->state->enable)
12212-
crtc_state->mode_changed = true;
12213-
12214-
/* FIXME: Do we need to always set mode_changed for
12215-
* modeset_crtc if it is enabled? modeset_affect_pipes()
12216-
* did that. */
12217-
}
12218-
}
12219-
1222012199
static struct intel_crtc_state *
1222112200
intel_modeset_compute_config(struct drm_crtc *crtc,
12222-
struct drm_display_mode *mode,
1222312201
struct drm_atomic_state *state)
1222412202
{
1222512203
struct intel_crtc_state *pipe_config;
@@ -12229,7 +12207,9 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
1222912207
if (ret)
1223012208
return ERR_PTR(ret);
1223112209

12232-
intel_atomic_modeset_compute_changed_flags(state, crtc);
12210+
ret = drm_atomic_helper_check_modeset(state->dev, state);
12211+
if (ret)
12212+
return ERR_PTR(ret);
1223312213

1223412214
/*
1223512215
* Note this needs changes when we start tracking multiple modes
@@ -12244,7 +12224,7 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
1224412224
if (!pipe_config->base.enable)
1224512225
return pipe_config;
1224612226

12247-
ret = intel_modeset_pipe_config(crtc, mode, state, pipe_config);
12227+
ret = intel_modeset_pipe_config(crtc, state, pipe_config);
1224812228
if (ret)
1224912229
return ERR_PTR(ret);
1225012230

@@ -12262,6 +12242,10 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
1226212242

1226312243
intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,"[modeset]");
1226412244

12245+
ret = drm_atomic_helper_check_planes(state->dev, state);
12246+
if (ret)
12247+
return ERR_PTR(ret);
12248+
1226512249
return pipe_config;
1226612250
}
1226712251

@@ -12337,7 +12321,6 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
1233712321
}
1233812322

1233912323
static int __intel_set_mode(struct drm_crtc *modeset_crtc,
12340-
struct drm_display_mode *mode,
1234112324
struct intel_crtc_state *pipe_config)
1234212325
{
1234312326
struct drm_device *dev = modeset_crtc->dev;
@@ -12380,7 +12363,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
1238012363
* single crtc and mode.
1238112364
*/
1238212365
if (pipe_config->base.enable && needs_modeset(&pipe_config->base)) {
12383-
modeset_crtc->mode = *mode;
12366+
modeset_crtc->mode = pipe_config->base.mode;
1238412367
/* mode_set/enable/disable functions rely on a correct pipe
1238512368
* config. */
1238612369
intel_crtc_set_state(to_intel_crtc(modeset_crtc), pipe_config);
@@ -12446,12 +12429,11 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
1244612429
}
1244712430

1244812431
static int intel_set_mode_with_config(struct drm_crtc *crtc,
12449-
struct drm_display_mode *mode,
1245012432
struct intel_crtc_state *pipe_config)
1245112433
{
1245212434
int ret;
1245312435

12454-
ret = __intel_set_mode(crtc, mode, pipe_config);
12436+
ret = __intel_set_mode(crtc, pipe_config);
1245512437

1245612438
if (ret == 0)
1245712439
intel_modeset_check_state(crtc->dev);
@@ -12460,19 +12442,18 @@ static int intel_set_mode_with_config(struct drm_crtc *crtc,
1246012442
}
1246112443

1246212444
static int intel_set_mode(struct drm_crtc *crtc,
12463-
struct drm_display_mode *mode,
1246412445
struct drm_atomic_state *state)
1246512446
{
1246612447
struct intel_crtc_state *pipe_config;
1246712448
int ret = 0;
1246812449

12469-
pipe_config = intel_modeset_compute_config(crtc, mode, state);
12450+
pipe_config = intel_modeset_compute_config(crtc, state);
1247012451
if (IS_ERR(pipe_config)) {
1247112452
ret = PTR_ERR(pipe_config);
1247212453
goto out;
1247312454
}
1247412455

12475-
ret = intel_set_mode_with_config(crtc, mode, pipe_config);
12456+
ret = intel_set_mode_with_config(crtc, pipe_config);
1247612457
if (ret)
1247712458
goto out;
1247812459

@@ -12539,125 +12520,21 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
1253912520
}
1254012521

1254112522
crtc_state->base.enable = intel_crtc->new_enabled;
12523+
12524+
if (&intel_crtc->base == crtc)
12525+
drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
1254212526
}
1254312527

1254412528
intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
1254512529
crtc->primary->fb, crtc->x, crtc->y);
1254612530

12547-
intel_set_mode(crtc, &crtc->mode, state);
12531+
intel_set_mode(crtc, state);
1254812532

1254912533
drm_atomic_state_free(state);
1255012534
}
1255112535

1255212536
#undef for_each_intel_crtc_masked
1255312537

12554-
static bool
12555-
is_crtc_connector_off(struct drm_mode_set *set)
12556-
{
12557-
int i;
12558-
12559-
if (set->num_connectors == 0)
12560-
return false;
12561-
12562-
if (WARN_ON(set->connectors == NULL))
12563-
return false;
12564-
12565-
for (i = 0; i < set->num_connectors; i++)
12566-
if (set->connectors[i]->encoder &&
12567-
set->connectors[i]->encoder->crtc == set->crtc &&
12568-
set->connectors[i]->dpms != DRM_MODE_DPMS_ON)
12569-
return true;
12570-
12571-
return false;
12572-
}
12573-
12574-
static void
12575-
intel_set_config_compute_mode_changes(struct drm_mode_set *set,
12576-
struct intel_crtc_state *pipe_config)
12577-
{
12578-
struct drm_atomic_state *state;
12579-
struct drm_connector *connector;
12580-
struct drm_connector_state *connector_state;
12581-
struct drm_crtc *crtc;
12582-
struct drm_crtc_state *crtc_state;
12583-
int i;
12584-
12585-
/* We should be able to check here if the fb has the same properties
12586-
* and then just flip_or_move it */
12587-
if (is_crtc_connector_off(set)) {
12588-
pipe_config->base.mode_changed = true;
12589-
} else if (set->crtc->primary->fb != set->fb) {
12590-
/*
12591-
* If we have no fb, we can only flip as long as the crtc is
12592-
* active, otherwise we need a full mode set. The crtc may
12593-
* be active if we've only disabled the primary plane, or
12594-
* in fastboot situations.
12595-
*/
12596-
if (set->crtc->primary->fb == NULL) {
12597-
struct intel_crtc *intel_crtc =
12598-
to_intel_crtc(set->crtc);
12599-
12600-
if (intel_crtc->active) {
12601-
DRM_DEBUG_KMS("crtc has no fb, will flip\n");
12602-
pipe_config->base.planes_changed = true;
12603-
} else {
12604-
DRM_DEBUG_KMS("inactive crtc, full mode set\n");
12605-
pipe_config->base.mode_changed = true;
12606-
}
12607-
} else if (set->fb == NULL) {
12608-
pipe_config->base.mode_changed = true;
12609-
} else if (set->fb->pixel_format !=
12610-
set->crtc->primary->fb->pixel_format) {
12611-
pipe_config->base.mode_changed = true;
12612-
} else {
12613-
pipe_config->base.planes_changed = true;
12614-
}
12615-
}
12616-
12617-
if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
12618-
pipe_config->base.planes_changed = true;
12619-
12620-
if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
12621-
DRM_DEBUG_KMS("modes are different, full mode set\n");
12622-
drm_mode_debug_printmodeline(&set->crtc->mode);
12623-
drm_mode_debug_printmodeline(set->mode);
12624-
pipe_config->base.mode_changed = true;
12625-
}
12626-
12627-
state = pipe_config->base.state;
12628-
12629-
for_each_connector_in_state(state, connector, connector_state, i) {
12630-
if (connector_state->best_encoder !=
12631-
connector->state->best_encoder) {
12632-
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] encoder changed, full mode switch\n",
12633-
connector->base.id,
12634-
connector->name);
12635-
pipe_config->base.mode_changed = true;
12636-
}
12637-
12638-
if (connector_state->crtc != connector->state->crtc) {
12639-
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] crtc changed, full mode switch\n",
12640-
connector->base.id,
12641-
connector->name);
12642-
pipe_config->base.mode_changed = true;
12643-
}
12644-
}
12645-
12646-
for_each_crtc_in_state(state, crtc, crtc_state, i) {
12647-
if (crtc_state->enable == crtc->state->enable)
12648-
continue;
12649-
12650-
DRM_DEBUG_KMS("[CRTC:%d] %sabled, full mode switch\n",
12651-
crtc->base.id,
12652-
crtc_state->enable ? "en" : "dis");
12653-
pipe_config->base.mode_changed = true;
12654-
}
12655-
12656-
DRM_DEBUG_KMS("computed changes for [CRTC:%d], mode_changed=%d, fb_changed=%d\n",
12657-
set->crtc->base.id, pipe_config->base.mode_changed,
12658-
pipe_config->base.planes_changed);
12659-
}
12660-
1266112538
static bool intel_connector_in_mode_set(struct intel_connector *connector,
1266212539
struct drm_mode_set *set)
1266312540
{
@@ -12774,6 +12651,21 @@ intel_modeset_stage_output_state(struct drm_device *dev,
1277412651
crtc_state->enable = drm_atomic_connectors_for_crtc(state, crtc);
1277512652
}
1277612653

12654+
ret = intel_modeset_setup_plane_state(state, set->crtc, set->mode,
12655+
set->fb, set->x, set->y);
12656+
if (ret)
12657+
return ret;
12658+
12659+
crtc_state = drm_atomic_get_crtc_state(state, set->crtc);
12660+
if (IS_ERR(crtc_state))
12661+
return PTR_ERR(crtc_state);
12662+
12663+
if (set->mode)
12664+
drm_mode_copy(&crtc_state->mode, set->mode);
12665+
12666+
if (set->num_connectors)
12667+
crtc_state->active = true;
12668+
1277712669
return 0;
1277812670
}
1277912671

@@ -12821,30 +12713,17 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
1282112713
if (ret)
1282212714
goto out;
1282312715

12824-
ret = intel_modeset_setup_plane_state(state, set->crtc, set->mode,
12825-
set->fb, set->x, set->y);
12826-
if (ret)
12827-
goto out;
12828-
12829-
pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
12830-
state);
12716+
pipe_config = intel_modeset_compute_config(set->crtc, state);
1283112717
if (IS_ERR(pipe_config)) {
1283212718
ret = PTR_ERR(pipe_config);
1283312719
goto out;
1283412720
}
1283512721

12836-
/* Compute whether we need a full modeset, only an fb base update or no
12837-
* change at all. In the future we might also check whether only the
12838-
* mode changed, e.g. for LVDS where we only change the panel fitter in
12839-
* such cases. */
12840-
intel_set_config_compute_mode_changes(set, pipe_config);
12841-
1284212722
intel_update_pipe_size(to_intel_crtc(set->crtc));
1284312723

1284412724
primary_plane_was_visible = primary_plane_visible(set->crtc);
1284512725

12846-
ret = intel_set_mode_with_config(set->crtc, set->mode,
12847-
pipe_config);
12726+
ret = intel_set_mode_with_config(set->crtc, pipe_config);
1284812727

1284912728
if (ret == 0 &&
1285012729
pipe_config->base.enable &&

0 commit comments

Comments
 (0)