Skip to content

Commit

Permalink
drm/vc4: Disable the 2pixel/clock odd timings workaround for interlaced
Browse files Browse the repository at this point in the history
Whilst BCM2712 does fix using odd horizontal timings, it doesn't
work with interlaced modes.

Drop the workaround for interlaced modes and revert to the same
behaviour as BCM2711.

raspberrypi#6281

Signed-off-by: Dave Stevenson <[email protected]>
  • Loading branch information
popcornmix authored and 6by9 committed Dec 4, 2024
1 parent e651829 commit bbc9361
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
20 changes: 17 additions & 3 deletions drivers/gpu/drm/vc4/vc4_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,9 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
u8 ppc = pv_data->pixels_per_clock;
u8 ppc = (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
pv_data->pixels_per_clock_int :
pv_data->pixels_per_clock;

u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
Expand Down Expand Up @@ -426,7 +428,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
*/
CRTC_WRITE(PV_V_CONTROL,
PV_VCONTROL_CONTINUOUS |
(vc4->gen >= VC4_GEN_6_C ? PV_VCONTROL_ODD_TIMING : 0) |
(vc4->gen >= VC4_GEN_6_C && ppc == 1 ?
PV_VCONTROL_ODD_TIMING : 0) |
(is_dsi ? PV_VCONTROL_DSI : 0) |
PV_VCONTROL_INTERLACE |
(odd_field_first
Expand All @@ -438,7 +441,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
} else {
CRTC_WRITE(PV_V_CONTROL,
PV_VCONTROL_CONTINUOUS |
(vc4->gen >= VC4_GEN_6_C ? PV_VCONTROL_ODD_TIMING : 0) |
(vc4->gen >= VC4_GEN_6_C && ppc == 1 ?
PV_VCONTROL_ODD_TIMING : 0) |
(is_dsi ? PV_VCONTROL_DSI : 0));
CRTC_WRITE(PV_VSYNCD_EVEN, 0);
}
Expand Down Expand Up @@ -1208,6 +1212,7 @@ const struct vc4_pv_data bcm2835_pv0_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
Expand All @@ -1223,6 +1228,7 @@ const struct vc4_pv_data bcm2835_pv1_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
Expand All @@ -1238,6 +1244,7 @@ const struct vc4_pv_data bcm2835_pv2_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
[PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
Expand All @@ -1253,6 +1260,7 @@ const struct vc4_pv_data bcm2711_pv0_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_DSI0,
[1] = VC4_ENCODER_TYPE_DPI,
Expand All @@ -1268,6 +1276,7 @@ const struct vc4_pv_data bcm2711_pv1_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_DSI1,
[1] = VC4_ENCODER_TYPE_SMI,
Expand All @@ -1283,6 +1292,7 @@ const struct vc4_pv_data bcm2711_pv2_data = {
},
.fifo_depth = 256,
.pixels_per_clock = 2,
.pixels_per_clock_int = 2,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_HDMI0,
},
Expand All @@ -1297,6 +1307,7 @@ const struct vc4_pv_data bcm2711_pv3_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
},
Expand All @@ -1311,6 +1322,7 @@ const struct vc4_pv_data bcm2711_pv4_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 2,
.pixels_per_clock_int = 2,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_HDMI1,
},
Expand All @@ -1324,6 +1336,7 @@ const struct vc4_pv_data bcm2712_pv0_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 2,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_HDMI0,
},
Expand All @@ -1337,6 +1350,7 @@ const struct vc4_pv_data bcm2712_pv1_data = {
},
.fifo_depth = 64,
.pixels_per_clock = 1,
.pixels_per_clock_int = 2,
.encoder_types = {
[0] = VC4_ENCODER_TYPE_HDMI1,
},
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/vc4/vc4_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ struct vc4_pv_data {

/* Number of pixels output per clock period */
u8 pixels_per_clock;
/* Number of pixels output per clock period when in an interlaced mode */
u8 pixels_per_clock_int;

enum vc4_encoder_type encoder_types[4];
};
Expand Down
8 changes: 7 additions & 1 deletion drivers/gpu/drm/vc4/vc4_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,9 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
unsigned long long tmds_char_rate = mode->clock * 1000;
unsigned long long tmds_bit_rate;

if (vc4_hdmi->variant->unsupported_odd_h_timings) {
if (vc4_hdmi->variant->unsupported_odd_h_timings ||
(vc4_hdmi->variant->unsupported_int_odd_h_timings &&
(mode->flags & DRM_MODE_FLAG_INTERLACE))) {
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
/* Only try to fixup DBLCLK modes to get 480i and 576i
* working.
Expand Down Expand Up @@ -3481,6 +3483,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
PHY_LANE_CK,
},
.unsupported_odd_h_timings = true,
.unsupported_int_odd_h_timings = true,
.external_irq_controller = true,

.init_resources = vc5_hdmi_init_resources,
Expand Down Expand Up @@ -3510,6 +3513,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
PHY_LANE_2,
},
.unsupported_odd_h_timings = true,
.unsupported_int_odd_h_timings = true,
.external_irq_controller = true,

.init_resources = vc5_hdmi_init_resources,
Expand Down Expand Up @@ -3539,6 +3543,7 @@ static const struct vc4_hdmi_variant bcm2712_hdmi0_variant = {
PHY_LANE_CK,
},
.unsupported_odd_h_timings = false,
.unsupported_int_odd_h_timings = true,
.external_irq_controller = true,

.init_resources = vc5_hdmi_init_resources,
Expand Down Expand Up @@ -3566,6 +3571,7 @@ static const struct vc4_hdmi_variant bcm2712_hdmi1_variant = {
PHY_LANE_CK,
},
.unsupported_odd_h_timings = false,
.unsupported_int_odd_h_timings = true,
.external_irq_controller = true,

.init_resources = vc5_hdmi_init_resources,
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/vc4/vc4_hdmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ struct vc4_hdmi_variant {

/* The BCM2711 cannot deal with odd horizontal pixel timings */
bool unsupported_odd_h_timings;
/* The BCM2712 can handle odd horizontal pixel timings, but not in
* interlaced modes
*/
bool unsupported_int_odd_h_timings;

/*
* The BCM2711 CEC/hotplug IRQ controller is shared between the
Expand Down

0 comments on commit bbc9361

Please sign in to comment.