@@ -38,6 +38,8 @@ struct vc4_crtc {
38
38
struct drm_crtc base ;
39
39
struct drm_encoder * encoder ;
40
40
struct drm_connector * connector ;
41
+ struct drm_plane * primary ;
42
+ struct drm_plane * cursor ;
41
43
void __iomem * regs ;
42
44
43
45
struct drm_pending_vblank_event * event ;
@@ -126,8 +128,6 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane,
126
128
u32 bpp = 32 ;
127
129
int ret ;
128
130
129
- vc4_plane_set_primary_blank (plane , false);
130
-
131
131
fbinfo -> xres = state -> crtc_w ;
132
132
fbinfo -> yres = state -> crtc_h ;
133
133
fbinfo -> xres_virtual = state -> crtc_w ;
@@ -175,6 +175,12 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane,
175
175
vc4_plane -> fbinfo_bus_addr );
176
176
WARN_ON_ONCE (fbinfo -> pitch != fb -> pitches [0 ]);
177
177
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);
178
184
}
179
185
180
186
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,
192
198
struct drm_framebuffer * fb = state -> fb ;
193
199
struct drm_gem_cma_object * bo = drm_fb_cma_get_gem_obj (fb , 0 );
194
200
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
+ };
196
207
u32 packet_info [] = { state -> crtc_w , state -> crtc_h ,
197
208
0 , /* unused */
198
209
bo -> paddr + fb -> offsets [0 ],
@@ -336,10 +347,30 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
336
347
337
348
static void vc4_crtc_disable (struct drm_crtc * crtc )
338
349
{
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);
339
361
}
340
362
341
363
static void vc4_crtc_enable (struct drm_crtc * crtc )
342
364
{
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
+ }
343
374
}
344
375
345
376
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)
635
666
cursor_plane -> crtc = crtc ;
636
667
vc4 -> crtc [drm_crtc_index (crtc )] = vc4_crtc ;
637
668
669
+ vc4_crtc -> primary = primary_plane ;
670
+ vc4_crtc -> cursor = cursor_plane ;
671
+
638
672
vc4_encoder = devm_kzalloc (dev , sizeof (* vc4_encoder ), GFP_KERNEL );
639
673
if (!vc4_encoder )
640
674
return - ENOMEM ;
0 commit comments