Skip to content

Commit

Permalink
drm/vc4: Add support for double-clocked modes.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
anholt authored and pelwell committed Oct 7, 2016
1 parent 367d89d commit 4124cdb
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
17 changes: 11 additions & 6 deletions drivers/gpu/drm/vc4/vc4_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
bool debug_dump_regs = false;

if (debug_dump_regs) {
Expand All @@ -384,14 +385,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,
Expand Down Expand Up @@ -426,7 +430,7 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
PV_VCONTROL_CONTINUOUS |
(is_dsi ? PV_VCONTROL_DSI : 0) |
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 {
Expand All @@ -435,12 +439,13 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
(is_dsi ? PV_VCONTROL_DSI : 0));
}

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 |
Expand Down
16 changes: 11 additions & 5 deletions drivers/gpu/drm/vc4/vc4_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
VC4_HDMI_VERTA_VSP) |
VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
Expand All @@ -433,7 +434,8 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,

HD_WRITE(VC4_HD_VID_CTL, 0);

clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000);
clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000 *
((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));

HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
Expand All @@ -443,14 +445,18 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
HDMI_WRITE(VC4_HDMI_HORZA,
(vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
(hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
VC4_SET_FIELD(mode->hdisplay * pixel_rep,
VC4_HDMI_HORZA_HAP));

HDMI_WRITE(VC4_HDMI_HORZB,
VC4_SET_FIELD(mode->htotal - mode->hsync_end,
VC4_SET_FIELD((mode->htotal -
mode->hsync_end) * pixel_rep,
VC4_HDMI_HORZB_HBP) |
VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
VC4_SET_FIELD((mode->hsync_end -
mode->hsync_start) * pixel_rep,
VC4_HDMI_HORZB_HSP) |
VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
VC4_SET_FIELD((mode->hsync_start -
mode->hdisplay) * pixel_rep,
VC4_HDMI_HORZB_HFP));

HDMI_WRITE(VC4_HDMI_VERTA0, verta);
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/vc4/vc4_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@
# define PV_CONTROL_CLR_AT_START BIT(14)
# define PV_CONTROL_TRIGGER_UNDERFLOW BIT(13)
# define PV_CONTROL_WAIT_HSTART BIT(12)
# define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
# define PV_CONTROL_PIXEL_REP_SHIFT 4
# define PV_CONTROL_CLK_SELECT_DSI_VEC 0
# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1
# define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2)
Expand Down

0 comments on commit 4124cdb

Please sign in to comment.