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.
"README.md" did not exist on "50ee4a6fe3529fc98820f466ec6000aa333a4539"
As requested by @abhinavk in #34 (comment 2087098), here's an issue to track the progress around supporting DSC on bonded DSI (2:2:2 toplogy).
This is on the Sony Xperia 1 III (sm8350-sony-xperia-sagami-pdx215.dts) with ana6707_amb650yl01 panel. It hosts 4 modes, 1644x3840 and 1096x2560 resolutions, both at 60 and 120Hz refresh rate. 1096x2560@60 is used in the dumps below.
Only the left encoder seems to emit data, the right side of the panel remains static and corrupted;
Every 5th-or-so slice seems to be interpreted correctly by the panel and shows readable framebuffer consle.
For this to work many kernel changes are needed that I am working towards upstreaming, as long as we can figure out this last issue which is likely a misconfiguration of the DSC or DSI block(s). They are spread far and wide on a massive development branch, but according to @abhinav there was no need to spend time sorting these out and pointing to a clean branch containing them. Instead, if someone (from Qcom) can help me validate and hopefully pin-point a register issue in the provided devcoredump, I will work towards cleaning, publishing and upstreaming these patches. The current work-in-progress is available at https://github.com/somainline/linux/commits/marijn/panel-exclusives.
Non-exhaustive list of what has already been done to support DSC on dual-DSI:
Better support for active-CTL (both architectural as well as register programming), which is a combination of my changes on top of those from @lumag;
Replacement of hardcoded 2:2:1 topology codepaths to also support this 2:2:2 topology (and 1:1:1 for e.g. the FairPhone 5 that @lucaweiss is working on);
Proper disablement of DSC multiplex mode (while retaining split-panel) when using bonded-DSI with multiple DSC encoders;
Boilerplate to support passing only half the (DSC) width to both DSI encoders, so that their math for clocks and number of slices/pixels to send remains correct.
For example, over the width of this panel 1096 pixels are sent in two slices. However, because there are two encoders, both panels only see 512 pixels with a slice width of 1 (this has been confirmed with a downstream kernel).
Edited
Designs
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related.
Learn more.
I've played with Xiaomi Mi Pad 6 's dual-dsi + dsc panel and got similar results lolThe only difference was that I was getting regularly correctly parsed slice data on both halfs of the display. Unfortunately I couldn't get any further either.
Edit: This is a video panel BTW, not a command mode one
Sorry for the lack of updates -- finally was able to set aside some time this week to take a look at the dumps.
I'm working on confirming the DSC register configuration with downstream. In the mean time, can you share a hex dump of the PPS being sent from your panel driver?
Hi @jesszhan, glad to hear that this is being picked up! If it wasn't for the somewhat unnecessary "bump" message above I wouldn't have seen this, as there was no notification for your first reply.
I had forgotten to mention that I've pushed all the commits needed to get this far, which I will send upstream once we've found the final issue and confirmed this is all working:
Hi @jesszhan, this was a test that turned out not to make a difference.
The value used downstream (where this topology is fully working) is 3, and mainline (dpu_encoder_dsc_initial_line_calc()) was returning some other value (I don't remember what, maybe it was 2).
@MarijnS95 , got it. So far I'm not seeing any issues with the register dump, but it looks like you're hardcoding your pclk and byte clk rates based on the uncompressed clock rate from DT.
Can you try using the following compressed clock values and let me know if that fixes anything?
@jesszhan with that hardcoding many clock values have been tried, including those calculated downstream and calculated manually. Clocks close to the values you suggest have also been tried, and even exactly the ones you suggest. Unfortunately they make no difference to the output.
Found the golden egg during Easter today: after long debugging sessions, this is all that was needed on top of the previous state to get dual-DSI dual-DSC working properly without corruption:
While on a random tour through DPU I found that strangely INTF_3 (the slave DSI interface on my configuration) is never flushed, though it definitely writes registers that should be applied. This fixed all the corruption and timeouts/errors in dmesg, but as before only the left side of the panel was working. After a lot of random trial-and-error, leaving DSI1 PHY clocks to use the entire DSI1 PLL tree leading up all the way to DSI1 VCO, instead of parenting off of DSI0 clocks makes the right panel show output too.
This is not a proper fix and likely amounts to a missing flag in dispcc, as having the whole DSI1 clock tree generating the same frequency (possibly at a different phase?) as DSI0 is unnecessarily wasting power.
I've already compared the clock trees downstream and upstream (before and after this change) and don't see anything out of the ordinary.
I'll work on pushing the patches for this to the aforementioned branch as soon as possible, as well as clean them up in some soon-ish™ time frame to be upstreamable.
Another weird thing that I have been unable to explain (why downstream doesn't suffer). For 1096x2560@60Hz there is a corrupted line at the top of the screen, and a video recording shows clearly that it's a tear (above the line displays an earlier or later frame than below):
It's a strange number since this mode has nothing to do with the 3840 mode. Calling this function with 0 for every mode immediately gets rid of this corruption
Since PPSPLIT support was stripped out of the upstream DPU driver when it was submitted, this should have become if (false && !is_master) goto skip;, thus never skipping the flush. However, the if was erroneously modified by removing the false && bit (as shown in the diff above), thus always skipping the flush for the slave, which is wrong.
I'll send a patch shortly to address this.
Reparenting DSI1 clocks to DSI0 tree breaks
Here's a clk_summary diff from having assigned-clock-parents (the case that breaks with colorful corruption) to having a duplicated clocktree:
The problem is understood now, but a clean solution hasn't emerged yet. @lumag helpfully pointed me to dsi_7nm_set_usecase() which after some debugging shows that it was setting the MASTER configuration on both PLLs, maybe causing the PLL/MUX to not source from the right parent (even though the dispcc clocks have their own muxes for this).
It's not yet understood why debugcc measured a clock signal on all children from this PLL.
This seems really terrible and I wish we could just use the clock API to tell us what our parent is, to configure this what is effectively a mux? Instead of having dsi_manager push about global state :(
What seems to happen is that msm_dsi_host_register() enables and configures the PLL via dsi_7nm_set_usecase(), before we push the global state onto it via msm_dsi_phy_set_usecase(), so simply flipping that logic is enough:
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.cindex f7a9554c17d8..2beb742f85a3 100644--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c@@ -81,6 +83,12 @@ static int dsi_mgr_setup_components(int id) msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE); msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy); } else if (other_dsi) {+ /* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */+ msm_dsi_phy_set_usecase(clk_master_dsi->phy,+ MSM_DSI_PHY_MASTER);+ msm_dsi_phy_set_usecase(clk_slave_dsi->phy,+ MSM_DSI_PHY_SLAVE);+ struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ? msm_dsi : other_dsi; struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?@@ -100,10 +109,6 @@ static int dsi_mgr_setup_components(int id) return ret; /* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */- msm_dsi_phy_set_usecase(clk_master_dsi->phy,- MSM_DSI_PHY_MASTER);- msm_dsi_phy_set_usecase(clk_slave_dsi->phy,- MSM_DSI_PHY_SLAVE); msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy); msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy); }
Thanks @MarijnS95 for the updates. I will review your series.
Regarding #41 (comment 2375636), I actually checked this flow to make sure one was master and the other was slave. But I didnt follow why you had to move those two lines?
msm_dsi_host_register() is not enabling phy. msm_dsi_phy_enable() does that.
Even from the register dumps,
====================dsi0_phy================
0x0 : 00000024 00000000 00000000 00000000
0x10 : 00000061 00000030 00000000 00000000
reg 0x14 is 30 for DSI0, which means internal PLL
====================dsi1_phy================
0x0 : 00000024 00000000 00000000 00000000
0x10 : 000000f1 00000034 00000000 00000000
for dsi1_phy, reg 0x14 is 0x34 which is external PLL
Hi @abhinavk, thanks for the quick reply. Looking forward to the review, and hope you notice that the cover letter explains that I'm not sure what is up with the diff proposed above, as it doesn't seem like a very clean solution, and is mostly "RFC". You'll also notice that I point out that perhaps something is wrong with the panel driver and/or path around it.
Feel free to reply that directly under the right thread to keep conversations segregated :)
I actually checked this flow to make sure one was master and the other was slave. But I didnt follow why you had to move those two lines?
msm_dsi_host_register() is not enabling phy. msm_dsi_phy_enable() does that.
Even from the register dumps,
[..]
for dsi1_phy, reg 0x14 is 0x34 which is external PLL
So this matches the code
Thanks for doing the archaeology, I hadn't known that it was set correctly before. So perhaps, if I had found the missing slave intf flush issue sooner, this might not have been a problem yet, and is the result of more recent changes "somewhere"?
Debug logging pointed out to me that the flow was as follows:
dsi_mgr_setup_components()
msm_dsi_host_register()
dsi_7nm_phy_enable() -> dsi_7nm_set_usecase(), with "internal" for both PLLs.
msm_dsi_phy_set_usecase(), which is too late at this point
But what better way to show that with a backtrace (which I should have included in the patch/cover letter). Here you can clearly see a flow that goes from msm_dsi_manager_register() all the way down through the panel driver attaching a DSI host, and ultimately resulting in a commit from the framebuffer and calling dsi_7nm_phy_enable(). Again, before msm_dsi_phy_set_usecase() was called: