@@ -196,6 +196,62 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc)
196
196
vc4_hvs_lut_load (crtc );
197
197
}
198
198
199
+ static int vc4_hvs_init_channel (struct vc4_dev * vc4 , struct drm_crtc * crtc ,
200
+ struct drm_display_mode * mode , bool oneshot )
201
+ {
202
+ struct vc4_crtc_state * vc4_crtc_state = to_vc4_crtc_state (crtc -> state );
203
+ unsigned int chan = vc4_crtc_state -> assigned_channel ;
204
+ u32 dispctrl ;
205
+
206
+ /* Turn on the scaler, which will wait for vstart to start
207
+ * compositing.
208
+ * When feeding the transposer, we should operate in oneshot
209
+ * mode.
210
+ */
211
+ dispctrl = SCALER_DISPCTRLX_ENABLE ;
212
+
213
+ if (!vc4 -> hvs -> hvs5 )
214
+ dispctrl |= VC4_SET_FIELD (mode -> hdisplay ,
215
+ SCALER_DISPCTRLX_WIDTH ) |
216
+ VC4_SET_FIELD (mode -> vdisplay ,
217
+ SCALER_DISPCTRLX_HEIGHT ) |
218
+ (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0 );
219
+ else
220
+ dispctrl |= VC4_SET_FIELD (mode -> hdisplay ,
221
+ SCALER5_DISPCTRLX_WIDTH ) |
222
+ VC4_SET_FIELD (mode -> vdisplay ,
223
+ SCALER5_DISPCTRLX_HEIGHT ) |
224
+ (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0 );
225
+
226
+ HVS_WRITE (SCALER_DISPCTRLX (chan ), dispctrl );
227
+
228
+ return 0 ;
229
+ }
230
+
231
+ static void vc4_hvs_stop_channel (struct drm_device * dev , unsigned int chan )
232
+ {
233
+ struct vc4_dev * vc4 = to_vc4_dev (dev );
234
+
235
+ if (HVS_READ (SCALER_DISPCTRLX (chan )) & SCALER_DISPCTRLX_ENABLE )
236
+ return ;
237
+
238
+ HVS_WRITE (SCALER_DISPCTRLX (chan ),
239
+ HVS_READ (SCALER_DISPCTRLX (chan )) | SCALER_DISPCTRLX_RESET );
240
+ HVS_WRITE (SCALER_DISPCTRLX (chan ),
241
+ HVS_READ (SCALER_DISPCTRLX (chan )) & ~SCALER_DISPCTRLX_ENABLE );
242
+
243
+ /* Once we leave, the scaler should be disabled and its fifo empty. */
244
+ WARN_ON_ONCE (HVS_READ (SCALER_DISPCTRLX (chan )) & SCALER_DISPCTRLX_RESET );
245
+
246
+ WARN_ON_ONCE (VC4_GET_FIELD (HVS_READ (SCALER_DISPSTATX (chan )),
247
+ SCALER_DISPSTATX_MODE ) !=
248
+ SCALER_DISPSTATX_MODE_DISABLED );
249
+
250
+ WARN_ON_ONCE ((HVS_READ (SCALER_DISPSTATX (chan )) &
251
+ (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY )) !=
252
+ SCALER_DISPSTATX_EMPTY );
253
+ }
254
+
199
255
int vc4_hvs_atomic_check (struct drm_crtc * crtc ,
200
256
struct drm_crtc_state * state )
201
257
{
@@ -268,63 +324,19 @@ void vc4_hvs_atomic_enable(struct drm_crtc *crtc,
268
324
struct vc4_crtc_state * vc4_state = to_vc4_crtc_state (crtc -> state );
269
325
struct drm_display_mode * mode = & crtc -> state -> adjusted_mode ;
270
326
bool oneshot = vc4_state -> feed_txp ;
271
- u32 dispctrl ;
272
327
273
328
vc4_hvs_update_dlist (crtc );
274
-
275
- /* Turn on the scaler, which will wait for vstart to start
276
- * compositing.
277
- * When feeding the transposer, we should operate in oneshot
278
- * mode.
279
- */
280
- dispctrl = SCALER_DISPCTRLX_ENABLE ;
281
-
282
- if (!vc4 -> hvs -> hvs5 )
283
- dispctrl |= VC4_SET_FIELD (mode -> hdisplay ,
284
- SCALER_DISPCTRLX_WIDTH ) |
285
- VC4_SET_FIELD (mode -> vdisplay ,
286
- SCALER_DISPCTRLX_HEIGHT ) |
287
- (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0 );
288
- else
289
- dispctrl |= VC4_SET_FIELD (mode -> hdisplay ,
290
- SCALER5_DISPCTRLX_WIDTH ) |
291
- VC4_SET_FIELD (mode -> vdisplay ,
292
- SCALER5_DISPCTRLX_HEIGHT ) |
293
- (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0 );
294
-
295
- HVS_WRITE (SCALER_DISPCTRLX (vc4_state -> assigned_channel ), dispctrl );
329
+ vc4_hvs_init_channel (vc4 , crtc , mode , oneshot );
296
330
}
297
331
298
332
void vc4_hvs_atomic_disable (struct drm_crtc * crtc ,
299
333
struct drm_crtc_state * old_state )
300
334
{
301
335
struct drm_device * dev = crtc -> dev ;
302
- struct vc4_dev * vc4 = to_vc4_dev (dev );
303
336
struct vc4_crtc_state * vc4_state = to_vc4_crtc_state (old_state );
304
337
unsigned int chan = vc4_state -> assigned_channel ;
305
338
306
- if (HVS_READ (SCALER_DISPCTRLX (chan )) &
307
- SCALER_DISPCTRLX_ENABLE ) {
308
- HVS_WRITE (SCALER_DISPCTRLX (chan ),
309
- SCALER_DISPCTRLX_RESET );
310
-
311
- /* While the docs say that reset is self-clearing, it
312
- * seems it doesn't actually.
313
- */
314
- HVS_WRITE (SCALER_DISPCTRLX (chan ), 0 );
315
- }
316
-
317
- /* Once we leave, the scaler should be disabled and its fifo empty. */
318
-
319
- WARN_ON_ONCE (HVS_READ (SCALER_DISPCTRLX (chan )) & SCALER_DISPCTRLX_RESET );
320
-
321
- WARN_ON_ONCE (VC4_GET_FIELD (HVS_READ (SCALER_DISPSTATX (chan )),
322
- SCALER_DISPSTATX_MODE ) !=
323
- SCALER_DISPSTATX_MODE_DISABLED );
324
-
325
- WARN_ON_ONCE ((HVS_READ (SCALER_DISPSTATX (chan )) &
326
- (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY )) !=
327
- SCALER_DISPSTATX_EMPTY );
339
+ vc4_hvs_stop_channel (dev , chan );
328
340
}
329
341
330
342
void vc4_hvs_atomic_flush (struct drm_crtc * crtc ,
0 commit comments