From: Chris Morgan <hidden> Date: 2021-09-08 13:54:13
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
Signed-off-by: Chris Morgan <redacted>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: 2021-09-08 18:06:03
On Wed, Sep 08, 2021 at 08:53:56AM -0500, Chris Morgan wrote:
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
To me it all makes a lot of sense, thank you for deep analysis of the issue!
In any case I think we will need a Fixes tag to something (either one of
clk-fractional-divider.c series or preexisted).
Anyway, FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
quoted hunk
Signed-off-by: Chris Morgan <redacted>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
From: Chris Morgan <hidden> Date: 2021-09-10 22:03:37
On Wed, Sep 08, 2021 at 09:05:52PM +0300, Andy Shevchenko wrote:
On Wed, Sep 08, 2021 at 08:53:56AM -0500, Chris Morgan wrote:
quoted
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
To me it all makes a lot of sense, thank you for deep analysis of the issue!
In any case I think we will need a Fixes tag to something (either one of
clk-fractional-divider.c series or preexisted).
Would this work for a "fixes"?
commit 287422a95fe2 ("drm/rockchip: Round up _before_ giving to the
clock framework")
That's the commit that introduced this "bug", even though it wasn't a
problem until the new commit that changed the way fractional clocks
worked for rockchip.
Thank you.
Anyway, FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
quoted
Signed-off-by: Chris Morgan <redacted>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
Hi,
Am Mittwoch, 8. September 2021, 15:53:56 CEST schrieb Chris Morgan:
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
Signed-off-by: Chris Morgan <redacted>
With 5.15-rc1 on:
- rk3288-pinky+eDP (was working -> still working)
- rk3399-kevin+eDP (was working -> still working)
- px30-minievb (was broken -> working again)
Tested-by: Heiko Stuebner <heiko@sntech.de>
I've also added Doug, maybe he remembers some historic artifact
to keep in mind about the original patch.
Heiko
From: Doug Anderson <dianders@chromium.org> Date: 2021-09-16 17:08:22
Hi,
On Tue, Sep 14, 2021 at 4:14 AM Heiko Stübner [off-list ref] wrote:
Hi,
Am Mittwoch, 8. September 2021, 15:53:56 CEST schrieb Chris Morgan:
quoted
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
Signed-off-by: Chris Morgan <redacted>
With 5.15-rc1 on:
- rk3288-pinky+eDP (was working -> still working)
- rk3399-kevin+eDP (was working -> still working)
- px30-minievb (was broken -> working again)
Tested-by: Heiko Stuebner <heiko@sntech.de>
I've also added Doug, maybe he remembers some historic artifact
to keep in mind about the original patch.
So when you say "was working" -> "still working", how did you test
that? Did you just confirm that something was showing up on the
screen, or did you check debugfs and make sure that the PLLs were all
being set correctly? Also, I can't quite remember if the problems here
were related to the internal display (and on which rockchip device) or
HDMI where we could have a whole lot more possible pixel clocks. I can
dig if need be. ...but I'm fairly certain that we can't just delete
the "+ 999" and expect everything to work. All of the stuff in the
comment above the "+ 999" is still as true today as it was when I
wrote it. DRM is still in kHz and the Rockchip clock driver still
rounds down.
I suspect that the problem here is that the logic I wrote up just
doesn't work great if your display clock is made by a "frac" clock.
That's pretty much what I was saying when I wrote the comment:
NOTE: if the PLL (maybe through a divider) could actually make
a clock rate 999 Hz higher instead of the one we want then this
could be a problem.
Maybe we can come up with a solution, though.
So one thing is that I'd suspect that the problem is actually a bug
with the fractional clock driver. "Best Numerator 17001, Best
Denominator 17000" is probably not a valid thing to set and the clock
driver should know this and seek out a different rate. I haven't dug
through your code paths but, for instance, the comments above
rockchip_fractional_approximation() say that denominator must be 20x
the numerator if you want a good clock. That's clearly not the case
here. There could also be maximum values of the numerator /
denominator that are being ignored. I would sorta bet that if the frac
clock driver was fixed that a clock anywhere between 17000000 and
17000999 would work just fine for you.
In any case, despite the clock driver being screwy, probably this
would fix it for you (untested) and is a better solution I think:
rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
if (rate / 1000 != adjusted_mode->clock)
rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
Basically: if we can happen to make the rate exactly then we're good.
Otherwise then try bumping up by 999.
From: Chris Morgan <hidden> Date: 2021-09-16 18:45:26
On Thu, Sep 16, 2021 at 10:08:05AM -0700, Doug Anderson wrote:
Hi,
On Tue, Sep 14, 2021 at 4:14 AM Heiko Stübner [off-list ref] wrote:
quoted
Hi,
Am Mittwoch, 8. September 2021, 15:53:56 CEST schrieb Chris Morgan:
quoted
From: Chris Morgan <redacted>
After commit 928f9e268611 ("clk: fractional-divider: Hide
clk_fractional_divider_ops from wide audience") was merged it appears
that the DSI panel on my Odroid Go Advance stopped working. Upon closer
examination of the problem, it looks like it was the fixup in the
rockchip_drm_vop.c file was causing the issue. The changes made to the
clk driver appear to change some assumptions made in the fixup.
After debugging the working 5.14 kernel and the no-longer working
5.15 kernel, it looks like this was broken all along but still
worked, whereas after the fractional clock change it stopped
working despite the issue (it went from sort-of broken to very broken).
In the 5.14 kernel the dclk_vopb_frac was being requested to be set to
17000999 on my board. The clock driver was taking the value of the
parent clock and attempting to divide the requested value from it
(17000000/17000999 = 0), then subtracting 1 from it (making it -1),
and running it through fls_long to get 64. It would then subtract
the value of fd->mwidth from it to get 48, and then bit shift
17000999 to the left by 48, coming up with a very large number of
7649082492112076800. This resulted in a numerator of 65535 and a
denominator of 1 from the clk driver. The driver seemingly would
try again and get a correct 1:1 value later, and then move on.
Output from my 5.14 kernel (with some printfs for good measure):
[ 2.830066] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.839431] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.855980] Clock is dclk_vopb_frac
[ 2.856004] Scale 64, Rate 7649082492112076800, Oldrate 17000999, Parent Rate 17000000, Best Numerator 65535, Best Denominator 1, fd->mwidth 16
[ 2.903529] Clock is dclk_vopb_frac
[ 2.903556] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
[ 2.903579] Clock is dclk_vopb_frac
[ 2.903583] Scale 0, Rate 17000000, Oldrate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1, fd->mwidth 16
Contrast this with 5.15 after the clk change where the rate of 17000999
was getting passed and resulted in numerators/denomiators of 17001/
17000.
Output from my 5.15 kernel (with some printfs added for good measure):
[ 2.817571] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.826975] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.843430] Rate 17000999, Parent Rate 17000000, Best Numerator 17018, Best Denominator 17017
[ 2.891073] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891269] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
[ 2.891281] Rate 17001000, Parent Rate 17000000, Best Numerator 17001, Best Denominator 17000
After tracing through the code it appeared that this function here was
adding a 999 to the requested frequency because of how the clk driver
was rounding/accepting those frequencies. I believe after the changes
made in the commit listed above the assumptions listed in this driver
are no longer true. When I remove the + 999 from the driver the DSI
panel begins to work again.
Output from my 5.15 kernel with 999 removed (printfs added):
[ 2.852054] rockchip-drm display-subsystem: bound ff460000.vop (ops vop_component_ops)
[ 2.864483] rockchip-drm display-subsystem: bound ff450000.dsi (ops dw_mipi_dsi_rockchip_ops)
[ 2.880869] Clock is dclk_vopb_frac
[ 2.880892] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928521] Clock is dclk_vopb_frac
[ 2.928551] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
[ 2.928570] Clock is dclk_vopb_frac
[ 2.928574] Rate 17000000, Parent Rate 17000000, Best Numerator 1, Best Denominator 1
I have tested the change extensively on my Odroid Go Advance (Rockchip
RK3326) and it appears to work well. However, this change will affect
all Rockchip SoCs that use this driver so I believe further testing
is warranted. Please note that without this change I can confirm
at least all PX30s with DSI panels will stop working with the 5.15
kernel.
Signed-off-by: Chris Morgan <redacted>
With 5.15-rc1 on:
- rk3288-pinky+eDP (was working -> still working)
- rk3399-kevin+eDP (was working -> still working)
- px30-minievb (was broken -> working again)
Tested-by: Heiko Stuebner <heiko@sntech.de>
I've also added Doug, maybe he remembers some historic artifact
to keep in mind about the original patch.
So when you say "was working" -> "still working", how did you test
that? Did you just confirm that something was showing up on the
screen, or did you check debugfs and make sure that the PLLs were all
being set correctly? Also, I can't quite remember if the problems here
were related to the internal display (and on which rockchip device) or
HDMI where we could have a whole lot more possible pixel clocks. I can
dig if need be. ...but I'm fairly certain that we can't just delete
the "+ 999" and expect everything to work. All of the stuff in the
comment above the "+ 999" is still as true today as it was when I
wrote it. DRM is still in kHz and the Rockchip clock driver still
rounds down.
I suspect that the problem here is that the logic I wrote up just
doesn't work great if your display clock is made by a "frac" clock.
That's pretty much what I was saying when I wrote the comment:
quoted
NOTE: if the PLL (maybe through a divider) could actually make
a clock rate 999 Hz higher instead of the one we want then this
could be a problem.
Maybe we can come up with a solution, though.
So one thing is that I'd suspect that the problem is actually a bug
with the fractional clock driver. "Best Numerator 17001, Best
Denominator 17000" is probably not a valid thing to set and the clock
driver should know this and seek out a different rate. I haven't dug
through your code paths but, for instance, the comments above
rockchip_fractional_approximation() say that denominator must be 20x
the numerator if you want a good clock. That's clearly not the case
here. There could also be maximum values of the numerator /
denominator that are being ignored. I would sorta bet that if the frac
clock driver was fixed that a clock anywhere between 17000000 and
17000999 would work just fine for you.
In any case, despite the clock driver being screwy, probably this
would fix it for you (untested) and is a better solution I think:
rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
if (rate / 1000 != adjusted_mode->clock)
rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
This appears to work for me at least. I'll resubmit a patch with this
as the solution. Thank you.
Basically: if we can happen to make the rate exactly then we're good.
Otherwise then try bumping up by 999.