Due to an influx of spam, we have had to impose restrictions on new accounts. Please see this wiki page for instructions on how to get full permissions. Sorry for the inconvenience.
Admin message
The migration is almost done, at least the rest should happen in the background. There are still a few technical difference between the old cluster and the new ones, and they are summarized in this issue. Please pay attention to the TL:DR at the end of the comment.
SC7180: Color Transform Matrix breaks after suspend
on sc7180, Color Transform Matrix support breaks after suspending and resuming the device. Before and after suspend, drm_info shows that the CTM is correctly set (non-null CTM blob). Even when changing the CTM settings after resume, they no longer take any effect. Completely disabling the display This issue can be reproduced with both stable kernel 6.0.12 and the latest v6.1 branch.
One trick to get the CTM to be applied again is to disable the display (close laptop screen) while an external monitor is connected, then re-enable the display (open the laptop screen again) and disconnect the external monitor.
Not sure if it helps, but attached is a full dmesg log with DRM debug enabled. System suspends at 167.267821. Color Transform Matrix works before the suspend but no longer after resume: dmesg-ctm-bug.txt
Edited
Designs
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related.
Learn more.
Our QA team could not recreate this with the sc7180 chromebook with 5.15 kernel as most of our internal software builds are still using that kernel for sc7180.
So perhaps something got broken between 5.15 and 6.x kernels.
We will have to check with the latest kernels what got broken now.
could be a difference between suspend-to-idle vs suspend-to-ram (or whatever "deep suspend" means)? IIRC on CrOS s2idle is used, at least for arm64, but distros may be using suspend-to-ram instead (because apparently s2idle draws a lot more power on x86?)
Thank you @jesszhan@abhinavk@robclark. I was able to confirm that the issue also happens with s2idle. However, it only happens if an external display is connected. If no external display is connected, Color Transform Matrix does NOT break after deep suspend nor after s2idle suspend.
Disconnecting the external display after the suspend, unsuspend cycle does not restore Color Transform Matrix functionality. The only way to restore the functionality without reboot appears to be the trick described in the Overview: "One trick to get the CTM to be applied again is to disable the display (close laptop screen) while an external monitor is connected, then re-enable the display (open the laptop screen again) and disconnect the external monitor."
@jesszhan@abhinavk@robclark the external monitor issue may be more complicated. But I've also noticed a problem for the case without any external monitors. In that case, CTM is simply no longer applied after suspend / wake-up cycle. Only if user modifies CTM setting, CTM starts being applied again. As example, see below log output. CTM is set to blob=79 before the suspend, which applies a night light effect. After suspend and resume, CTM blob remains unchanged but the night light effect disappears, meaning that the driver/msm no longer applies CTM. Upon changing the CTM in GUI Settings, it is being applied again.
I presume that ChromeOS works around this kernel bug by always re-applying / modifying CTM settings after system wakup @robclark?
@leezu could you please check, if you remove the if (!state->color_mgmt_changed) return; from _dpu_crtc_setup_cp_blocks, will the CTM be applied after resume?
thank you! Rebuilding with below patch resolves the issue for the single monitor setting. I do not have the external display handy before the second week of January, so I will report on the effect in the external display later.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.cindex 13ce321283ff..269eff899901 100644--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c@@ -747,10 +747,6 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) struct dpu_hw_dspp *dspp; int i;-- if (!state->color_mgmt_changed)- return;- for (i = 0; i < cstate->num_mixers; i++) { ctl = mixer[i].lm_ctl; dspp = mixer[i].hw_dspp;
@abhinavk@robclark short summary of my understanding of the issue. The driver expects that the hw_dspp state is corectly cached, thus the DSPP is reprogrammed only if there was a change in one of color management properties. However during suspend/resume the hardware state of DSPP is lost. As there was no change in props, corresponding flag is not set, so DSPP is not reprogrammed.
I think the easiest way to fix the issue is to force color_mgmt_changed flag in the suspended state before calling resume functions. WDYT?
If you agree with my analisys, could you please send corresponding patch?
I was able to recreate the issue on SC7180, but I had some doubts about the proposed fix. Should it be up to drivers to dictate what the state of a property should be after a resume? And aren't there some cases where CTM shouldn't be applied after a resume?
For example, if we end up resuming with a different state where CTM wasn't previously applied, wouldn't reapplying CTM after resume be wrong?
FWIW, I looked for examples of this from other drivers and wasn't able to find examples other drivers implementing a similar fix.
The atomic state should be applied (if the state is lost by the hw) across s/r.. it is an implementation detail of the hw whether the state needs to be reprogrammed after resume. Ie. if it is still showing up in /sys/kernel/debug/dri/0/state then the hw state should reflect that.
I was thinking a bit more about it. Rather than touching the color_mgmt_changed flag which is controlled by UAPI, I feel that below change should be better because we will be programming the CP blocks even if active_changed.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.cindex 13ce321283ff..36d09ba8f757 100644--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) int i;- if (!state->color_mgmt_changed)+ if (!state->color_mgmt_changed && !state->active_changed) return; for (i = 0; i < cstate->num_mixers; i++) {
Just to note. We are reaquiring the DSPPs in dpu_encoder_virt_atomic_check if drm_atomic_crtc_needs_modeset(). Thus even if color_mgmt (or active) wasn't changed the backing DSPP unit might change. I think we'd better use drm_atomic_crtc_needs_modeset() here in addition to color_mgmt_changed.
BTW: what is the cost of DSPP reprogramming flush? Is it something noticeable?
@abhinavk I was asking to understand if the if (color_management_changed) condition makes any sense at all. In other words, if we remove it and measure power consumption, can we notice the difference?
@lumag We need to investigate the power consumption angle but its not just the flush. The CTM matrix also gets reprogrammed every frame if we do that. Dont think its a good idea.
Meanwhile, @leezu can you please check if below change helps for this issue?
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.cindex 13ce321283ff..c745471c1901 100644--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) int i;- if (!state->color_mgmt_changed)+ if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state)) return; for (i = 0; i < cstate->num_mixers; i++) {