aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vc4/vc4_crtc.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-09-29 15:34:44 -0700
committerEric Anholt <eric@anholt.net>2016-10-06 11:58:28 -0700
commitdfccd937deec9283d6ced73e138808e62bec54e8 (patch)
tree546c4042707df9cbbcc2c4c2dcf446dd03758d4c /drivers/gpu/drm/vc4/vc4_crtc.c
parentdrm/vc4: Set up the AVI and SPD infoframes. (diff)
downloadlinux-dev-dfccd937deec9283d6ced73e138808e62bec54e8.tar.xz
linux-dev-dfccd937deec9283d6ced73e138808e62bec54e8.zip
drm/vc4: Add support for double-clocked modes.
Now that we have infoframes to report the pixel repeat flag, we can start using it. Fixes locking the 720x480i and 720x576i modes on my Dell 2408WFP. Like the 1920x1080i case, they don't fit properly on the screen, though. Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_crtc.c')
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 83cafea03eff..7f08d681a74b 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -378,6 +378,7 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct drm_crtc_state *state = crtc->state;
struct drm_display_mode *mode = &state->adjusted_mode;
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+ u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
u32 format = PV_CONTROL_FORMAT_24;
bool debug_dump_regs = false;
int clock_select = vc4_get_clock_select(crtc);
@@ -393,14 +394,17 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
CRTC_WRITE(PV_CONTROL, 0);
CRTC_WRITE(PV_HORZA,
- VC4_SET_FIELD(mode->htotal - mode->hsync_end,
+ VC4_SET_FIELD((mode->htotal -
+ mode->hsync_end) * pixel_rep,
PV_HORZA_HBP) |
- VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
+ VC4_SET_FIELD((mode->hsync_end -
+ mode->hsync_start) * pixel_rep,
PV_HORZA_HSYNC));
CRTC_WRITE(PV_HORZB,
- VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
+ VC4_SET_FIELD((mode->hsync_start -
+ mode->hdisplay) * pixel_rep,
PV_HORZB_HFP) |
- VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
+ VC4_SET_FIELD(mode->hdisplay * pixel_rep, PV_HORZB_HACTIVE));
CRTC_WRITE(PV_VERTA,
VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
@@ -434,20 +438,21 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
CRTC_WRITE(PV_V_CONTROL,
PV_VCONTROL_CONTINUOUS |
PV_VCONTROL_INTERLACE |
- VC4_SET_FIELD(mode->htotal / 2,
+ VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
PV_VCONTROL_ODD_DELAY));
CRTC_WRITE(PV_VSYNCD_EVEN, 0);
} else {
CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
}
- CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
+ CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
CRTC_WRITE(PV_CONTROL,
VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
VC4_SET_FIELD(vc4_get_fifo_full_level(format),
PV_CONTROL_FIFO_LEVEL) |
+ VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
PV_CONTROL_CLR_AT_START |
PV_CONTROL_TRIGGER_UNDERFLOW |
PV_CONTROL_WAIT_HSTART |