Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRM Writeback connector priority changes #6345

Open
wants to merge 2 commits into
base: rpi-6.6.y
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions drivers/gpu/drm/vc4/vc4_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ 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;
u32 dsp3_mux_pri;

if (!crtc_state->active)
continue;
Expand All @@ -241,15 +241,22 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
* enabled. In this case, FIFO 2 is directly accessed by the
* TXP IP, and we need to disable the FIFO2 -> pixelvalve1
* route.
*
* TXP can also run with a lower panic level than a live display,
* as it doesn't have the same real-time constraint.
*/
if (vc4_crtc->feeds_txp)
dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
else
dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
if (vc4_crtc->feeds_txp) {
dsp3_mux_pri = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
dsp3_mux_pri |= VC4_SET_FIELD(1, SCALER_DISPCTRL_PANIC2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for this being 1 (Use panic mode for first two of the frame or if empty) rather than 0 (Fixed priority of 2’b00 (never panic).) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from the firmware (middleware/hvs/hvs.c)

   static const uint32_t priority_0 = 0x2;  // panic when <2 lines in FIFO
   static const uint32_t priority_1 = 0x2;  // panic when <2 lines in FIFO
   static const uint32_t priority_2 = 0x1;  // raised but no panic

If you think we can work with never panic, then I'm happy to switch it to that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full options are:

0 = Fixed priority of 2’b00 (never panic).
1 = Use panic mode for first two of the frame or if empty.
2 = Use panic mode whenever less than two complete lines in FIFO.
3 = Fixed priority of 2’b11 (always panic).

I don't see this as real time, so I don't think it needs to panic ever.

But there could be a concern that a non-panicking memory access from a plane being fetched for writeback will hold up a following panicking access from a plane needed by HDMI, effectively killing it's priority (I don't believe there's any way to overtake).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know very little on how the AXI priorities are going to interact, hence just copying the firmware settings.

Happy to take guidance on which to use.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think logically 0 (never panic) makes sense - we are not real time when writing back, and don't want to interfere with actual real time masters like camera.

If we see the theoretical issue of low priority writeback accesses holding off subsequent high priority accesses needed by hdmi, then we can revisit (it will likely have to be the same as hdmi priority) - but I have no evidence of that actually occurring.

So, I'd recommend 0 for this PR.

} else {
dsp3_mux_pri = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
dsp3_mux_pri |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
}

dispctrl = HVS_READ(SCALER_DISPCTRL) &
~SCALER_DISPCTRL_DSP3_MUX_MASK;
HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux);
~(SCALER_DISPCTRL_DSP3_MUX_MASK |
SCALER_DISPCTRL_PANIC2_MASK);
HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux_pri);
}
}

Expand Down Expand Up @@ -674,17 +681,26 @@ static int vc4_load_tracker_atomic_check(struct drm_atomic_state *state)
for_each_oldnew_plane_in_state(state, plane, old_plane_state,
new_plane_state, i) {
struct vc4_plane_state *vc4_plane_state;
struct vc4_crtc *vc4_crtc;

if (old_plane_state->fb && old_plane_state->crtc) {
vc4_plane_state = to_vc4_plane_state(old_plane_state);
load_state->membus_load -= vc4_plane_state->membus_load;
load_state->hvs_load -= vc4_plane_state->hvs_load;
vc4_crtc = to_vc4_crtc(old_plane_state->crtc);

if (!vc4_crtc->feeds_txp) {
load_state->membus_load -= vc4_plane_state->membus_load;
load_state->hvs_load -= vc4_plane_state->hvs_load;
}
}

if (new_plane_state->fb && new_plane_state->crtc) {
vc4_plane_state = to_vc4_plane_state(new_plane_state);
load_state->membus_load += vc4_plane_state->membus_load;
load_state->hvs_load += vc4_plane_state->hvs_load;
vc4_crtc = to_vc4_crtc(new_plane_state->crtc);

if (!vc4_crtc->feeds_txp) {
load_state->membus_load += vc4_plane_state->membus_load;
load_state->hvs_load += vc4_plane_state->hvs_load;
}
}
}

Expand Down