Skip to content

Commit 79c47d9

Browse files
anholtpopcornmix
authored andcommitted
drm/vc4: Add support for setting DPMS in firmwarekms.
This ensures that the screen goes blank during DPMS (screensaver), including the cursor. Planes don't necessarily get disabled during CRTC disable, so we need to be careful to not leave them on or turn them back on early. Signed-off-by: Eric Anholt <[email protected]>
1 parent 7589ce5 commit 79c47d9

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

drivers/gpu/drm/vc4/vc4_firmware_kms.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct vc4_crtc {
3838
struct drm_crtc base;
3939
struct drm_encoder *encoder;
4040
struct drm_connector *connector;
41+
struct drm_plane *primary;
42+
struct drm_plane *cursor;
4143
void __iomem *regs;
4244

4345
struct drm_pending_vblank_event *event;
@@ -126,8 +128,6 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane,
126128
u32 bpp = 32;
127129
int ret;
128130

129-
vc4_plane_set_primary_blank(plane, false);
130-
131131
fbinfo->xres = state->crtc_w;
132132
fbinfo->yres = state->crtc_h;
133133
fbinfo->xres_virtual = state->crtc_w;
@@ -175,6 +175,12 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane,
175175
vc4_plane->fbinfo_bus_addr);
176176
WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]);
177177
WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]);
178+
179+
/* If the CRTC is on (or going to be on) and we're enabled,
180+
* then unblank. Otherwise, stay blank until CRTC enable.
181+
*/
182+
if (state->crtc->state->active)
183+
vc4_plane_set_primary_blank(plane, false);
178184
}
179185

180186
static void vc4_primary_plane_atomic_disable(struct drm_plane *plane,
@@ -192,7 +198,12 @@ static void vc4_cursor_plane_atomic_update(struct drm_plane *plane,
192198
struct drm_framebuffer *fb = state->fb;
193199
struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
194200
int ret;
195-
u32 packet_state[] = { true, state->crtc_x, state->crtc_y, 0 };
201+
u32 packet_state[] = {
202+
state->crtc->state->active,
203+
state->crtc_x,
204+
state->crtc_y,
205+
0
206+
};
196207
u32 packet_info[] = { state->crtc_w, state->crtc_h,
197208
0, /* unused */
198209
bo->paddr + fb->offsets[0],
@@ -336,10 +347,30 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
336347

337348
static void vc4_crtc_disable(struct drm_crtc *crtc)
338349
{
350+
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
351+
352+
/* Always turn the planes off on CRTC disable. In DRM, planes
353+
* are enabled/disabled through the update/disable hooks
354+
* above, and the CRTC enable/disable independently controls
355+
* whether anything scans out at all, but the firmware doesn't
356+
* give us a CRTC-level control for that.
357+
*/
358+
vc4_cursor_plane_atomic_disable(vc4_crtc->cursor,
359+
vc4_crtc->cursor->state);
360+
vc4_plane_set_primary_blank(vc4_crtc->primary, true);
339361
}
340362

341363
static void vc4_crtc_enable(struct drm_crtc *crtc)
342364
{
365+
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
366+
367+
/* Unblank the planes (if they're supposed to be displayed). */
368+
if (vc4_crtc->primary->state->fb)
369+
vc4_plane_set_primary_blank(vc4_crtc->primary, false);
370+
if (vc4_crtc->cursor->state->fb) {
371+
vc4_cursor_plane_atomic_update(vc4_crtc->cursor,
372+
vc4_crtc->cursor->state);
373+
}
343374
}
344375

345376
static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -635,6 +666,9 @@ static int vc4_fkms_bind(struct device *dev, struct device *master, void *data)
635666
cursor_plane->crtc = crtc;
636667
vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
637668

669+
vc4_crtc->primary = primary_plane;
670+
vc4_crtc->cursor = cursor_plane;
671+
638672
vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL);
639673
if (!vc4_encoder)
640674
return -ENOMEM;

0 commit comments

Comments
 (0)