From: Marek Vasut <marek.vasut@gmail.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: linux-clk@vger.kernel.org,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@codeaurora.org>,
Linux-Renesas <linux-renesas-soc@vger.kernel.org>
Subject: Re: [PATCH V4] clk: vc5: Add support for IDT VersaClock 5P49V5923 and 5P49V5933
Date: Wed, 11 Jan 2017 16:53:53 +0100 [thread overview]
Message-ID: <f1a287f5-6050-2e19-99c9-e17972e4db88@gmail.com> (raw)
In-Reply-To: <8755535.oe5AAjKalT@avalon>
On 01/11/2017 04:41 PM, Laurent Pinchart wrote:
> Hi Marek,
Hi!
> Thank you for the patch.
>
> On Wednesday 11 Jan 2017 15:37:11 Marek Vasut wrote:
>> On 01/10/2017 07:50 PM, Marek Vasut wrote:
>>> Add driver for IDT VersaClock 5 5P49V5923 and 5P49V5933 chips. These
>>> chips have two clock inputs, XTAL or CLK, which are muxed into single
>>> PLL/VCO input. In case of 5P49V5923, the XTAL in built into the chip
>>> while the 5P49V5923 requires external XTAL.
>>>
>>> The PLL feeds two fractional dividers. Each fractional divider feeds
>>> output mux, which allows selecting between clock from the fractional
>>> divider itself or from output mux on output N-1. In case of output
>>> mux 0, the output N-1 is instead connected to the output from the mux
>>> feeding the PLL.
>>>
>>> The driver thus far supports only the 5P49V5923 and 5P49V5933, while
>>> it should be easily extensible to the whole 5P49V59xx family of chips
>>> as they are all pretty similar.
>>>
>>> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
>>> Cc: Michael Turquette <mturquette@baylibre.com>
>>> Cc: Stephen Boyd <sboyd@codeaurora.org>
>>
>> +Cc Laurent, linux-renesas
>>
>>> ---
>>> V2: - Drop address-cells and size-cells from the binding
>>> - Add clock-names to the binding
>>> - Drop vc5_input_names
>>> - Fix assortment of spelling mistakes
>>> - Switch div_frc and div_int datatype to uXX
>>> - Switch f_in to u32
>>> - Add missing remove
>>> - Define macros for handling XIN and CLKIN
>>> - Rework the FOD fractional divider calculation, this was wrong
>>> and made the output clock be off considerably under certain
>>> circumstances (when the fractional part was large).
>>>
>>> V3: - Rework the MUX frequency recalculation and divider configration
>>> so that it fits into the clock framework
>>> - Add support for 5P49V5933 chip to lay groundwork for adding more
>>> chips easily.
>>> - Export the OUT0_SEL_I2CB output into the clock framework, so it
>>> can be accessed from DT as well. WARNING: This does change the
>>> bindings, clock0 is now the OUT0_SEL_I2CB, clock1 is OUT1 and
>>> clock2 is OUT2 (or OUT4 on the 5P49V5933).
>>> - Drop unnecessary caching of pin_*_name clock name and clk_hw
>>> structures in driver data.
>>> - Add missing MAINTAINERS entry
>>>
>>> V4: - Support also 5P49V5923A by dropping the B from the bindings and
>>> code. According to the update notice, the chips are identical
>>> except for disabling the VCO monitoring, which is internal
>>> factory-defined bit and has no impact on silicon performance.
>>>
>>> ---
>>>
>>> .../devicetree/bindings/clock/idt,versaclock5.txt | 43 ++
>
> If you decide to split the bindings in a separate patch as often requested by
> the DT reviewers,
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> for them. Please see below for more comments.
>
>>> MAINTAINERS | 5 +
>>> drivers/clk/Kconfig | 10 +
>>> drivers/clk/Makefile | 1 +
>>> drivers/clk/clk-versaclock5.c | 821 ++++++++++++++++
>>> 5 files changed, 880 insertions(+)
>>> create mode 100644
>>> Documentation/devicetree/bindings/clock/idt,versaclock5.txt create mode
>>> 100644 drivers/clk/clk-versaclock5.c
>
> [snip]
>
>>> diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
>>> new file mode 100644
>>> index 000000000000..14f518e84d6d
>>> --- /dev/null
>>> +++ b/drivers/clk/clk-versaclock5.c
>
> [snip]
>
>>> +/*
>>> + * VersaClock5 i2c regmap
>>> + */
>>> +static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
>>> +{
>>> + /* Factory reserved regs, make them read-only */
>>> + if (reg >= 0 && reg <= 0xf)
>
> reg is unsigned, it will always be >= 0. You can drop the first part of the
> condition.
Fixed
>>> + return false;
>>> +
>>> + /* Factory reserved regs, make them read-only */
>>> + if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
>>> + return false;
>>> +
>>> + return true;
>>> +}
>
> [snip]
>
>>> +static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate,
>>> + unsigned long *parent_rate)
>>> +{
>>> + unsigned long idiv;
>>> +
>>> + /* PLL cannot operate with input clock above 50 MHz. */
>>> + if (rate > 50000000)
>>> + return -EINVAL;
>
> As this is a PLL constraint, shouldn't it be enforced by vc5_pll_round_rate()
> instead ?
vc5_pll_round_rate can only enforce PLL output frequency, not input
frequency AFAICT .
>>> + /* CLKIN within range of PLL input, feed directly to PLL. */
>>> + if (*parent_rate <= 50000000)
>>> + return *parent_rate;
>>> +
>>> + idiv = DIV_ROUND_UP(*parent_rate, rate);
>>> + if (idiv > 127)
>>> + return -EINVAL;
>>> +
>>> + return *parent_rate / idiv;
>>> +}
[...]
>>> +static struct clk_hw *
>>> +vc5_of_clk_get(struct of_phandle_args *clkspec, void *data)
>>> +{
>>> + struct vc5_driver_data *vc5 = data;
>>> + unsigned int idx = clkspec->args[0];
>>> +
>>> + if (idx > 2) {
>>> + pr_err("%s: invalid index %u\n", __func__, idx);
>
> Does this deserve an error message ?
I think it does, the driver will yell if you use incorrect index in the
bindings.
>>> + return ERR_PTR(-EINVAL);
>>> + }
>>> +
>>> + return &vc5->clk_out[idx].hw;
>>> +}
>>> +
>>> +static int vc5_map_index_to_output(const enum vc5_model model,
>>> + const unsigned int n)
>>> +{
>>> + switch (model) {
>>> + case IDT_VC5_5P49V5923:
>>> + if (n == 0) /* OUT1 */
>>> + return 0;
>>> + if (n == 1) /* OUT2 */
>>> + return 1;
>>> + break;
>>> + case IDT_VC5_5P49V5933:
>>> + if (n == 0) /* OUT1 */
>>> + return 0;
>>> + if (n == 1) /* OUT4 */
>>> + return 3;
>>> + break;
>>> + }
>>> +
>>> + /*
>>> + * If we got here, there is certainly a bug in the driver,
>>> + * but we shouldn't crash the kernel.
>>> + */
>>> + WARN_ON("Invalid clock index!\n");
>>> + return -EINVAL;
>
> I don't think that's needed. The function is called from two locations only,
> and they're both very easy to audit. You can just return n in the
> IDT_VC5_5P49V5923 case and return n == 0 ? 0 : 3 in the other case.
OK, dropped and fixed.
>>> +}
>
> [snip]
>
>>> +static int vc5_probe(struct i2c_client *client,
>>> + const struct i2c_device_id *id)
>>> +{
>>> + const struct of_device_id *of_id =
>>> + of_match_device(clk_vc5_of_match, &client->dev);
>>> + struct vc5_driver_data *vc5;
>>> + struct clk_init_data init;
>>> + const char *parent_names[2];
>>> + unsigned int n, idx;
>>> + int ret;
>>> +
>>> + vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
>>> + if (vc5 == NULL)
>>> + return -ENOMEM;
>>> +
>>> + i2c_set_clientdata(client, vc5);
>>> + vc5->client = client;
>>> + vc5->model = (enum vc5_model)of_id->data;
>>> +
>>> + vc5->pin_xin = devm_clk_get(&client->dev, "xin");
>>> + if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
>>> + return -EPROBE_DEFER;
>>> +
>>> + vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
>>> + if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
>>> + return -EPROBE_DEFER;
>>> +
>>> + vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
>>> + if (IS_ERR(vc5->regmap)) {
>>> + dev_err(&client->dev, "failed to allocate register map\n");
>>> + return PTR_ERR(vc5->regmap);
>>> + }
>>> +
>>> + /* Register clock input mux */
>>> + memset(&init, 0, sizeof(init));
>>> +
>>> + if (!IS_ERR(vc5->pin_xin)) {
>>> + clk_prepare_enable(vc5->pin_xin);
>
> Given that the CCF core will take care of enabling/disabling parents as
> needed, do you need this ?
It should, so, dropped.
[...]
--
Best regards,
Marek Vasut
next prev parent reply other threads:[~2017-01-11 15:53 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-10 18:50 [PATCH V4] clk: vc5: Add support for IDT VersaClock 5P49V5923 and 5P49V5933 Marek Vasut
2017-01-11 14:37 ` Marek Vasut
2017-01-11 15:41 ` Laurent Pinchart
2017-01-11 15:53 ` Marek Vasut [this message]
2017-01-11 16:42 ` Laurent Pinchart
2017-01-11 22:05 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f1a287f5-6050-2e19-99c9-e17972e4db88@gmail.com \
--to=marek.vasut@gmail.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-clk@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=sboyd@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox