128 lines
4.9 KiB
Diff
128 lines
4.9 KiB
Diff
|
From 184580ac95b7fa05eaf5ee16393ddd6103493d0a Mon Sep 17 00:00:00 2001
|
||
|
From: Eric Anholt <eric@anholt.net>
|
||
|
Date: Wed, 28 Sep 2016 19:01:48 -0700
|
||
|
Subject: [PATCH] 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>
|
||
|
---
|
||
|
drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++------
|
||
|
drivers/gpu/drm/vc4/vc4_hdmi.c | 16 +++++++++++-----
|
||
|
drivers/gpu/drm/vc4/vc4_regs.h | 2 ++
|
||
|
3 files changed, 24 insertions(+), 11 deletions(-)
|
||
|
|
||
|
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
|
||
|
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
|
||
|
@@ -371,6 +371,7 @@ static void vc4_crtc_mode_set_nofb(struc
|
||
|
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) {
|
||
|
@@ -384,14 +385,17 @@ static void vc4_crtc_mode_set_nofb(struc
|
||
|
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,
|
||
|
@@ -426,7 +430,7 @@ static void vc4_crtc_mode_set_nofb(struc
|
||
|
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 {
|
||
|
@@ -435,12 +439,13 @@ static void vc4_crtc_mode_set_nofb(struc
|
||
|
(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 |
|
||
|
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||
|
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||
|
@@ -411,6 +411,7 @@ static void vc4_hdmi_encoder_mode_set(st
|
||
|
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,
|
||
|
@@ -433,7 +434,8 @@ static void vc4_hdmi_encoder_mode_set(st
|
||
|
|
||
|
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) |
|
||
|
@@ -443,14 +445,18 @@ static void vc4_hdmi_encoder_mode_set(st
|
||
|
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);
|
||
|
--- a/drivers/gpu/drm/vc4/vc4_regs.h
|
||
|
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
|
||
|
@@ -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)
|