Skip to content

hmc7044: add dynamic PLL2 rate selection via CCF#3283

Open
vai-tomme wants to merge 11 commits into
analogdevicesinc:mainfrom
vai-tomme:upstream/hmc7044
Open

hmc7044: add dynamic PLL2 rate selection via CCF#3283
vai-tomme wants to merge 11 commits into
analogdevicesinc:mainfrom
vai-tomme:upstream/hmc7044

Conversation

@vai-tomme
Copy link
Copy Markdown
Contributor

@vai-tomme vai-tomme commented Apr 27, 2026

PR Description

This series extends the HMC7044 driver to expose PLL2 as a CCF clock and support dynamic PLL2 rate selection. When a requested output frequency cannot be satisfied by an integer divider alone, the driver searches for a PLL2 rate that best approximates the target. Per-channel deviation budgets can be specified to protect other outputs from excessive frequency error when PLL2 is retuned.

Tested on zcu102 with modifications on top of main branch. Noting that curiously jesd204 link does not come up successfully with main branch, but situation is same with or without these changes applied.

Signed-off-by: Tomas Melin tomas.melin@vaisala.com

PR Type

  • Bug fix (a change that fixes an issue)
  • New feature (a change that adds new functionality)
  • Breaking change (a change that affects other repos or cause CIs to fail)

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have compiled my changes, including the documentation
  • I have tested the changes on the relevant hardware
  • I have updated the documentation outside this repo accordingly
  • I have provided links for the relevant upstream lore

Register pll2 as parent in the case device is hmc7044. This will
enable control and propagation of clock changes to sibling channels
and parent clock within the device. Support clock framework
operations for the added pll2 clock.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Make the pll2 setting calculations a separate function. Calculating
appropriate settings and achievable frequencies as a separate request
is needed when controlling the clock via the clock framework.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
@vai-tomme vai-tomme force-pushed the upstream/hmc7044 branch from e6dc2c0 to c153c5b Compare May 4, 2026 14:18
vai-tomme added 9 commits May 4, 2026 14:22
Add new set-rate-parent property.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Add a new property to make channel rate setting possible
to propagate to parent. The escalation happens when a frequency
that is not directly achievable is requested. Since not all
requested frequencies are necessarily achievable by all channels
at once, this feature allows to describe which channels should
be prioritized. Channels that lack this property will work as before.
That is, only operate within the range of divider settings available,
and with constant parent frequency rate.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Implementation for both determine_rate and round_rate operations
are typically not required. In this case supporting both is not
needed and also would require extending current implementations to
both support parent rate setting. To avoid any conflicts with
this, drop determine rate in favor of the round rate implementation.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Split functionality to register clocks separately in preparation
to support pll2 clock operations dynamically.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Round rate operation will be called to determine whether a requested
frequency can be fulfilled. Here we add support to also calculate
a suitable new parent rate for the case where parent rate propagation
has been set for the specific clock being changed.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Relay writes to common clock framework when channel frequency settings
are altered via sysfs interface. This allows to escalate frequency changes
to parent clocks and do other sanity checks to the frequency being
requested, in a common fashion.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
When requesting zero as output frequency for a specific channel,
set the channel register to disabled. Also add the support codes for
avoiding division by zero. Setting a frequency different than zero
re-enables the channels with other settings restored.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Add the adi,max-deviation-ppm property. When set on a channel, any
PLL2 rate change requested by a CLK_SET_RATE_PARENT channel is
rejected if it would shift this channel's output frequency by more
than the specified number of parts per million from its current rate.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
Account for maximum allowed deviations when setting frequency.

Logic works accordingly:
If set-rate-parent is enabled for a specific channel, a new
parent pll2 rate will be looked for when the frequency does not match
an allowed divider.
If the parent clock rate changes, this implies that the accuracy of
other channels might change. Therefore, check all other channel's allowed
deviations.
If a potential parent rate that fulfills the requested rate for the
channel does not meet deviation requirements of the other channels,
skip it and go to next candidate. This check applies to all channels that
are not currently disabled.
If any of the channel deviation requirements fail, the requested frequency
will be rejected.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
@vai-tomme
Copy link
Copy Markdown
Contributor Author

vai-tomme commented May 4, 2026

  • split dt binding commit to separate patch

@vai-tomme vai-tomme force-pushed the upstream/hmc7044 branch from c153c5b to 30964aa Compare May 4, 2026 14:26
Copy link
Copy Markdown
Collaborator

@nunojsa nunojsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for contributing. Some remarks from me

[3] = "clkin3",
};

static int hmc7044_setup(struct iio_dev *indio_dev);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Juts prefer that you move the function if really needed.

