For debug purposes it is useful to know how far away the generated pixelclock is from the desired rate, so print the amount of error.
After adding this patch and with debug enabled we have:
imx-ipuv3 2400000.ipu: disp 0: panel size = 1920 x 1080 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 24000000Hz Needed 138500000Hz imx-ipuv3 2400000.ipu: IPU clock can give 132000000 with divider 2, error -4.3% imx-ipuv3 2400000.ipu: Want 138500000Hz IPU 264000000Hz DI 138500000Hz using DI, 138500000Hz, error 0.0% imx-ipuv3 2400000.ipu: disp 1: panel size = 1024 x 768 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz imx-ipuv3 2400000.ipu: Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz, error 0.9%
Signed-off-by: Fabio Estevam fabio.estevam@freescale.com --- drivers/gpu/ipu-v3/ipu-di.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c index c490ba4..148ef6e 100644 --- a/drivers/gpu/ipu-v3/ipu-di.c +++ b/drivers/gpu/ipu-v3/ipu-di.c @@ -402,7 +402,7 @@ static void ipu_di_config_clock(struct ipu_di *di, const struct ipu_di_signal_cfg *sig) { struct clk *clk; - unsigned clkgen0; + unsigned clkgen0, error; uint32_t val;
if (sig->clkflags & IPU_DI_CLKMODE_EXT) { @@ -451,7 +451,7 @@ static void ipu_di_config_clock(struct ipu_di *di, * otherwise we use the DI clock. */ unsigned long rate, clkrate; - unsigned div, error; + unsigned div;
clkrate = clk_get_rate(di->clk_ipu); div = (clkrate + sig->pixelclock / 2) / sig->pixelclock; @@ -503,12 +503,15 @@ static void ipu_di_config_clock(struct ipu_di *di, val |= DI_GEN_DI_CLK_EXT; ipu_di_write(di, val, DI_GENERAL);
- dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, %luHz\n", + error = (clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4)) / (sig->pixelclock / 1000); + + dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, %luHz, error %d.%u%%\n", sig->pixelclock, clk_get_rate(di->clk_ipu), clk_get_rate(di->clk_di), clk == di->clk_di ? "DI" : "IPU", - clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4)); + clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4), + (signed)(error - 1000) / 10, error % 10); }
int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
Hi Fabio,
Am Dienstag, den 02.09.2014, 10:31 -0300 schrieb Fabio Estevam:
For debug purposes it is useful to know how far away the generated pixelclock is from the desired rate, so print the amount of error.
After adding this patch and with debug enabled we have:
imx-ipuv3 2400000.ipu: disp 0: panel size = 1920 x 1080 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 24000000Hz Needed 138500000Hz imx-ipuv3 2400000.ipu: IPU clock can give 132000000 with divider 2, error -4.3% imx-ipuv3 2400000.ipu: Want 138500000Hz IPU 264000000Hz DI 138500000Hz using DI, 138500000Hz, error 0.0% imx-ipuv3 2400000.ipu: disp 1: panel size = 1024 x 768 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz imx-ipuv3 2400000.ipu: Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz, error 0.9%
As this example shows ...
[...]
- dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, %luHz\n",
- error = (clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4)) / (sig->pixelclock / 1000);
- dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, %luHz, error %d.%u%%\n", sig->pixelclock, clk_get_rate(di->clk_ipu), clk_get_rate(di->clk_di), clk == di->clk_di ? "DI" : "IPU",
clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4));
clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4),
(signed)(error - 1000) / 10, error % 10);
... this only works for positive deviations. If error < 1000, error % 10 will return the wrong value and for 990 < error < 1000 the sign is missing.
Also you are losing a lot of presicion. the real error in the example is more like 0.000002%, so I wonder how useful this really is.
regards Philipp
dri-devel@lists.freedesktop.org