Skip to content

Commit 904f668

Browse files
committed
drm/vc4: hdmi: Add a set_timings callback
Similarly to the previous patches, the timings setup in the HDMI controller of the BCM2711 is slightly different, mostly because it supports higher resolutions and thus needed more spaces for the various timings, resulting in the register layout changing. Let's add a callback for that as well. Signed-off-by: Maxime Ripard <[email protected]> Tested-by: Chanwoo Choi <[email protected]> Tested-by: Hoegeun Kwon <[email protected]> Tested-by: Stefan Wahren <[email protected]> Reviewed-by: Dave Stevenson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/0cfcbb379212f90b4abc76c0ccf3b90d1d7c0268.1599120059.git-series.maxime@cerno.tech
1 parent 89f31a2 commit 904f668

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

drivers/gpu/drm/vc4/vc4_hdmi.c

+40-32
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,9 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
369369
HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
370370
}
371371

372-
static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
372+
static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
373+
struct drm_display_mode *mode)
373374
{
374-
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
375-
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
376-
struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
377-
bool debug_dump_regs = false;
378375
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
379376
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
380377
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -392,6 +389,41 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
392389
mode->crtc_vsync_end -
393390
interlaced,
394391
VC4_HDMI_VERTB_VBP));
392+
393+
HDMI_WRITE(HDMI_HORZA,
394+
(vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
395+
(hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
396+
VC4_SET_FIELD(mode->hdisplay * pixel_rep,
397+
VC4_HDMI_HORZA_HAP));
398+
399+
HDMI_WRITE(HDMI_HORZB,
400+
VC4_SET_FIELD((mode->htotal -
401+
mode->hsync_end) * pixel_rep,
402+
VC4_HDMI_HORZB_HBP) |
403+
VC4_SET_FIELD((mode->hsync_end -
404+
mode->hsync_start) * pixel_rep,
405+
VC4_HDMI_HORZB_HSP) |
406+
VC4_SET_FIELD((mode->hsync_start -
407+
mode->hdisplay) * pixel_rep,
408+
VC4_HDMI_HORZB_HFP));
409+
410+
HDMI_WRITE(HDMI_VERTA0, verta);
411+
HDMI_WRITE(HDMI_VERTA1, verta);
412+
413+
HDMI_WRITE(HDMI_VERTB0, vertb_even);
414+
HDMI_WRITE(HDMI_VERTB1, vertb);
415+
416+
HDMI_WRITE(HDMI_VID_CTL,
417+
(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
418+
(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
419+
}
420+
421+
static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
422+
{
423+
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
424+
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
425+
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
426+
bool debug_dump_regs = false;
395427
int ret;
396428

397429
ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
@@ -435,33 +467,8 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
435467
VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
436468
VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
437469

438-
HDMI_WRITE(HDMI_HORZA,
439-
(vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
440-
(hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
441-
VC4_SET_FIELD(mode->hdisplay * pixel_rep,
442-
VC4_HDMI_HORZA_HAP));
443-
444-
HDMI_WRITE(HDMI_HORZB,
445-
VC4_SET_FIELD((mode->htotal -
446-
mode->hsync_end) * pixel_rep,
447-
VC4_HDMI_HORZB_HBP) |
448-
VC4_SET_FIELD((mode->hsync_end -
449-
mode->hsync_start) * pixel_rep,
450-
VC4_HDMI_HORZB_HSP) |
451-
VC4_SET_FIELD((mode->hsync_start -
452-
mode->hdisplay) * pixel_rep,
453-
VC4_HDMI_HORZB_HFP));
454-
455-
HDMI_WRITE(HDMI_VERTA0, verta);
456-
HDMI_WRITE(HDMI_VERTA1, verta);
457-
458-
HDMI_WRITE(HDMI_VERTB0, vertb_even);
459-
HDMI_WRITE(HDMI_VERTB1, vertb);
460-
461-
HDMI_WRITE(HDMI_VID_CTL,
462-
(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
463-
(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
464-
470+
if (vc4_hdmi->variant->set_timings)
471+
vc4_hdmi->variant->set_timings(vc4_hdmi, mode);
465472

466473
if (vc4_encoder->hdmi_monitor &&
467474
drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
@@ -1445,6 +1452,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
14451452
.init_resources = vc4_hdmi_init_resources,
14461453
.csc_setup = vc4_hdmi_csc_setup,
14471454
.reset = vc4_hdmi_reset,
1455+
.set_timings = vc4_hdmi_set_timings,
14481456
.phy_init = vc4_hdmi_phy_init,
14491457
.phy_disable = vc4_hdmi_phy_disable,
14501458
.phy_rng_enable = vc4_hdmi_phy_rng_enable,

drivers/gpu/drm/vc4/vc4_hdmi.h

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ struct vc4_hdmi_variant {
4444
/* Callback to enable / disable the CSC */
4545
void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
4646

47+
/* Callback to configure the video timings in the HDMI block */
48+
void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
49+
struct drm_display_mode *mode);
50+
4751
/* Callback to initialize the PHY according to the mode */
4852
void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
4953
struct drm_display_mode *mode);

0 commit comments

Comments
 (0)