diff options
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 7e440f61977f..9eee47969e77 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c | |||
@@ -287,6 +287,47 @@ int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu) | |||
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | static void rcar_du_group_set_dpad_levels(struct rcar_du_group *rgrp) | ||
291 | { | ||
292 | static const u32 doflr_values[2] = { | ||
293 | DOFLR_HSYCFL0 | DOFLR_VSYCFL0 | DOFLR_ODDFL0 | | ||
294 | DOFLR_DISPFL0 | DOFLR_CDEFL0 | DOFLR_RGBFL0, | ||
295 | DOFLR_HSYCFL1 | DOFLR_VSYCFL1 | DOFLR_ODDFL1 | | ||
296 | DOFLR_DISPFL1 | DOFLR_CDEFL1 | DOFLR_RGBFL1, | ||
297 | }; | ||
298 | static const u32 dpad_mask = BIT(RCAR_DU_OUTPUT_DPAD1) | ||
299 | | BIT(RCAR_DU_OUTPUT_DPAD0); | ||
300 | struct rcar_du_device *rcdu = rgrp->dev; | ||
301 | u32 doflr = DOFLR_CODE; | ||
302 | unsigned int i; | ||
303 | |||
304 | if (rcdu->info->gen < 2) | ||
305 | return; | ||
306 | |||
307 | /* | ||
308 | * The DPAD outputs can't be controlled directly. However, the parallel | ||
309 | * output of the DU channels routed to DPAD can be set to fixed levels | ||
310 | * through the DOFLR group register. Use this to turn the DPAD on or off | ||
311 | * by driving fixed low-level signals at the output of any DU channel | ||
312 | * not routed to a DPAD output. This doesn't affect the DU output | ||
313 | * signals going to other outputs, such as the internal LVDS and HDMI | ||
314 | * encoders. | ||
315 | */ | ||
316 | |||
317 | for (i = 0; i < rgrp->num_crtcs; ++i) { | ||
318 | struct rcar_du_crtc_state *rstate; | ||
319 | struct rcar_du_crtc *rcrtc; | ||
320 | |||
321 | rcrtc = &rcdu->crtcs[rgrp->index * 2 + i]; | ||
322 | rstate = to_rcar_crtc_state(rcrtc->crtc.state); | ||
323 | |||
324 | if (!(rstate->outputs & dpad_mask)) | ||
325 | doflr |= doflr_values[i]; | ||
326 | } | ||
327 | |||
328 | rcar_du_group_write(rgrp, DOFLR, doflr); | ||
329 | } | ||
330 | |||
290 | int rcar_du_group_set_routing(struct rcar_du_group *rgrp) | 331 | int rcar_du_group_set_routing(struct rcar_du_group *rgrp) |
291 | { | 332 | { |
292 | struct rcar_du_device *rcdu = rgrp->dev; | 333 | struct rcar_du_device *rcdu = rgrp->dev; |
@@ -306,5 +347,7 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp) | |||
306 | 347 | ||
307 | rcar_du_group_write(rgrp, DORCR, dorcr); | 348 | rcar_du_group_write(rgrp, DORCR, dorcr); |
308 | 349 | ||
350 | rcar_du_group_set_dpad_levels(rgrp); | ||
351 | |||
309 | return rcar_du_set_dpad0_vsp1_routing(rgrp->dev); | 352 | return rcar_du_set_dpad0_vsp1_routing(rgrp->dev); |
310 | } | 353 | } |