Re: [PATCH v2 2/6] media: qcom: camss: clamp VFE clock rates to the highest level

From: Loic Poulain

Date: Mon Oct 26 2026 - 05:32:11 EST


On Sat, Oct 24, 2026 at 11:40 AM Atanas Filipov
<atanas.filipov@xxxxxxxxxxxxxxxx> wrote:
>
> The VFE fails to power on when the pixel rate exceeds the highest rate
> listed for any of its clocks. The rate tables of the VFE clocks are
> independent and need not have the same number of levels, so a clock
> with a lower top rate than the VFE core clock, such as the SC7280
> camnoc_axi clock, makes the VFE reject pixel rates the core clock
> still supports.
>
> Clamp each clock to its highest listed rate instead, and warn that the
> pixel rate exceeds it when the clock lists more than one rate. Take the
> clamp into account when another line powers on an already running VFE,
> so that a clock running at its highest rate does not reject the
> request.
>
> Signed-off-by: Atanas Filipov <atanas.filipov@xxxxxxxxxxxxxxxx>
> ---
> drivers/media/platform/qcom/camss/camss-vfe.c | 18 +++++++++++-------
> 1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 59be37f83df3..359b5942df89 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -996,15 +996,13 @@ static int vfe_set_clock_rates(struct vfe_device *vfe)
> if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
> long rate;
>
> - for (j = 0; j < clock->nfreqs; j++)
> + for (j = 0; j < clock->nfreqs - 1; j++)
> if (min_rate < clock->freq[j])
> break;
>
> - if (j == clock->nfreqs) {
> - dev_err(dev,
> - "Pixel clock is too high for VFE");
> - return -EINVAL;
> - }
> + if (clock->nfreqs > 1 && min_rate >= clock->freq[j])
> + dev_warn(dev, "Pixel clock is too high for VFE clock %s\n",
> + clock->name);

But are we still comparing the pixel rate against potentially
non-pixel clocks here, such as AXI?

>
> /* if sensor pixel clock is not available */
> /* set highest possible VFE clock rate */
> @@ -1046,9 +1044,15 @@ static int vfe_check_clock_rates(struct vfe_device *vfe)
>
> if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
> unsigned long rate;
> + long max_rate;
> +
> + /* A clock already at its highest rate cannot go higher */
> + max_rate = clk_round_rate(clock->clk, clock->freq[clock->nfreqs - 1]);
> + if (max_rate < 0)
> + return max_rate;
>
> rate = clk_get_rate(clock->clk);
> - if (rate < min_rate)
> + if (rate < min_t(u64, min_rate, max_rate))
> return -EBUSY;
> }
> }
> --
> 2.34.1
>