Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: freescale: fsl-samsung-hdmi: Clean up fld_tg_code calculation

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>
Link: https://lore.kernel.org/r/20241026132014.73050-3-aford173@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Adam Ford and committed by
Vinod Koul
d567679f 1b9b8b15

+10 -20
+10 -20
drivers/phy/freescale/phy-fsl-samsung-hdmi.c
··· 331 331 { 332 332 u32 pclk = cfg->pixclk; 333 333 u32 fld_tg_code; 334 - u32 pclk_khz; 335 - u8 div = 1; 334 + u32 int_pllclk; 335 + u8 div; 336 336 337 - switch (cfg->pixclk) { 338 - case 22250000 ... 47500000: 339 - div = 1; 340 - break; 341 - case 50349650 ... 99000000: 342 - div = 2; 343 - break; 344 - case 100699300 ... 198000000: 345 - div = 4; 346 - break; 347 - case 205000000 ... 297000000: 348 - div = 8; 349 - break; 337 + /* Find int_pllclk speed */ 338 + for (div = 0; div < 4; div++) { 339 + int_pllclk = pclk / (1 << div); 340 + if (int_pllclk < (50 * MHZ)) 341 + break; 350 342 } 351 343 352 - writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12)); 344 + writeb(FIELD_PREP(REG12_CK_DIV_MASK, div), phy->regs + PHY_REG(12)); 353 345 354 346 /* 355 347 * Calculation for the frequency lock detector target code (fld_tg_code) ··· 354 362 * settings rounding up always too. TODO: Check if that is 355 363 * correct. 356 364 */ 357 - pclk /= div; 358 - pclk_khz = pclk / 1000; 359 - fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24; 360 - fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000); 365 + 366 + fld_tg_code = DIV_ROUND_UP(24 * MHZ * 256, int_pllclk); 361 367 362 368 /* FLD_TOL and FLD_RP_CODE taken from downstream driver */ 363 369 writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),