mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
clk: rockchip: Fractional PLL coefficient on RK3588/RK3576 is two's complement
When the PLL rates table was first committed for RK3588 (and later reused for RK3576), the fractional PLL coefficient was defined as an unsigned value, while the TRM clearly states that it is a two's complement 16-bit value. Treating the fractional PLL coefficient as unsigned in rate recalculation results in a kernel-visible rate which deviates from what the hardware actually generates by Fin / (p * 2^s), or 2 MHz for the two affected table entries. Rockchip's downstream kernel later revised the fractional PLL code [1] to account for the two's complement nature of the coefficient, but that change wasn't upstreamed. Change the PLL table definition to use two's complement for the fractional coefficient and update its users accordingly. Note that a negative fractional coefficient is meant to be subtracted from the next larger integer multiplier, so the m values in the table are also adjusted accordingly for the two negative-k entries. Rockchip's downstream commit introducing the two's complement logic for k also does unrelated tweaks to the PLL parameters which are not explained by the switch to the two's complement, so they are not replicated here. If any of the parameters prove to need further tweaks (e.g. for precision or jitter) that would better be done in targeted follow-up commits. Fractional PLL rates don't seem to be used by any current mainline consumers, so this is purely a correctness fix. It will also be important to properly support DisplayPort output going forward, as the video output controller derives its pixel clock from system PLLs with no dedicated PHY PLL option for DP unlike HDMI, and some display modes are only achievable using fractional PLL rates. Link:7a72bc05dc[1] Fixes:f1c506d152("clk: rockchip: add clock controller for the RK3588") Fixes:cc40f5baa9("clk: rockchip: Add clock controller for the RK3576") Signed-off-by: Alexey Charkov <alchark@flipper.net> Link: https://patch.msgid.link/20260723-rk3588-fracpll-v2-2-3adfb9dda235@flipper.net Signed-off-by: Heiko Stuebner <heiko@sntech.de>
This commit is contained in:
parent
52aef653c3
commit
5814788834
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/clk.h>
|
||||
#include "clk.h"
|
||||
|
|
@ -906,6 +907,7 @@ static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,
|
|||
* For Fvco < 3 GHz: period jitter +-2% frac PLL, +-1.50% int PLL
|
||||
* Fvco = ((m + k / 65536) * Fin) / p
|
||||
* Fout = ((m + k / 65536) * Fin) / (p * 2^s)
|
||||
* -32768 <= k <= 32767 (only available in frac PLLs, not int PLLs)
|
||||
*/
|
||||
static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
||||
{
|
||||
|
|
@ -920,11 +922,10 @@ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned
|
|||
|
||||
if (cur.k) {
|
||||
/* fractional mode */
|
||||
u64 frac_rate64 = prate * cur.k;
|
||||
s64 frac_rate64 = (s64)prate * cur.k;
|
||||
|
||||
postdiv = cur.p * 65536;
|
||||
do_div(frac_rate64, postdiv);
|
||||
rate64 += frac_rate64;
|
||||
rate64 += div_s64(frac_rate64, postdiv);
|
||||
}
|
||||
rate64 = rate64 >> cur.s;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,13 +79,13 @@ static struct rockchip_pll_rate_table rk3576_pll_rates[] = {
|
|||
RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
|
||||
RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
|
||||
RK3588_PLL_RATE(983040000, 4, 655, 2, 23592),
|
||||
RK3588_PLL_RATE(955520000, 3, 477, 2, 49806),
|
||||
RK3588_PLL_RATE(955520000, 3, 478, 2, -15730),
|
||||
RK3588_PLL_RATE(903168000, 6, 903, 2, 11009),
|
||||
RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
|
||||
RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
|
||||
RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
|
||||
RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
|
||||
RK3588_PLL_RATE(785560000, 3, 392, 2, 51117),
|
||||
RK3588_PLL_RATE(785560000, 3, 393, 2, -14419),
|
||||
RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
|
||||
RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
|
||||
RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
|
||||
|
|
|
|||
|
|
@ -79,14 +79,14 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
|
|||
RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
|
||||
RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
|
||||
RK3588_PLL_RATE(983040000, 4, 655, 2, 23592),
|
||||
RK3588_PLL_RATE(955520000, 3, 477, 2, 49806),
|
||||
RK3588_PLL_RATE(955520000, 3, 478, 2, -15730),
|
||||
RK3588_PLL_RATE(903168000, 6, 903, 2, 11009),
|
||||
RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
|
||||
RK3588_PLL_RATE(850000000, 3, 425, 2, 0),
|
||||
RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
|
||||
RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
|
||||
RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
|
||||
RK3588_PLL_RATE(785560000, 3, 392, 2, 51117),
|
||||
RK3588_PLL_RATE(785560000, 3, 393, 2, -14419),
|
||||
RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
|
||||
RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
|
||||
RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
|
||||
|
|
|
|||
|
|
@ -635,10 +635,10 @@ struct rockchip_pll_rate_table {
|
|||
};
|
||||
struct {
|
||||
/* for RK3588 */
|
||||
unsigned int m;
|
||||
unsigned int p;
|
||||
unsigned int s;
|
||||
unsigned int k;
|
||||
unsigned int m; /* main divider, 10 bit unsigned */
|
||||
unsigned int p; /* pre-divider, 6 bit unsigned */
|
||||
unsigned int s; /* scaler, 3 bit unsigned */
|
||||
s16 k; /* fractional part, 16 bit two's complement */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user