static unsigned long hmc7044_pll2_recalc_rate(unsigned long vcxo_freq,
unsigned long pll2_freq,
bool force_r2_eq_1,
struct hmc7044_pll2_config *pll2)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logically, the struct should be the first argument

unsigned long r2_max;

vcxo_freq = vcxo_freq / 1000;
pll2_freq = pll2_freq / 1000;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we gain something from DIV_ROUND_CLOSEST()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thin that wouldn't gain anything here. The frequencies are exact kHz multiples so it would give the same result.

pll2_freq = pll2_freq / 1000;

if (pll2_freq < HMC7044_LOW_VCO_MIN ||
pll2_freq > HMC7044_HIGH_VCO_MAX)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just put it in one line

while ((n2[0] < HMC7044_N2_MIN) && (r2[0] <= HMC7044_R2_MAX / 2)) {
n2[0] *= 2;
r2[0] *= 2;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: new line


/* don't propagate rate change to parent*/
if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
return oldrate;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I get the don't propagate the parent rate thing but why do we return oldrate? is it because if we can't change the parent than we can assume no new rate will work? Maybe I'm missing something

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because shortly before, based on the requested rate, we have calculcated what the rate will be with the current PLL2 frequency. As we are not changing that, oldrate is what we can achieve.

struct hmc7044_chan_spec {
unsigned int num;
bool disable;
bool mute;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm don't really like this kind of "write 0" to disable. If that isn't an allowed value we should just error out instead of doing this kind of stuff, Both CCF and IIO have explicit things to disable channels or clocks

if (deviation < min_dev) {
min_dev = deviation;
deviation_ppm = abs(rate - newrate) *
1000000 / rate;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. More readable if it goes to the same line

div = hmc7044_calc_out_div(pll2_candidate, current_rate);
candidate_rate = DIV_ROUND_CLOSEST(pll2_candidate, div);
deviation_ppm = abs(current_rate - candidate_rate) *
1000000 / current_rate;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also put it in the same line unless we pass the 101 col limit

@analogdevicesinc analogdevicesinc deleted a comment from github-actions Bot May 7, 2026
@nunojsa nunojsa removed the llm review Request a review from a LLM Reviewer label May 7, 2026
@nunojsa nunojsa added the llm review Request a review from a LLM Reviewer label May 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

LLM review

This series adds PLL2 clock framework integration to the HMC7044 jitter attenuator driver, enabling dynamic PLL2 rate changes, channel muting via zero-rate, and per-channel deviation guards (adi,max-deviation-ppm / adi,set-rate-parent).

run: 25484988610

84a63553 - register pll2 clock

Clock name collision: hmc7044_pll2_register() registers the PLL2 clock with the hardcoded name "hmc7044_pll2":

// drivers/iio/frequency/hmc7044.c:1101
init.name = "hmc7044_pll2";

The Linux clock framework requires globally unique clock names. When two HMC7044 instances are present (common in multi-chip systems), devm_clk_register() on the second device returns -EEXIST and the driver fails to probe. All 14 output clocks correctly use per-device names from the clock-output-names DT property; the same approach is needed here. Compare with adf4382.c and adf4350.c which use devm_kasprintf(&dev, GFP_KERNEL, "%s-clk", dev_name(dev)).

CI warnings

No checkpatch warnings were found. Clean build confirmed with gcc_arm cross-compiler (W=1 extra warnings enabled).

Verification data

The HMC7044 datasheet was fetched from the doctools docling mirror (hmc7044.md) and used to verify: VCO frequency range (2400–3200 MHz guaranteed coverage), N2 feedback divider range (8–65535), R2 reference divider range (1–4095) — all consistent with the driver's HMC7044_RECOMM_VCO_MIN/MAX, HMC7044_N2_MIN/MAX, and HMC7044_R2_MAX constants.

Suggested patches

Apply the suggested patches with:

cd path/to/repository
export GITHUB_TOKEN=ghp_***
apply-patches --repo=analogdevicesinc/linux 25484988610
Install instructions

The following one-liner installs the script if not present already:

grep "/apply-patches.sh" ~/.bashrc ||  { curl "https://raw.githubusercontent.com/analogdevicesinc/doctools/refs/heads/main/ci/scripts/apply-patches.sh"    -o ~/.local/bin/apply-patches.sh &&  echo "source ~/.local/bin/apply-patches.sh" >> ~/.bashrc ; source ~/.bashrc ; }

More information at AI Usage.

@nunojsa
Copy link
Copy Markdown
Collaborator

nunojsa commented May 7, 2026

AI complain seems valid

@vai-tomme
Copy link
Copy Markdown
Contributor Author

AI complain seems valid

  • It does, I will check it out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llm review Request a review from a LLM Reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants