All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafał Miłecki" <zajec5@gmail.com>
To: Stephen Boyd <sboyd@codeaurora.org>
Cc: "Michael Turquette" <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org,
	bcm-kernel-feedback-list <bcm-kernel-feedback-list@broadcom.com>,
	"Rafał Miłecki" <rafal@milecki.pl>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Eric Anholt" <eric@anholt.net>,
	"Jon Mason" <jonmason@broadcom.com>,
	"Florian Fainelli" <f.fainelli@gmail.com>,
	"Stephen Warren" <swarren@wwwdotorg.org>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS"
	<devicetree@vger.kernel.org>,
	"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH V5] clk: bcm: Add driver for BCM53573 ILP clock
Date: Thu, 25 Aug 2016 15:28:04 +0200	[thread overview]
Message-ID: <CACna6rwB8bPMqZ8Gz5x8WVMeB83T3J=D7dXsDpMO8YdNHFSKaA@mail.gmail.com> (raw)
In-Reply-To: <20160824084738.GB6502@codeaurora.org>

On 24 August 2016 at 10:47, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 08/23, Rafał Miłecki wrote:
>> diff --git a/drivers/clk/bcm/clk-bcm53573-ilp.c b/drivers/clk/bcm/clk-bcm53573-ilp.c
>> new file mode 100644
>> index 0000000..b7ac0eb
>> --- /dev/null
>> +++ b/drivers/clk/bcm/clk-bcm53573-ilp.c
>> @@ -0,0 +1,146 @@
>> +/*
>> + * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/clk.h>
>
> Is this include used?

No. Good point.


>> +#include <linux/clk-provider.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/slab.h>
>> +
>> +#define PMU_XTAL_FREQ_RATIO                  0x66c
>> +#define  XTAL_ALP_PER_4ILP                   0x00001fff
>> +#define  XTAL_CTL_EN                         0x80000000
>> +#define PMU_SLOW_CLK_PERIOD                  0x6dc
>> +
>> +struct bcm53573_ilp {
>> +     struct clk *clk;
>> +     struct clk_hw hw;
>> +     void __iomem *pmu;
>> +};
>> +
>> +static int bcm53573_ilp_enable(struct clk_hw *hw)
>> +{
>> +     struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
>> +
>> +     writel(0x10199, ilp->pmu + PMU_SLOW_CLK_PERIOD);
>> +     writel(0x10000, ilp->pmu + 0x674);
>
> Is there a name for 0x674?
>> +
>> +     return 0;
>> +}
>> +
>> +static unsigned long bcm53573_ilp_recalc_rate(struct clk_hw *hw,
>> +                                           unsigned long parent_rate)
>> +{
>> +     struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
>> +     void __iomem *pmu = ilp->pmu;
>> +     u32 last_val, cur_val;
>> +     u32 sum = 0, num = 0, loop_num = 0;
>
> Should these just be plain ints? Do we care about sizes for these
> variables?
>
>> +     u32 avg;
>
> This one too.

Right.


>> +
>> +     /* Enable measurement */
>> +     writel(XTAL_CTL_EN, pmu + PMU_XTAL_FREQ_RATIO);
>> +
>> +     /* Read initial value */
>> +     last_val = readl(pmu + PMU_XTAL_FREQ_RATIO) & XTAL_ALP_PER_4ILP;
>> +
>> +     /*
>> +      * At minimum we should loop for a bit to let hardware do the
>> +      * measurement. This isn't very accurate however, so for a better
>> +      * precision lets try getting 20 different values for and use average.
>> +      */
>> +     while (num < 20) {
>> +             cur_val = readl(pmu + PMU_XTAL_FREQ_RATIO) & XTAL_ALP_PER_4ILP;
>> +
>> +             if (cur_val != last_val) {
>> +                     /* Got different value, use it */
>> +                     sum += cur_val;
>> +                     num++;
>> +                     loop_num = 0;
>> +                     last_val = cur_val;
>> +             } else if (++loop_num > 5000) {
>> +                     /* Same value over and over, give up */
>> +                     sum += cur_val;
>> +                     num++;
>> +                     break;
>> +             }
>
> Should there be a udelay() here? Or we're expected to tight loop
> read the hardware? If so we should throw in a cpu_relax() here to
> indicate tight loop.
>
>> +     }
>> +
>> +     /* Disable measurement to save power */
>> +     writel(0x0, pmu + PMU_XTAL_FREQ_RATIO);
>> +
>> +     avg = sum / num;
>> +
>> +     return parent_rate * 4 / avg;
>> +}
>> +
>> +static const struct clk_ops bcm53573_ilp_clk_ops = {
>> +     .enable = bcm53573_ilp_enable,
>
> No disable? Or .is_enabled?

The beauty of working without datasheets... I'll compare initial reg
state with one after enabling and see if there is sth obvious.


>> +     .recalc_rate = bcm53573_ilp_recalc_rate,
>> +};
>> +
>> +static void bcm53573_ilp_init(struct device_node *np)
>> +{
>> +     struct bcm53573_ilp *ilp;
>> +     struct resource res;
>> +     struct clk_init_data init = { 0 };
>> +     const char *parent_name;
>> +     int index;
>> +     int err;
>> +
>> +     ilp = kzalloc(sizeof(*ilp), GFP_KERNEL);
>> +     if (!ilp)
>> +             return;
>> +
>> +     parent_name = of_clk_get_parent_name(np, 0);
>> +     if (!parent_name) {
>> +             err = -ENOENT;
>> +             goto err_free_ilp;
>> +     }
>> +
>> +     /* TODO: This looks generic, try making it OF helper. */
>> +     index = of_property_match_string(np, "reg-names", "pmu");
>> +     if (index < 0) {
>> +             err = index;
>> +             goto err_free_ilp;
>> +     }
>> +     err = of_address_to_resource(np, index, &res);
>> +     if (err)
>> +             goto err_free_ilp;
>> +     ilp->pmu = ioremap(res.start, resource_size(&res));
>> +     if (IS_ERR(ilp->pmu)) {
>> +             err = PTR_ERR(ilp->pmu);
>> +             goto err_free_ilp;
>> +     }
>> +
>> +     init.name = np->name;
>> +     init.ops = &bcm53573_ilp_clk_ops;
>> +     init.parent_names = &parent_name;
>> +     init.num_parents = 1;
>> +
>> +     ilp->hw.init = &init;
>> +     ilp->clk = clk_register(NULL, &ilp->hw);
>
> please use clk_hw_register() and of_clk_add_hw_provider().

I wasn't aware of this API change, thanks.


>> +     if (WARN_ON(IS_ERR(ilp->clk)))
>> +             goto err_unmap_pmu;
>> +
>> +     err = of_clk_add_provider(np, of_clk_src_simple_get, ilp->clk);
>> +     if (err)
>> +             goto err_clk_unregister;
>> +
>> +     return;
>> +
>> +err_clk_unregister:
>> +     clk_unregister(ilp->clk);
>> +err_unmap_pmu:
>> +     iounmap(ilp->pmu);
>> +err_free_ilp:
>> +     kfree(ilp);
>> +     pr_err("Failed to init ILP clock: %d\n", err);
>> +}
>> +CLK_OF_DECLARE(bcm53573_ilp_clk, "brcm,bcm53573-ilp", bcm53573_ilp_init);
>
> Can this be a platform driver instead?

I guess it can. Should it? It's not clear to me when CLK_OF_DECLARE is
preferred and when it's not.

-- 
Rafał

WARNING: multiple messages have this Message-ID (diff)
From: "Rafał Miłecki" <zajec5@gmail.com>
To: Stephen Boyd <sboyd@codeaurora.org>
Cc: "Michael Turquette" <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org,
	bcm-kernel-feedback-list <bcm-kernel-feedback-list@broadcom.com>,
	"Rafał Miłecki" <rafal@milecki.pl>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Eric Anholt" <eric@anholt.net>,
	"Jon Mason" <jonmason@broadcom.com>,
	"Florian Fainelli" <f.fainelli@gmail.com>,
	"Stephen Warren" <swarren@wwwdotorg.org>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS"
	<devicetree@vger.kernel.org>,
	"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH V5] clk: bcm: Add driver for BCM53573 ILP clock
Date: Thu, 25 Aug 2016 15:28:04 +0200	[thread overview]
Message-ID: <CACna6rwB8bPMqZ8Gz5x8WVMeB83T3J=D7dXsDpMO8YdNHFSKaA@mail.gmail.com> (raw)
In-Reply-To: <20160824084738.GB6502@codeaurora.org>

On 24 August 2016 at 10:47, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 08/23, Rafa=C5=82 Mi=C5=82ecki wrote:
>> diff --git a/drivers/clk/bcm/clk-bcm53573-ilp.c b/drivers/clk/bcm/clk-bc=
m53573-ilp.c
>> new file mode 100644
>> index 0000000..b7ac0eb
>> --- /dev/null
>> +++ b/drivers/clk/bcm/clk-bcm53573-ilp.c
>> @@ -0,0 +1,146 @@
>> +/*
>> + * Copyright (C) 2016 Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/clk.h>
>
> Is this include used?

No. Good point.


>> +#include <linux/clk-provider.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/slab.h>
>> +
>> +#define PMU_XTAL_FREQ_RATIO                  0x66c
>> +#define  XTAL_ALP_PER_4ILP                   0x00001fff
>> +#define  XTAL_CTL_EN                         0x80000000
>> +#define PMU_SLOW_CLK_PERIOD                  0x6dc
>> +
>> +struct bcm53573_ilp {
>> +     struct clk *clk;
>> +     struct clk_hw hw;
>> +     void __iomem *pmu;
>> +};
>> +
>> +static int bcm53573_ilp_enable(struct clk_hw *hw)
>> +{
>> +     struct bcm53573_ilp *ilp =3D container_of(hw, struct bcm53573_ilp,=
 hw);
>> +
>> +     writel(0x10199, ilp->pmu + PMU_SLOW_CLK_PERIOD);
>> +     writel(0x10000, ilp->pmu + 0x674);
>
> Is there a name for 0x674?
>> +
>> +     return 0;
>> +}
>> +
>> +static unsigned long bcm53573_ilp_recalc_rate(struct clk_hw *hw,
>> +                                           unsigned long parent_rate)
>> +{
>> +     struct bcm53573_ilp *ilp =3D container_of(hw, struct bcm53573_ilp,=
 hw);
>> +     void __iomem *pmu =3D ilp->pmu;
>> +     u32 last_val, cur_val;
>> +     u32 sum =3D 0, num =3D 0, loop_num =3D 0;
>
> Should these just be plain ints? Do we care about sizes for these
> variables?
>
>> +     u32 avg;
>
> This one too.

Right.


>> +
>> +     /* Enable measurement */
>> +     writel(XTAL_CTL_EN, pmu + PMU_XTAL_FREQ_RATIO);
>> +
>> +     /* Read initial value */
>> +     last_val =3D readl(pmu + PMU_XTAL_FREQ_RATIO) & XTAL_ALP_PER_4ILP;
>> +
>> +     /*
>> +      * At minimum we should loop for a bit to let hardware do the
>> +      * measurement. This isn't very accurate however, so for a better
>> +      * precision lets try getting 20 different values for and use aver=
age.
>> +      */
>> +     while (num < 20) {
>> +             cur_val =3D readl(pmu + PMU_XTAL_FREQ_RATIO) & XTAL_ALP_PE=
R_4ILP;
>> +
>> +             if (cur_val !=3D last_val) {
>> +                     /* Got different value, use it */
>> +                     sum +=3D cur_val;
>> +                     num++;
>> +                     loop_num =3D 0;
>> +                     last_val =3D cur_val;
>> +             } else if (++loop_num > 5000) {
>> +                     /* Same value over and over, give up */
>> +                     sum +=3D cur_val;
>> +                     num++;
>> +                     break;
>> +             }
>
> Should there be a udelay() here? Or we're expected to tight loop
> read the hardware? If so we should throw in a cpu_relax() here to
> indicate tight loop.
>
>> +     }
>> +
>> +     /* Disable measurement to save power */
>> +     writel(0x0, pmu + PMU_XTAL_FREQ_RATIO);
>> +
>> +     avg =3D sum / num;
>> +
>> +     return parent_rate * 4 / avg;
>> +}
>> +
>> +static const struct clk_ops bcm53573_ilp_clk_ops =3D {
>> +     .enable =3D bcm53573_ilp_enable,
>
> No disable? Or .is_enabled?

The beauty of working without datasheets... I'll compare initial reg
state with one after enabling and see if there is sth obvious.


>> +     .recalc_rate =3D bcm53573_ilp_recalc_rate,
>> +};
>> +
>> +static void bcm53573_ilp_init(struct device_node *np)
>> +{
>> +     struct bcm53573_ilp *ilp;
>> +     struct resource res;
>> +     struct clk_init_data init =3D { 0 };
>> +     const char *parent_name;
>> +     int index;
>> +     int err;
>> +
>> +     ilp =3D kzalloc(sizeof(*ilp), GFP_KERNEL);
>> +     if (!ilp)
>> +             return;
>> +
>> +     parent_name =3D of_clk_get_parent_name(np, 0);
>> +     if (!parent_name) {
>> +             err =3D -ENOENT;
>> +             goto err_free_ilp;
>> +     }
>> +
>> +     /* TODO: This looks generic, try making it OF helper. */
>> +     index =3D of_property_match_string(np, "reg-names", "pmu");
>> +     if (index < 0) {
>> +             err =3D index;
>> +             goto err_free_ilp;
>> +     }
>> +     err =3D of_address_to_resource(np, index, &res);
>> +     if (err)
>> +             goto err_free_ilp;
>> +     ilp->pmu =3D ioremap(res.start, resource_size(&res));
>> +     if (IS_ERR(ilp->pmu)) {
>> +             err =3D PTR_ERR(ilp->pmu);
>> +             goto err_free_ilp;
>> +     }
>> +
>> +     init.name =3D np->name;
>> +     init.ops =3D &bcm53573_ilp_clk_ops;
>> +     init.parent_names =3D &parent_name;
>> +     init.num_parents =3D 1;
>> +
>> +     ilp->hw.init =3D &init;
>> +     ilp->clk =3D clk_register(NULL, &ilp->hw);
>
> please use clk_hw_register() and of_clk_add_hw_provider().

I wasn't aware of this API change, thanks.


>> +     if (WARN_ON(IS_ERR(ilp->clk)))
>> +             goto err_unmap_pmu;
>> +
>> +     err =3D of_clk_add_provider(np, of_clk_src_simple_get, ilp->clk);
>> +     if (err)
>> +             goto err_clk_unregister;
>> +
>> +     return;
>> +
>> +err_clk_unregister:
>> +     clk_unregister(ilp->clk);
>> +err_unmap_pmu:
>> +     iounmap(ilp->pmu);
>> +err_free_ilp:
>> +     kfree(ilp);
>> +     pr_err("Failed to init ILP clock: %d\n", err);
>> +}
>> +CLK_OF_DECLARE(bcm53573_ilp_clk, "brcm,bcm53573-ilp", bcm53573_ilp_init=
);
>
> Can this be a platform driver instead?

