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);
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,
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 |
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,
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) |
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);
# 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)