* [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
@ 2026-07-29 10:18 Rajesh Gugulothu
2026-09-01 9:36 ` Gugulothu, Rajesh
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Rajesh Gugulothu @ 2026-07-29 10:18 UTC (permalink / raw)
To: Laurent Pinchart, Mauro Carvalho Chehab, Michal Simek
Cc: rajesh.gugulothu, linux-media, linux-arm-kernel, linux-kernel
This update enables the vtc to set the pixel clock based on the
specified timing parameters. A new fps field is added to struct
xvtc_config and the pixel rate is computed as fps * hsize * vsize.
After setting the rate, the actual clock rate is read back and a
warning is emitted if it deviates beyond a small tolerance.
The pixel rate is computed in unsigned long arithmetic to avoid a 32-bit
overflow in the fps * hsize * vsize product.
Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
---
drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
2 files changed, 20 insertions(+)
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c
index 92fec7bb4..695eb2a46 100644
--- a/drivers/media/platform/xilinx/xilinx-vtc.c
+++ b/drivers/media/platform/xilinx/xilinx-vtc.c
@@ -141,6 +141,9 @@
#define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
+/* Value of 1 = .01% */
+#define XVTC_CLK_MAX_PCT_ERR 1
+
/**
* struct xvtc_device - Xilinx Video Timing Controller device structure
* @xvip: Xilinx Video IP device
@@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
const struct xvtc_config *config)
{
int ret;
+ unsigned long s_rate;
+ unsigned long g_rate;
+ unsigned long clk_err;
if (!xvtc->has_generator)
return -ENXIO;
+ s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
+ ret = clk_set_rate(xvtc->xvip.clk, s_rate);
+ if (ret < 0)
+ return ret;
+
+ /* Verify that the clock is within a reasonable tolerance. */
+ g_rate = clk_get_rate(xvtc->xvip.clk);
+ clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
+ if (clk_err > XVTC_CLK_MAX_PCT_ERR)
+ dev_warn(xvtc->xvip.dev,
+ "Failed to set clk rate: %lu, actual rate: %lu\n",
+ s_rate, g_rate);
+
ret = clk_prepare_enable(xvtc->xvip.clk);
if (ret < 0)
return ret;
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h
index 855845911..0f360ed55 100644
--- a/drivers/media/platform/xilinx/xilinx-vtc.h
+++ b/drivers/media/platform/xilinx/xilinx-vtc.h
@@ -27,6 +27,7 @@ struct xvtc_config {
unsigned int vsync_start;
unsigned int vsync_end;
unsigned int vsize;
+ unsigned int fps;
};
struct xvtc_device *xvtc_of_get(struct device_node *np);
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-07-29 10:18 [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock Rajesh Gugulothu
@ 2026-09-01 9:36 ` Gugulothu, Rajesh
2026-09-01 11:56 ` Laurent Pinchart
2026-09-03 10:07 ` Tomi Valkeinen
2 siblings, 0 replies; 8+ messages in thread
From: Gugulothu, Rajesh @ 2026-09-01 9:36 UTC (permalink / raw)
To: Gugulothu, Rajesh, Laurent Pinchart, Mauro Carvalho Chehab,
Simek, Michal
Cc: linux-media, linux-arm-kernel, linux-kernel
AMD General
Hi All,
A gentle reminder on this patch. When you have a chance, could you please review it and let me know if any changes are needed?
Thanks,
Rajesh G
>-----Original Message-----
>From: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>Sent: Wednesday, July 29, 2026 3:48 PM
>To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>; Mauro Carvalho
>Chehab <mchehab@kernel.org>; Simek, Michal <michal.simek@amd.com>
>Cc: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>; linux-media@vger.kernel.org;
>linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org
>Subject: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
>
>This update enables the vtc to set the pixel clock based on the specified timing
>parameters. A new fps field is added to struct xvtc_config and the pixel rate is
>computed as fps * hsize * vsize.
>After setting the rate, the actual clock rate is read back and a warning is emitted if it
>deviates beyond a small tolerance.
>
>The pixel rate is computed in unsigned long arithmetic to avoid a 32-bit overflow in
>the fps * hsize * vsize product.
>
>Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>---
> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
>drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
> 2 files changed, 20 insertions(+)
>
>diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c
>b/drivers/media/platform/xilinx/xilinx-vtc.c
>index 92fec7bb4..695eb2a46 100644
>--- a/drivers/media/platform/xilinx/xilinx-vtc.c
>+++ b/drivers/media/platform/xilinx/xilinx-vtc.c
>@@ -141,6 +141,9 @@
>
> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>
>+/* Value of 1 = .01% */
>+#define XVTC_CLK_MAX_PCT_ERR 1
>+
> /**
> * struct xvtc_device - Xilinx Video Timing Controller device structure
> * @xvip: Xilinx Video IP device
>@@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
> const struct xvtc_config *config)
> {
> int ret;
>+ unsigned long s_rate;
>+ unsigned long g_rate;
>+ unsigned long clk_err;
>
> if (!xvtc->has_generator)
> return -ENXIO;
>
>+ s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
>+ ret = clk_set_rate(xvtc->xvip.clk, s_rate);
>+ if (ret < 0)
>+ return ret;
>+
>+ /* Verify that the clock is within a reasonable tolerance. */
>+ g_rate = clk_get_rate(xvtc->xvip.clk);
>+ clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
>+ if (clk_err > XVTC_CLK_MAX_PCT_ERR)
>+ dev_warn(xvtc->xvip.dev,
>+ "Failed to set clk rate: %lu, actual rate: %lu\n",
>+ s_rate, g_rate);
>+
> ret = clk_prepare_enable(xvtc->xvip.clk);
> if (ret < 0)
> return ret;
>diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h
>b/drivers/media/platform/xilinx/xilinx-vtc.h
>index 855845911..0f360ed55 100644
>--- a/drivers/media/platform/xilinx/xilinx-vtc.h
>+++ b/drivers/media/platform/xilinx/xilinx-vtc.h
>@@ -27,6 +27,7 @@ struct xvtc_config {
> unsigned int vsync_start;
> unsigned int vsync_end;
> unsigned int vsize;
>+ unsigned int fps;
> };
>
> struct xvtc_device *xvtc_of_get(struct device_node *np);
>--
>2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-07-29 10:18 [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock Rajesh Gugulothu
2026-09-01 9:36 ` Gugulothu, Rajesh
@ 2026-09-01 11:56 ` Laurent Pinchart
2026-09-03 10:07 ` Tomi Valkeinen
2 siblings, 0 replies; 8+ messages in thread
From: Laurent Pinchart @ 2026-09-01 11:56 UTC (permalink / raw)
To: Rajesh Gugulothu
Cc: Mauro Carvalho Chehab, Michal Simek, linux-media,
linux-arm-kernel, linux-kernel, Tomi Valkeinen
CC'ing Tomi who is working on Xilinx V4L2 drivers.
On Wed, Jul 29, 2026 at 03:48:08PM +0530, Rajesh Gugulothu wrote:
> This update enables the vtc to set the pixel clock based on the
> specified timing parameters. A new fps field is added to struct
> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
> After setting the rate, the actual clock rate is read back and a
> warning is emitted if it deviates beyond a small tolerance.
>
> The pixel rate is computed in unsigned long arithmetic to avoid a 32-bit
> overflow in the fps * hsize * vsize product.
>
> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
> ---
> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c
> index 92fec7bb4..695eb2a46 100644
> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
> @@ -141,6 +141,9 @@
>
> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>
> +/* Value of 1 = .01% */
> +#define XVTC_CLK_MAX_PCT_ERR 1
> +
> /**
> * struct xvtc_device - Xilinx Video Timing Controller device structure
> * @xvip: Xilinx Video IP device
> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
> const struct xvtc_config *config)
> {
> int ret;
> + unsigned long s_rate;
> + unsigned long g_rate;
> + unsigned long clk_err;
>
> if (!xvtc->has_generator)
> return -ENXIO;
>
> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
> + if (ret < 0)
> + return ret;
> +
> + /* Verify that the clock is within a reasonable tolerance. */
> + g_rate = clk_get_rate(xvtc->xvip.clk);
> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
> + dev_warn(xvtc->xvip.dev,
> + "Failed to set clk rate: %lu, actual rate: %lu\n",
> + s_rate, g_rate);
> +
> ret = clk_prepare_enable(xvtc->xvip.clk);
> if (ret < 0)
> return ret;
> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h
> index 855845911..0f360ed55 100644
> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
> @@ -27,6 +27,7 @@ struct xvtc_config {
> unsigned int vsync_start;
> unsigned int vsync_end;
> unsigned int vsize;
> + unsigned int fps;
> };
>
> struct xvtc_device *xvtc_of_get(struct device_node *np);
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-07-29 10:18 [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock Rajesh Gugulothu
2026-09-01 9:36 ` Gugulothu, Rajesh
2026-09-01 11:56 ` Laurent Pinchart
@ 2026-09-03 10:07 ` Tomi Valkeinen
2026-09-07 9:50 ` Gugulothu, Rajesh
2 siblings, 1 reply; 8+ messages in thread
From: Tomi Valkeinen @ 2026-09-03 10:07 UTC (permalink / raw)
To: Rajesh Gugulothu, Laurent Pinchart, Michal Simek
Cc: linux-media, linux-arm-kernel, linux-kernel, Mauro Carvalho Chehab
Hi,
On 29/07/2026 13:18, Rajesh Gugulothu wrote:
> This update enables the vtc to set the pixel clock based on the
> specified timing parameters. A new fps field is added to struct
> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
> After setting the rate, the actual clock rate is read back and a
> warning is emitted if it deviates beyond a small tolerance.
>
> The pixel rate is computed in unsigned long arithmetic to avoid a 32-bit
> overflow in the fps * hsize * vsize product.
>
> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
> ---
> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c
> index 92fec7bb4..695eb2a46 100644
> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
> @@ -141,6 +141,9 @@
>
> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>
> +/* Value of 1 = .01% */
> +#define XVTC_CLK_MAX_PCT_ERR 1
> +
> /**
> * struct xvtc_device - Xilinx Video Timing Controller device structure
> * @xvip: Xilinx Video IP device
> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
> const struct xvtc_config *config)
> {
> int ret;
> + unsigned long s_rate;
> + unsigned long g_rate;
> + unsigned long clk_err;
>
> if (!xvtc->has_generator)
> return -ENXIO;
>
> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
> + if (ret < 0)
> + return ret;
> +
> + /* Verify that the clock is within a reasonable tolerance. */
> + g_rate = clk_get_rate(xvtc->xvip.clk);
> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
> + dev_warn(xvtc->xvip.dev,
> + "Failed to set clk rate: %lu, actual rate: %lu\n",
> + s_rate, g_rate);
> +
> ret = clk_prepare_enable(xvtc->xvip.clk);
> if (ret < 0)
> return ret;
> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h
> index 855845911..0f360ed55 100644
> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
> @@ -27,6 +27,7 @@ struct xvtc_config {
> unsigned int vsync_start;
> unsigned int vsync_end;
> unsigned int vsize;
> + unsigned int fps;
> };
>
> struct xvtc_device *xvtc_of_get(struct device_node *np);
In upstream there's a single user for the VTC: the TPG driver. It
doesn't set the fps field, so the above code would always try to set the
rate to 0, wouldn't it?
What is "reasonable tolerance", why did you arrive to .01%? Also, the
actual result is not visible to the user.
I think this is a slightly bigger topic than a single VTC patch. There
should be a userspace API to set the FPS, and the user should see what
was the actual rate he got via the API (instead of a dev_warn when the
rate is off more than an arbitrary tolerance).
Tomi
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-09-03 10:07 ` Tomi Valkeinen
@ 2026-09-07 9:50 ` Gugulothu, Rajesh
2026-09-18 6:23 ` Gugulothu, Rajesh
2026-09-18 6:58 ` Tomi Valkeinen
0 siblings, 2 replies; 8+ messages in thread
From: Gugulothu, Rajesh @ 2026-09-07 9:50 UTC (permalink / raw)
To: Tomi Valkeinen, Laurent Pinchart, Simek, Michal
Cc: linux-media, linux-arm-kernel, linux-kernel, Mauro Carvalho Chehab
AMD General
Hi Tomi,
Thanks for the review, and Laurent for looping you in.
>-----Original Message-----
>From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>Sent: Thursday, September 3, 2026 3:38 PM
>To: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>; Laurent Pinchart
><laurent.pinchart@ideasonboard.com>; Simek, Michal <michal.simek@amd.com>
>Cc: linux-media@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>kernel@vger.kernel.org; Mauro Carvalho Chehab <mchehab@kernel.org>
>Subject: Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
>
>Hi,
>
>On 29/07/2026 13:18, Rajesh Gugulothu wrote:
>> This update enables the vtc to set the pixel clock based on the
>> specified timing parameters. A new fps field is added to struct
>> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
>> After setting the rate, the actual clock rate is read back and a
>> warning is emitted if it deviates beyond a small tolerance.
>>
>> The pixel rate is computed in unsigned long arithmetic to avoid a
>> 32-bit overflow in the fps * hsize * vsize product.
>>
>> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>> ---
>> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
>> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
>> 2 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c
>> b/drivers/media/platform/xilinx/xilinx-vtc.c
>> index 92fec7bb4..695eb2a46 100644
>> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
>> @@ -141,6 +141,9 @@
>>
>> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>>
>> +/* Value of 1 = .01% */
>> +#define XVTC_CLK_MAX_PCT_ERR 1
>> +
>> /**
>> * struct xvtc_device - Xilinx Video Timing Controller device structure
>> * @xvip: Xilinx Video IP device
>> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
>> const struct xvtc_config *config)
>> {
>> int ret;
>> + unsigned long s_rate;
>> + unsigned long g_rate;
>> + unsigned long clk_err;
>>
>> if (!xvtc->has_generator)
>> return -ENXIO;
>>
>> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
>> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* Verify that the clock is within a reasonable tolerance. */
>> + g_rate = clk_get_rate(xvtc->xvip.clk);
>> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
>> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
>> + dev_warn(xvtc->xvip.dev,
>> + "Failed to set clk rate: %lu, actual rate: %lu\n",
>> + s_rate, g_rate);
>> +
>> ret = clk_prepare_enable(xvtc->xvip.clk);
>> if (ret < 0)
>> return ret;
>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h
>> b/drivers/media/platform/xilinx/xilinx-vtc.h
>> index 855845911..0f360ed55 100644
>> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
>> @@ -27,6 +27,7 @@ struct xvtc_config {
>> unsigned int vsync_start;
>> unsigned int vsync_end;
>> unsigned int vsize;
>> + unsigned int fps;
>> };
>>
>> struct xvtc_device *xvtc_of_get(struct device_node *np);
>
>In upstream there's a single user for the VTC: the TPG driver. It doesn't set the fps
>field, so the above code would always try to set the rate to 0, wouldn't it?
>
You're right. The VTC change was posted without the TPG hunk that sets
fps (xtpg_config_vtc(): .fps = xtpg->fi_d / xtpg->fi_n), so upstream fps
stays 0 and we end up calling clk_set_rate(clk, 0) and dividing by zero.
I will include the TPG change in the series so the VTC code has a real
user.
>What is "reasonable tolerance", why did you arrive to .01%? Also, the actual result is
>not visible to the user.
>
Agreed, the 0.01% threshold was arbitrary. I will drop both the tolerance
and the dev_warn() - a log message is not something userspace can act on.
Instead the driver can use clk_round_rate() to get the achievable rate
and report the actual value through the API rather than dmesg. Does this
approach sound fine to you?
>I think this is a slightly bigger topic than a single VTC patch. There should be a
>userspace API to set the FPS, and the user should see what was the actual rate he
>got via the API (instead of a dev_warn when the rate is off more than an arbitrary
>tolerance).
Agreed. For v2 I will make the frame rate a userspace parameter and
report the achieved rate back through the same API, dropping the
tolerance/dev_warn heuristic entirely.
I plan to use the V4L2 frame-interval interface (VIDIOC_S/G_PARM on the
TPG source pad): compute the pixel clock from the requested interval,
program it via the VTC, and write the granted interval back so userspace
sees what it got. Let me know if you would prefer a different interface
(e.g. DV timings or a dedicated control); I would like to settle the API
before I respin.
>
> Tomi
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-09-07 9:50 ` Gugulothu, Rajesh
@ 2026-09-18 6:23 ` Gugulothu, Rajesh
2026-09-18 6:58 ` Tomi Valkeinen
1 sibling, 0 replies; 8+ messages in thread
From: Gugulothu, Rajesh @ 2026-09-18 6:23 UTC (permalink / raw)
To: Tomi Valkeinen, Laurent Pinchart, Simek, Michal
Cc: linux-media, linux-arm-kernel, linux-kernel, Mauro Carvalho Chehab
AMD General
Hi Tom,
A gentle reminder on this patch. When you have a chance, could you please review it.
Thanks,
Rajesh G
>-----Original Message-----
>From: Gugulothu, Rajesh
>Sent: Monday, September 7, 2026 3:21 PM
>To: 'Tomi Valkeinen' <tomi.valkeinen@ideasonboard.com>; Laurent Pinchart
><laurent.pinchart@ideasonboard.com>; Simek, Michal <michal.simek@amd.com>
>Cc: linux-media@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>kernel@vger.kernel.org; Mauro Carvalho Chehab <mchehab@kernel.org>
>Subject: RE: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
>
>Hi Tomi,
>
>Thanks for the review, and Laurent for looping you in.
>
>>-----Original Message-----
>>From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>>Sent: Thursday, September 3, 2026 3:38 PM
>>To: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>; Laurent Pinchart
>><laurent.pinchart@ideasonboard.com>; Simek, Michal
>><michal.simek@amd.com>
>>Cc: linux-media@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>>linux- kernel@vger.kernel.org; Mauro Carvalho Chehab
>><mchehab@kernel.org>
>>Subject: Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel
>>clock
>>
>>Hi,
>>
>>On 29/07/2026 13:18, Rajesh Gugulothu wrote:
>>> This update enables the vtc to set the pixel clock based on the
>>> specified timing parameters. A new fps field is added to struct
>>> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
>>> After setting the rate, the actual clock rate is read back and a
>>> warning is emitted if it deviates beyond a small tolerance.
>>>
>>> The pixel rate is computed in unsigned long arithmetic to avoid a
>>> 32-bit overflow in the fps * hsize * vsize product.
>>>
>>> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>>> ---
>>> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
>>> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
>>> 2 files changed, 20 insertions(+)
>>>
>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c
>>> b/drivers/media/platform/xilinx/xilinx-vtc.c
>>> index 92fec7bb4..695eb2a46 100644
>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
>>> @@ -141,6 +141,9 @@
>>>
>>> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>>>
>>> +/* Value of 1 = .01% */
>>> +#define XVTC_CLK_MAX_PCT_ERR 1
>>> +
>>> /**
>>> * struct xvtc_device - Xilinx Video Timing Controller device structure
>>> * @xvip: Xilinx Video IP device
>>> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
>>> const struct xvtc_config *config)
>>> {
>>> int ret;
>>> + unsigned long s_rate;
>>> + unsigned long g_rate;
>>> + unsigned long clk_err;
>>>
>>> if (!xvtc->has_generator)
>>> return -ENXIO;
>>>
>>> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
>>> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
>>> + if (ret < 0)
>>> + return ret;
>>> +
>>> + /* Verify that the clock is within a reasonable tolerance. */
>>> + g_rate = clk_get_rate(xvtc->xvip.clk);
>>> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
>>> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
>>> + dev_warn(xvtc->xvip.dev,
>>> + "Failed to set clk rate: %lu, actual rate: %lu\n",
>>> + s_rate, g_rate);
>>> +
>>> ret = clk_prepare_enable(xvtc->xvip.clk);
>>> if (ret < 0)
>>> return ret;
>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h
>>> b/drivers/media/platform/xilinx/xilinx-vtc.h
>>> index 855845911..0f360ed55 100644
>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
>>> @@ -27,6 +27,7 @@ struct xvtc_config {
>>> unsigned int vsync_start;
>>> unsigned int vsync_end;
>>> unsigned int vsize;
>>> + unsigned int fps;
>>> };
>>>
>>> struct xvtc_device *xvtc_of_get(struct device_node *np);
>>
>>In upstream there's a single user for the VTC: the TPG driver. It
>>doesn't set the fps field, so the above code would always try to set the rate to 0,
>wouldn't it?
>>
>You're right. The VTC change was posted without the TPG hunk that sets fps
>(xtpg_config_vtc(): .fps = xtpg->fi_d / xtpg->fi_n), so upstream fps stays 0 and we end
>up calling clk_set_rate(clk, 0) and dividing by zero.
>I will include the TPG change in the series so the VTC code has a real user.
>
>>What is "reasonable tolerance", why did you arrive to .01%? Also, the
>>actual result is not visible to the user.
>>
>Agreed, the 0.01% threshold was arbitrary. I will drop both the tolerance and the
>dev_warn() - a log message is not something userspace can act on.
>Instead the driver can use clk_round_rate() to get the achievable rate and report the
>actual value through the API rather than dmesg. Does this approach sound fine to
>you?
>
>>I think this is a slightly bigger topic than a single VTC patch. There
>>should be a userspace API to set the FPS, and the user should see what
>>was the actual rate he got via the API (instead of a dev_warn when the
>>rate is off more than an arbitrary tolerance).
>
>Agreed. For v2 I will make the frame rate a userspace parameter and report the
>achieved rate back through the same API, dropping the tolerance/dev_warn heuristic
>entirely.
>
>I plan to use the V4L2 frame-interval interface (VIDIOC_S/G_PARM on the TPG
>source pad): compute the pixel clock from the requested interval, program it via the
>VTC, and write the granted interval back so userspace sees what it got. Let me know
>if you would prefer a different interface (e.g. DV timings or a dedicated control); I
>would like to settle the API before I respin.
>>
>> Tomi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-09-07 9:50 ` Gugulothu, Rajesh
2026-09-18 6:23 ` Gugulothu, Rajesh
@ 2026-09-18 6:58 ` Tomi Valkeinen
2026-09-23 6:38 ` Gugulothu, Rajesh
1 sibling, 1 reply; 8+ messages in thread
From: Tomi Valkeinen @ 2026-09-18 6:58 UTC (permalink / raw)
To: Gugulothu, Rajesh
Cc: linux-media, linux-arm-kernel, linux-kernel,
Mauro Carvalho Chehab, Laurent Pinchart, Simek, Michal
Hi,
On 07/09/2026 12:50, Gugulothu, Rajesh wrote:
> AMD General
>
> Hi Tomi,
>
> Thanks for the review, and Laurent for looping you in.
>
>> -----Original Message-----
>> From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>> Sent: Thursday, September 3, 2026 3:38 PM
>> To: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>; Laurent Pinchart
>> <laurent.pinchart@ideasonboard.com>; Simek, Michal <michal.simek@amd.com>
>> Cc: linux-media@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>> kernel@vger.kernel.org; Mauro Carvalho Chehab <mchehab@kernel.org>
>> Subject: Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
>>
>> Hi,
>>
>> On 29/07/2026 13:18, Rajesh Gugulothu wrote:
>>> This update enables the vtc to set the pixel clock based on the
>>> specified timing parameters. A new fps field is added to struct
>>> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
>>> After setting the rate, the actual clock rate is read back and a
>>> warning is emitted if it deviates beyond a small tolerance.
>>>
>>> The pixel rate is computed in unsigned long arithmetic to avoid a
>>> 32-bit overflow in the fps * hsize * vsize product.
>>>
>>> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>>> ---
>>> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
>>> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
>>> 2 files changed, 20 insertions(+)
>>>
>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c
>>> b/drivers/media/platform/xilinx/xilinx-vtc.c
>>> index 92fec7bb4..695eb2a46 100644
>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
>>> @@ -141,6 +141,9 @@
>>>
>>> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>>>
>>> +/* Value of 1 = .01% */
>>> +#define XVTC_CLK_MAX_PCT_ERR 1
>>> +
>>> /**
>>> * struct xvtc_device - Xilinx Video Timing Controller device structure
>>> * @xvip: Xilinx Video IP device
>>> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
>>> const struct xvtc_config *config)
>>> {
>>> int ret;
>>> + unsigned long s_rate;
>>> + unsigned long g_rate;
>>> + unsigned long clk_err;
>>>
>>> if (!xvtc->has_generator)
>>> return -ENXIO;
>>>
>>> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
>>> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
>>> + if (ret < 0)
>>> + return ret;
>>> +
>>> + /* Verify that the clock is within a reasonable tolerance. */
>>> + g_rate = clk_get_rate(xvtc->xvip.clk);
>>> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
>>> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
>>> + dev_warn(xvtc->xvip.dev,
>>> + "Failed to set clk rate: %lu, actual rate: %lu\n",
>>> + s_rate, g_rate);
>>> +
>>> ret = clk_prepare_enable(xvtc->xvip.clk);
>>> if (ret < 0)
>>> return ret;
>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h
>>> b/drivers/media/platform/xilinx/xilinx-vtc.h
>>> index 855845911..0f360ed55 100644
>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
>>> @@ -27,6 +27,7 @@ struct xvtc_config {
>>> unsigned int vsync_start;
>>> unsigned int vsync_end;
>>> unsigned int vsize;
>>> + unsigned int fps;
>>> };
>>>
>>> struct xvtc_device *xvtc_of_get(struct device_node *np);
>>
>> In upstream there's a single user for the VTC: the TPG driver. It doesn't set the fps
>> field, so the above code would always try to set the rate to 0, wouldn't it?
>>
> You're right. The VTC change was posted without the TPG hunk that sets
> fps (xtpg_config_vtc(): .fps = xtpg->fi_d / xtpg->fi_n), so upstream fps
> stays 0 and we end up calling clk_set_rate(clk, 0) and dividing by zero.
> I will include the TPG change in the series so the VTC code has a real
> user.
>
>> What is "reasonable tolerance", why did you arrive to .01%? Also, the actual result is
>> not visible to the user.
>>
> Agreed, the 0.01% threshold was arbitrary. I will drop both the tolerance
> and the dev_warn() - a log message is not something userspace can act on.
> Instead the driver can use clk_round_rate() to get the achievable rate
> and report the actual value through the API rather than dmesg. Does this
> approach sound fine to you?
>
>> I think this is a slightly bigger topic than a single VTC patch. There should be a
>> userspace API to set the FPS, and the user should see what was the actual rate he
>> got via the API (instead of a dev_warn when the rate is off more than an arbitrary
>> tolerance).
>
> Agreed. For v2 I will make the frame rate a userspace parameter and
> report the achieved rate back through the same API, dropping the
> tolerance/dev_warn heuristic entirely.
>
> I plan to use the V4L2 frame-interval interface (VIDIOC_S/G_PARM on the
> TPG source pad): compute the pixel clock from the requested interval,
> program it via the VTC, and write the granted interval back so userspace
> sees what it got. Let me know if you would prefer a different interface
> (e.g. DV timings or a dedicated control); I would like to settle the API
> before I respin.
I think this sounds fine.
Do you have a design to test the TPG? I think Vivado dropped it many
years ago, and I have never actually ran the TPG driver.
Tomi
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
2026-09-18 6:58 ` Tomi Valkeinen
@ 2026-09-23 6:38 ` Gugulothu, Rajesh
0 siblings, 0 replies; 8+ messages in thread
From: Gugulothu, Rajesh @ 2026-09-23 6:38 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: linux-media, linux-arm-kernel, linux-kernel,
Mauro Carvalho Chehab, Laurent Pinchart, Simek, Michal
AMD General
Hi Tomi,
Thanks for the review. Please check my inline comments.
Thanks,
Rajesh G
>-----Original Message-----
>From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>Sent: Friday, September 18, 2026 12:29 PM
>To: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>
>Cc: linux-media@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>kernel@vger.kernel.org; Mauro Carvalho Chehab <mchehab@kernel.org>; Laurent
>Pinchart <laurent.pinchart@ideasonboard.com>; Simek, Michal
><michal.simek@amd.com>
>Subject: Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock
>
>Hi,
>
>On 07/09/2026 12:50, Gugulothu, Rajesh wrote:
>> AMD General
>>
>> Hi Tomi,
>>
>> Thanks for the review, and Laurent for looping you in.
>>
>>> -----Original Message-----
>>> From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>>> Sent: Thursday, September 3, 2026 3:38 PM
>>> To: Gugulothu, Rajesh <rajesh.gugulothu@amd.com>; Laurent Pinchart
>>> <laurent.pinchart@ideasonboard.com>; Simek, Michal
>>> <michal.simek@amd.com>
>>> Cc: linux-media@vger.kernel.org;
>>> linux-arm-kernel@lists.infradead.org; linux- kernel@vger.kernel.org;
>>> Mauro Carvalho Chehab <mchehab@kernel.org>
>>> Subject: Re: [PATCH] media: xilinx: vtc: Dynamically calculate pixel
>>> clock
>>>
>>> Hi,
>>>
>>> On 29/07/2026 13:18, Rajesh Gugulothu wrote:
>>>> This update enables the vtc to set the pixel clock based on the
>>>> specified timing parameters. A new fps field is added to struct
>>>> xvtc_config and the pixel rate is computed as fps * hsize * vsize.
>>>> After setting the rate, the actual clock rate is read back and a
>>>> warning is emitted if it deviates beyond a small tolerance.
>>>>
>>>> The pixel rate is computed in unsigned long arithmetic to avoid a
>>>> 32-bit overflow in the fps * hsize * vsize product.
>>>>
>>>> Signed-off-by: Rajesh Gugulothu <rajesh.gugulothu@amd.com>
>>>> ---
>>>> drivers/media/platform/xilinx/xilinx-vtc.c | 19 +++++++++++++++++++
>>>> drivers/media/platform/xilinx/xilinx-vtc.h | 1 +
>>>> 2 files changed, 20 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c
>>>> b/drivers/media/platform/xilinx/xilinx-vtc.c
>>>> index 92fec7bb4..695eb2a46 100644
>>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.c
>>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.c
>>>> @@ -141,6 +141,9 @@
>>>>
>>>> #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
>>>>
>>>> +/* Value of 1 = .01% */
>>>> +#define XVTC_CLK_MAX_PCT_ERR 1
>>>> +
>>>> /**
>>>> * struct xvtc_device - Xilinx Video Timing Controller device structure
>>>> * @xvip: Xilinx Video IP device
>>>> @@ -175,10 +178,26 @@ int xvtc_generator_start(struct xvtc_device *xvtc,
>>>> const struct xvtc_config *config)
>>>> {
>>>> int ret;
>>>> + unsigned long s_rate;
>>>> + unsigned long g_rate;
>>>> + unsigned long clk_err;
>>>>
>>>> if (!xvtc->has_generator)
>>>> return -ENXIO;
>>>>
>>>> + s_rate = (unsigned long)config->fps * config->hsize * config->vsize;
>>>> + ret = clk_set_rate(xvtc->xvip.clk, s_rate);
>>>> + if (ret < 0)
>>>> + return ret;
>>>> +
>>>> + /* Verify that the clock is within a reasonable tolerance. */
>>>> + g_rate = clk_get_rate(xvtc->xvip.clk);
>>>> + clk_err = (abs(g_rate - s_rate) * 10000) / (s_rate);
>>>> + if (clk_err > XVTC_CLK_MAX_PCT_ERR)
>>>> + dev_warn(xvtc->xvip.dev,
>>>> + "Failed to set clk rate: %lu, actual rate: %lu\n",
>>>> + s_rate, g_rate);
>>>> +
>>>> ret = clk_prepare_enable(xvtc->xvip.clk);
>>>> if (ret < 0)
>>>> return ret;
>>>> diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h
>>>> b/drivers/media/platform/xilinx/xilinx-vtc.h
>>>> index 855845911..0f360ed55 100644
>>>> --- a/drivers/media/platform/xilinx/xilinx-vtc.h
>>>> +++ b/drivers/media/platform/xilinx/xilinx-vtc.h
>>>> @@ -27,6 +27,7 @@ struct xvtc_config {
>>>> unsigned int vsync_start;
>>>> unsigned int vsync_end;
>>>> unsigned int vsize;
>>>> + unsigned int fps;
>>>> };
>>>>
>>>> struct xvtc_device *xvtc_of_get(struct device_node *np);
>>>
>>> In upstream there's a single user for the VTC: the TPG driver. It
>>> doesn't set the fps field, so the above code would always try to set the rate to 0,
>wouldn't it?
>>>
>> You're right. The VTC change was posted without the TPG hunk that sets
>> fps (xtpg_config_vtc(): .fps = xtpg->fi_d / xtpg->fi_n), so upstream
>> fps stays 0 and we end up calling clk_set_rate(clk, 0) and dividing by zero.
>> I will include the TPG change in the series so the VTC code has a real
>> user.
>>
>>> What is "reasonable tolerance", why did you arrive to .01%? Also, the
>>> actual result is not visible to the user.
>>>
>> Agreed, the 0.01% threshold was arbitrary. I will drop both the
>> tolerance and the dev_warn() - a log message is not something userspace can act
>on.
>> Instead the driver can use clk_round_rate() to get the achievable rate
>> and report the actual value through the API rather than dmesg. Does
>> this approach sound fine to you?
>>
>>> I think this is a slightly bigger topic than a single VTC patch.
>>> There should be a userspace API to set the FPS, and the user should
>>> see what was the actual rate he got via the API (instead of a
>>> dev_warn when the rate is off more than an arbitrary tolerance).
>>
>> Agreed. For v2 I will make the frame rate a userspace parameter and
>> report the achieved rate back through the same API, dropping the
>> tolerance/dev_warn heuristic entirely.
>>
>> I plan to use the V4L2 frame-interval interface (VIDIOC_S/G_PARM on
>> the TPG source pad): compute the pixel clock from the requested
>> interval, program it via the VTC, and write the granted interval back
>> so userspace sees what it got. Let me know if you would prefer a
>> different interface (e.g. DV timings or a dedicated control); I would
>> like to settle the API before I respin.
>I think this sounds fine.
>
>Do you have a design to test the TPG? I think Vivado dropped it many years ago,
>and I have never actually ran the TPG driver.
Thanks, I will go with VIDIOC_S/G_PARM on the TPG source pad for v2.
Yes, I have a working internal design with TPG + VTC + framebuffer write,
and Vivado still ships the Video Test Pattern Generator (v_tpg). I will
test v2 on that pipeline before posting it.
>
> Tomi
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-23 6:38 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-29 10:18 [PATCH] media: xilinx: vtc: Dynamically calculate pixel clock Rajesh Gugulothu
2026-09-01 9:36 ` Gugulothu, Rajesh
2026-09-01 11:56 ` Laurent Pinchart
2026-09-03 10:07 ` Tomi Valkeinen
2026-09-07 9:50 ` Gugulothu, Rajesh
2026-09-18 6:23 ` Gugulothu, Rajesh
2026-09-18 6:58 ` Tomi Valkeinen
2026-09-23 6:38 ` Gugulothu, Rajesh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®