I guess it can. Should it? It's not clear to me when CLK_OF_DECLARE is
preferred and when it's not.

--=20
Rafa=C5=82

  reply	other threads:[~2016-08-25 13:41 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-10 12:05 [PATCH V3] clk: bcm: Add driver for Northstar ILP clock Rafał Miłecki
2016-08-10 12:05 ` Rafał Miłecki
2016-08-10 17:22 ` Jon Mason
2016-08-10 17:22   ` Jon Mason
2016-08-10 17:28   ` Rafał Miłecki
2016-08-10 17:28     ` Rafał Miłecki
2016-08-10 17:44     ` Ray Jui
2016-08-10 18:21       ` Jon Mason
2016-08-10 18:21         ` Jon Mason
2016-08-11  8:49         ` Rafał Miłecki
2016-08-11  8:49           ` Rafał Miłecki
2016-08-11 14:25           ` Jon Mason
2016-08-11 14:25             ` Jon Mason
2016-08-12  6:26             ` Rafał Miłecki
2016-08-12  6:26               ` Rafał Miłecki
2016-08-23  6:17 ` [PATCH V4] clk: bcm: Add driver for BCM53573 " Rafał Miłecki
2016-08-23  6:17   ` Rafał Miłecki
2016-08-23  6:25   ` [PATCH V5] " Rafał Miłecki
2016-08-23  6:25     ` Rafał Miłecki
2016-08-23 19:55     ` Rob Herring
2016-08-25 12:42       ` Rafał Miłecki
2016-08-25 12:42         ` Rafał Miłecki
2016-08-25 12:42         ` Rafał Miłecki
2016-08-31 16:16         ` Rob Herring
2016-09-05 12:12           ` Rafał Miłecki
2016-09-05 12:12             ` Rafał Miłecki
2016-09-05 12:12             ` Rafał Miłecki
2016-08-24  8:47     ` Stephen Boyd
2016-08-24  8:47       ` Stephen Boyd
2016-08-25 13:28       ` Rafał Miłecki [this message]
2016-08-25 13:28         ` Rafał Miłecki
2016-08-25 19:57         ` Stephen Boyd
2016-08-25 14:11       ` Rafał Miłecki
2016-08-25 14:11         ` Rafał Miłecki
2016-08-25 19:58         ` Stephen Boyd
2016-08-26 12:25     ` [PATCH V6] " Rafał Miłecki
2016-08-26 12:25       ` Rafał Miłecki
2016-09-05 14:29       ` [PATCH V7] " Rafał Miłecki
2016-09-05 14:29         ` Rafał Miłecki
2016-09-12 16:56         ` Rob Herring
2016-09-13  7:06         ` [PATCH V8] " Rafał Miłecki
2016-09-13  7:06           ` Rafał Miłecki
2016-09-14 23:44           ` Rob Herring
2016-09-14 23:44             ` Rob Herring
2016-09-14 23:44             ` Rob Herring
2016-09-16 23:23           ` Stephen Boyd
2016-09-16 23:23             ` Stephen Boyd
2016-09-17 19:20             ` Rafał Miłecki
2016-09-17 19:20               ` Rafał Miłecki
2016-09-17 19:20               ` Rafał Miłecki

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='CACna6rwB8bPMqZ8Gz5x8WVMeB83T3J=D7dXsDpMO8YdNHFSKaA@mail.gmail.com' \
    --to=zajec5@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=devicetree@vger.kernel.org \
    --cc=eric@anholt.net \
    --cc=f.fainelli@gmail.com \
    --cc=jonmason@broadcom.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=rafal@milecki.pl \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    --cc=swarren@wwwdotorg.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.