drm/vc4: PV1 can be driven via any HVS channel, so adapt to allow it

It was noted that if PV1 was in use to drive DSI1, then the
writeback connector could not be used as HVS channel 2 was
already in use.
The HVS allows PV1 (HVS output 2) to be driven by any HVS
channel via the DSP3_MUX setting, but that was hardcoded to be
either 2 (for PV1) or disabled for TXP.

Expand the available channels field for PV1, and configure
DSP3_MUX accordingly.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
This commit is contained in:
Dave Stevenson
2025-02-13 11:27:00 +00:00
committed by Dom Cobley
parent 19182c0e58
commit a3212758b7
2 changed files with 16 additions and 15 deletions

View File

@@ -1220,7 +1220,7 @@ const struct vc4_pv_data bcm2835_pv1_data = {
.base = {
.name = "pixelvalve-1",
.debugfs_name = "crtc1_regs",
.hvs_available_channels = BIT(2),
.hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
.hvs_output = 2,
},
.fifo_depth = 64,

View File

@@ -224,12 +224,11 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
u32 dispctrl;
u32 dsp3_mux_pri;
if (!crtc_state->active)
continue;
if (vc4_state->assigned_channel != 2)
if (vc4_crtc->data->hvs_output != 2)
continue;
/*
@@ -237,26 +236,28 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
* FIFO X'.
* SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'.
*
* DSP3 is connected to FIFO2 unless the transposer is
* enabled. In this case, FIFO 2 is directly accessed by the
* TXP IP, and we need to disable the FIFO2 -> pixelvalve1
* route.
* It is more likely that we want the TXP than 3 displays, so
* handle the mapping of DSP3 to any available FIFO.
*
* TXP can also run with a lower panic level than a live display,
* as it doesn't have the same real-time constraint.
*/
dispctrl = HVS_READ(SCALER_DISPCTRL) &
~SCALER_DISPCTRL_PANIC2_MASK;
if (vc4_crtc->feeds_txp) {
dsp3_mux_pri = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
dsp3_mux_pri |= VC4_SET_FIELD(0, SCALER_DISPCTRL_PANIC2);
dispctrl |= VC4_SET_FIELD(0, SCALER_DISPCTRL_PANIC2);
drm_WARN_ON(&vc4->base,
VC4_GET_FIELD(HVS_READ(SCALER_DISPCTRL),
SCALER_DISPCTRL_DSP3_MUX) == 2);
} else {
dsp3_mux_pri = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
dsp3_mux_pri |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
dispctrl |= VC4_SET_FIELD(vc4_state->assigned_channel,
SCALER_DISPCTRL_DSP3_MUX);
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
}
dispctrl = HVS_READ(SCALER_DISPCTRL) &
~(SCALER_DISPCTRL_DSP3_MUX_MASK |
SCALER_DISPCTRL_PANIC2_MASK);
HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux_pri);
HVS_WRITE(SCALER_DISPCTRL, dispctrl);
}
}