From: "Heiko Stübner" <heiko@sntech.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 9/9] rockchip: rk3188: Add clock driver
Date: Sun, 17 Jul 2016 17:33:41 +0200 [thread overview]
Message-ID: <3005812.9fWFW3yNq8@diego> (raw)
In-Reply-To: <CAPnjgZ2S3STs+QDfNS1KO9Kfktg-D4ttKdXiQ51Dw-PL-Vo-gg@mail.gmail.com>
Am Sonntag, 17. Juli 2016, 08:13:58 schrieb Simon Glass:
> Hi Heiko,
>
> On 15 July 2016 at 16:17, Heiko Stuebner <heiko@sntech.de> wrote:
> > Add a driver for setting up and modifying the various PLLs and peripheral
> > clocks on the RK3188.
> >
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> >
> > arch/arm/include/asm/arch-rockchip/cru_rk3188.h | 186 ++++++++++
> > drivers/clk/Makefile | 1 +
> > drivers/clk/clk_rk3188.c | 464
> > ++++++++++++++++++++++++ 3 files changed, 651 insertions(+)
> > create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3188.h
> > create mode 100644 drivers/clk/clk_rk3188.c
>
> Could you add a patch to move these files into a drivers/clk/rockchip
> directory?
ok
> > new file mode 100644
> > index 0000000..4c28393
> > --- /dev/null
> > +++ b/drivers/clk/clk_rk3188.c
> > @@ -0,0 +1,465 @@
> > +/*
> > + * (C) Copyright 2015 Google, Inc
> > + * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
> > + *
> > + * SPDX-License-Identifier: GPL-2.0
> > + */
> > +
> > +#include <common.h>
> > +#include <clk-uclass.h>
> > +#include <dm.h>
> > +#include <errno.h>
> > +#include <syscon.h>
> > +#include <asm/io.h>
> > +#include <asm/arch/clock.h>
> > +#include <asm/arch/cru_rk3188.h>
> > +#include <asm/arch/grf_rk3188.h>
> > +#include <asm/arch/hardware.h>
> > +#include <dt-bindings/clock/rk3188-cru.h>
> > +#include <dm/device-internal.h>
> > +#include <dm/lists.h>
> > +#include <dm/uclass-internal.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +struct rk3188_clk_priv {
> > + struct rk3188_grf *grf;
> > + struct rk3188_cru *cru;
> > + ulong rate;
> > + bool has_bwadj;
> > +};
> > +
> > +struct pll_div {
> > + u32 nr;
> > + u32 nf;
> > + u32 no;
> > +};
> > +
> > +enum {
> > + VCO_MAX_HZ = 2200U * 1000000,
> > + VCO_MIN_HZ = 440 * 1000000,
> > + OUTPUT_MAX_HZ = 2200U * 1000000,
> > + OUTPUT_MIN_HZ = 30 * 1000000,
> > + FREF_MAX_HZ = 2200U * 1000000,
> > + FREF_MIN_HZ = 30 * 1000,
> > +};
> > +
> > +enum {
> > + /* PLL CON0 */
> > + PLL_OD_MASK = 0x0f,
> > +
> > + /* PLL CON1 */
> > + PLL_NF_MASK = 0x1fff,
> > +
> > + /* PLL CON2 */
> > + PLL_BWADJ_MASK = 0x0fff,
> > +
> > + /* PLL CON3 */
> > + PLL_RESET_SHIFT = 5,
> > +
> > + /* GRF_SOC_STATUS0 */
> > + SOCSTS_DPLL_LOCK = 1 << 5,
> > + SOCSTS_APLL_LOCK = 1 << 6,
> > + SOCSTS_CPLL_LOCK = 1 << 7,
> > + SOCSTS_GPLL_LOCK = 1 << 8,
> > +};
> > +
> > +#define RATE_TO_DIV(input_rate, output_rate) \
> > + ((input_rate) / (output_rate) - 1);
> > +
> > +#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
> > +
> > +#define PLL_DIVISORS(hz, _nr, _no) {\
> > + .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
> > + _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
> > + (_nr * _no) == hz, #hz "Hz cannot be hit with PLL
> > "\
> > + "divisors on line " __stringify(__LINE__));
> > +
> > +/* Keep divisors as low as possible to reduce jitter and power usage */
> > +static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
> > +static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
> > +static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
> > +
> > +void *rockchip_get_cru(void)
> > +{
> > + struct rk3188_clk_priv *priv;
> > + struct udevice *dev;
> > + int ret;
> > +
> > + ret = uclass_get_device_by_name(UCLASS_CLK,
> > + "clock-controller at 20000000",
> > &dev);
>
> This seems odd. Could you use uclass_get_device(UCLASS_CLK, 0, .&dev) ?
Index 0 actually gets me the 24MHz oscillator fixed clock :-), which is why I
switched to the by-name variant to not depend on some dts or uclass ordering.
I'm wondering how that works on the other socs.
>
> > + if (ret)
> > + return ERR_PTR(ret);
> > +
> > + priv = dev_get_priv(dev);
> > +
> > + return priv->cru;
> > +}
> > +
> > +static int rkclk_set_pll(struct rk3188_cru *cru, enum rk_clk_id clk_id,
> > + const struct pll_div *div, bool has_bwadj)
> > +{
> > + int pll_id = rk_pll_id(clk_id);
> > + struct rk3188_pll *pll = &cru->pll[pll_id];
> > + /* All PLLs have same VCO and output frequency range restrictions.
> > */ + uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
> > + uint output_hz = vco_hz / div->no;
> > +
> > + debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
> > + (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
> > + assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
> > + output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
> > + (div->no == 1 || !(div->no % 2)));
> > +
> > + /* enter reset */
> > + rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
> > +
> > + rk_clrsetreg(&pll->con0,
> > + CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
> > + ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
> > + rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
> > +
> > + if (has_bwadj)
> > + rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) -
> > 1); +
> > + udelay(10);
> > +
> > + /* return from reset */
> > + rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
> > +
> > + return 0;
> > +}
> > +
> > +static inline unsigned int log2(unsigned int value)
>
> Hmm this should go in a common file. Perhaps bitfield.h or common.h?
it looks like uboot is already carrying ilog2() in include/linux/log2.h ?
[...]
> > +static int rk3188_clk_probe(struct udevice *dev)
> > +{
> > + struct rk3188_clk_priv *priv = dev_get_priv(dev);
> > +
> > + priv->cru = (struct rk3188_cru *)dev_get_addr(dev);
> > + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
> > + priv->has_bwadj = of_device_is_compatible(dev,
> > "rockchip,rk3188a-cru") + ? 1 : 0;
>
> You should add a .data member to your udevice_id array below using a
> two-member enum, and check dev_get_driver_data() here.
ah, nice to know. I was wondering if and how uboot was handling .data stuff
but my short skimming through the sources didn't reveal that. Will change.
Heiko
next prev parent reply other threads:[~2016-07-17 15:33 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-15 22:17 [U-Boot] [PATCH 0/9] rockchip: cosmetics, a fix and first steps on the rk3188 Heiko Stuebner
2016-07-15 22:17 ` [U-Boot] [PATCH 1/9] cosmetic: rockchip: rk3288: pinctrl: fix config symbol naming Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 2/9] cosmetic: rockchip: rk3036: " Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 3/9] cosmetic: rockchip: sort socs according to numbers Heiko Stuebner
2016-07-16 15:47 ` Andreas Färber
2016-07-17 14:13 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 4/9] cosmetic: rockchip: rk3288: rename rkclk_configure_cpu Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 5/9] rockchip: rk3288: fix FREF_MIN_HZ constant Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 6/9] rockchip: rk3188: Add header files for PMU and GRF Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 7/9] rockchip: rk3188: Add pinctrl driver Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-17 15:47 ` Heiko Stübner
2016-07-17 15:49 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 8/9] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-15 22:17 ` [U-Boot] [PATCH 9/9] rockchip: rk3188: Add clock driver Heiko Stuebner
2016-07-17 14:13 ` Simon Glass
2016-07-17 15:33 ` Heiko Stübner [this message]
2016-07-17 15:48 ` Simon Glass
2016-07-18 13:31 ` Simon Glass
2016-07-17 14:14 ` [U-Boot] [PATCH 0/9] rockchip: cosmetics, a fix and first steps on the rk3188 Simon Glass
2016-07-17 15:20 ` Heiko Stübner
2016-07-17 15:27 ` Simon Glass
2016-07-18 12:16 ` Simon Glass
2016-07-18 13:42 ` Heiko Stübner
2016-07-20 14:19 ` Simon Glass
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=3005812.9fWFW3yNq8@diego \
--to=heiko@sntech.de \
--cc=u-boot@lists.denx.de \
/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