diff --git a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c index 830deb45f30903..9408e2549daf0c 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c +++ b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c @@ -91,7 +91,7 @@ static const struct encoder_constraint vc4_encoder_constraints[] = { ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 1), ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_VEC, 1), ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP0, 2), - ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 2), + ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 0, 1, 2), }; static const struct encoder_constraint vc5_encoder_constraints[] = { @@ -258,6 +258,9 @@ static const struct pv_muxing_param vc4_test_pv_muxing_params[] = { VC4_PV_MUXING_TEST("2 outputs: VEC, DSI1", VC4_ENCODER_TYPE_VEC, VC4_ENCODER_TYPE_DSI1), + VC4_PV_MUXING_TEST("2 outputs: TXP, DSI1", + VC4_ENCODER_TYPE_TXP0, + VC4_ENCODER_TYPE_DSI1), VC4_PV_MUXING_TEST("2 outputs: VEC, TXP", VC4_ENCODER_TYPE_VEC, VC4_ENCODER_TYPE_TXP0), @@ -293,6 +296,22 @@ static const struct pv_muxing_param vc4_test_pv_muxing_params[] = { VC4_ENCODER_TYPE_DPI, VC4_ENCODER_TYPE_VEC, VC4_ENCODER_TYPE_TXP0), + VC4_PV_MUXING_TEST("3 outputs: DSI1, HDMI, TXP", + VC4_ENCODER_TYPE_DSI1, + VC4_ENCODER_TYPE_HDMI0, + VC4_ENCODER_TYPE_TXP0), + VC4_PV_MUXING_TEST("3 outputs: DSI1, VEC, TXP", + VC4_ENCODER_TYPE_DSI1, + VC4_ENCODER_TYPE_VEC, + VC4_ENCODER_TYPE_TXP0), + VC4_PV_MUXING_TEST("3 outputs: DSI1, DPI, TXP", + VC4_ENCODER_TYPE_DSI1, + VC4_ENCODER_TYPE_DPI, + VC4_ENCODER_TYPE_TXP0), + VC4_PV_MUXING_TEST("3 outputs: DSI1, DSI0, TXP", + VC4_ENCODER_TYPE_DSI1, + VC4_ENCODER_TYPE_DSI0, + VC4_ENCODER_TYPE_TXP0), }; KUNIT_ARRAY_PARAM(vc4_test_pv_muxing, @@ -303,9 +322,6 @@ static const struct pv_muxing_param vc4_test_pv_muxing_invalid_params[] = { VC4_PV_MUXING_TEST("DPI/DSI0 Conflict", VC4_ENCODER_TYPE_DPI, VC4_ENCODER_TYPE_DSI0), - VC4_PV_MUXING_TEST("TXP/DSI1 Conflict", - VC4_ENCODER_TYPE_TXP0, - VC4_ENCODER_TYPE_DSI1), VC4_PV_MUXING_TEST("HDMI0/VEC Conflict", VC4_ENCODER_TYPE_HDMI0, VC4_ENCODER_TYPE_VEC), diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 046b50b766a083..307a533136692c 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1223,7 +1223,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, diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index ffe84025843eed..2e6ae0d04518c3 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -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); } }