Message ID | 20241020165102.340838-3-aford173@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [1/3] phy: freescale: fsl-samsung-hdmi: Expand Integer divider range | expand |
On 20.10.24 6:50 PM, Adam Ford wrote: > Currently, the calcuation for fld_tg_code is based on a lookup table, > but there are gaps in the lookup table, and frequencies in these > gaps may not properly use the correct divider. Based on the description > of FLD_CK_DIV, the internal PLL frequency should be less than 50 MHz, > so directly calcuate the value of FLD_CK_DIV from pixclk. > This allow for proper calcuation of any pixel clock and eliminates a > few gaps in the LUT. > > Since the value of the int_pllclk is in Hz, do the fixed-point > math in Hz to achieve a more accurate value and reduces the complexity > of the caluation to 24MHz * (256 / int_pllclk). > > Fixes: 6ad082bee902 ("phy: freescale: add Samsung HDMI PHY") > Signed-off-by: Adam Ford <aford173@gmail.com> Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de> > --- > drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 32 +++++++------------- > 1 file changed, 11 insertions(+), 21 deletions(-) > > diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c > index 719f8972cb5a..0bfe0c0907a0 100644 > --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c > +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c > @@ -331,25 +331,17 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy, > { > u32 pclk = cfg->pixclk; > u32 fld_tg_code; > - u32 pclk_khz; > - u8 div = 1; > - > - switch (cfg->pixclk) { > - case 22250000 ... 47500000: > - div = 1; > - break; > - case 50349650 ... 99000000: > - div = 2; > - break; > - case 100699300 ... 198000000: > - div = 4; > - break; > - case 205000000 ... 297000000: > - div = 8; > - break; > + u32 int_pllclk; > + u8 div; > + > + /* Find int_pllclk speed */ > + for (div = 0; div < 4; div++) { > + int_pllclk = pclk / (1 << div); > + if (int_pllclk < (50 * MHZ)) > + break; > } > > - writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12)); > + writeb(FIELD_PREP(REG12_CK_DIV_MASK, div), phy->regs + PHY_REG(12)); > > /* > * Calculation for the frequency lock detector target code (fld_tg_code) > @@ -362,10 +354,8 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy, > * settings rounding up always too. TODO: Check if that is > * correct. > */ > - pclk /= div; > - pclk_khz = pclk / 1000; > - fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24; > - fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000); > + > + fld_tg_code = DIV_ROUND_UP(24 * MHZ * 256, int_pllclk); > > /* FLD_TOL and FLD_RP_CODE taken from downstream driver */ > writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c index 719f8972cb5a..0bfe0c0907a0 100644 --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c @@ -331,25 +331,17 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy, { u32 pclk = cfg->pixclk; u32 fld_tg_code; - u32 pclk_khz; - u8 div = 1; - - switch (cfg->pixclk) { - case 22250000 ... 47500000: - div = 1; - break; - case 50349650 ... 99000000: - div = 2; - break; - case 100699300 ... 198000000: - div = 4; - break; - case 205000000 ... 297000000: - div = 8; - break; + u32 int_pllclk; + u8 div; + + /* Find int_pllclk speed */ + for (div = 0; div < 4; div++) { + int_pllclk = pclk / (1 << div); + if (int_pllclk < (50 * MHZ)) + break; } - writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12)); + writeb(FIELD_PREP(REG12_CK_DIV_MASK, div), phy->regs + PHY_REG(12)); /* * Calculation for the frequency lock detector target code (fld_tg_code) @@ -362,10 +354,8 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy, * settings rounding up always too. TODO: Check if that is * correct. */ - pclk /= div; - pclk_khz = pclk / 1000; - fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24; - fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000); + + fld_tg_code = DIV_ROUND_UP(24 * MHZ * 256, int_pllclk); /* FLD_TOL and FLD_RP_CODE taken from downstream driver */ writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
Currently, the calcuation for fld_tg_code is based on a lookup table, but there are gaps in the lookup table, and frequencies in these gaps may not properly use the correct divider. Based on the description of FLD_CK_DIV, the internal PLL frequency should be less than 50 MHz, so directly calcuate the value of FLD_CK_DIV from pixclk. This allow for proper calcuation of any pixel clock and eliminates a few gaps in the LUT. Since the value of the int_pllclk is in Hz, do the fixed-point math in Hz to achieve a more accurate value and reduces the complexity of the caluation to 24MHz * (256 / int_pllclk). Fixes: 6ad082bee902 ("phy: freescale: add Samsung HDMI PHY") Signed-off-by: Adam Ford <aford173@gmail.com> --- drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 32 +++++++------------- 1 file changed, 11 insertions(+), 21 deletions(-)