[U-Boot] [PATCH v3 3/9] clk: actions: Add common clock driver
Manivannan Sadhasivam
manivannan.sadhasivam at linaro.org
Thu Jan 17 15:15:44 UTC 2019
Hi,
On Tue, Jan 15, 2019 at 12:43:36AM +0000, André Przywara wrote:
> On 14/01/2019 12:41, Amit Singh Tomar wrote:
>
> Hi,
>
> > CMU block on most of the actions SoC seems to be identical(at-least, S900 and S700).
>
> Actually they are not. Not even for the small subset that we implement
> here. Try "diff -wu arch/arm/include/asm/arch-owl/regs_s*.h" for a
> start, plus the differences in the #ifdefs below.
>
> > This patch converts S900 clock driver to something common that can
> > be used for other SoCs, for instance S700(most of clk registres are same).
>
> I am not sure this is a viable approach, really.
> The driver claims to support both SoC's via their compatible strings,
> but in fact is just implementing the one configured via Kconfig.
> While we should be able to easily replace the #ifdefs with something
> checking the .data member associated with the respective .compatible
> string, it gets hairy with the #defines in regs_s[79]00.h.
> So either it's two different .c files, with the register definitions in
> there, or we change the CMU_* defines to CMU_S[79]00_* and include both.
>
> Maybe you could try this and report how it looks like?
> If half of the file is within if-else statements, separating is problem
> more worthwhile.
> Mani, you mentioned the S500, I guess this is even more different,
> right? Which would point into the "separate files" direction.
>
S500 is different in terms of the clock initializations. Ideally we should
have a minimal set of common clk driver like in Linux which I authored.
Otherwise, we should move forward with individual clk files for each
SoC. Having #ifdef's will definitely make the code look messy.
Thanks,
Mani
> >
> > Signed-off-by: Amit Singh Tomar <amittomer25 at gmail.com>
> > ---
> > Changes since v1:
> > * Moved CLK and CLK_OWL symbols from defconfig to arch/arm/Kconfig.
> > ---
> > arch/arm/Kconfig | 2 +
> > arch/arm/include/asm/arch-owl/clk_owl.h | 61 +++++++++++++
> > arch/arm/include/asm/arch-owl/clk_s900.h | 57 -------------
> > arch/arm/include/asm/arch-owl/regs_s700.h | 56 ++++++++++++
>
> This file doesn't define an interface, so should live in the
> drivers/clk/owl directory. Same with the regs_s900.h.
>
> > configs/bubblegum_96_defconfig | 3 -
> > drivers/clk/owl/Kconfig | 10 +--
> > drivers/clk/owl/Makefile | 2 +-
> > drivers/clk/owl/clk_owl.c | 132 ++++++++++++++++++++++++++++
> > drivers/clk/owl/clk_s900.c | 137 ------------------------------
> > 9 files changed, 255 insertions(+), 205 deletions(-)
> > create mode 100644 arch/arm/include/asm/arch-owl/clk_owl.h
> > delete mode 100644 arch/arm/include/asm/arch-owl/clk_s900.h
> > create mode 100644 arch/arm/include/asm/arch-owl/regs_s700.h
> > create mode 100644 drivers/clk/owl/clk_owl.c
> > delete mode 100644 drivers/clk/owl/clk_s900.c
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 1a2e561..1daf3bf 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -764,6 +764,8 @@ config ARCH_OWL
> > select DM
> > select DM_SERIAL
> > select OWL_SERIAL
> > + select CLK
> > + select CLK_OWL
> > select OF_CONTROL
> > imply CMD_DM
> >
> > diff --git a/arch/arm/include/asm/arch-owl/clk_owl.h b/arch/arm/include/asm/arch-owl/clk_owl.h
> > new file mode 100644
> > index 0000000..962badd
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-owl/clk_owl.h
> > @@ -0,0 +1,61 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * Actions Semi SoCs Clock Definitions
> > + *
> > + * Copyright (C) 2015 Actions Semi Co., Ltd.
> > + * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > + *
> > + */
> > +
> > +#ifndef _OWL_CLK_H_
> > +#define _OWL_CLK_H_
> > +
> > +#include <clk-uclass.h>
> > +
> > +struct owl_clk_priv {
> > + phys_addr_t base;
> > +};
> > +
> > +/* BUSCLK register definitions */
> > +#define CMU_PDBGDIV_8 7
> > +#define CMU_PDBGDIV_SHIFT 26
> > +#define CMU_PDBGDIV_DIV (CMU_PDBGDIV_8 << CMU_PDBGDIV_SHIFT)
> > +#define CMU_PERDIV_8 7
> > +#define CMU_PERDIV_SHIFT 20
> > +#define CMU_PERDIV_DIV (CMU_PERDIV_8 << CMU_PERDIV_SHIFT)
> > +#define CMU_NOCDIV_2 1
> > +#define CMU_NOCDIV_SHIFT 19
> > +#define CMU_NOCDIV_DIV (CMU_NOCDIV_2 << CMU_NOCDIV_SHIFT)
> > +#define CMU_DMMCLK_SRC_APLL 2
> > +#define CMU_DMMCLK_SRC_SHIFT 10
> > +#define CMU_DMMCLK_SRC (CMU_DMMCLK_SRC_APLL << CMU_DMMCLK_SRC_SHIFT)
> > +#define CMU_APBCLK_DIV BIT(8)
> > +#define CMU_NOCCLK_SRC BIT(7)
> > +#define CMU_AHBCLK_DIV BIT(4)
> > +#define CMU_CORECLK_MASK 3
> > +#define CMU_CORECLK_CPLL BIT(1)
> > +#define CMU_CORECLK_HOSC BIT(0)
> > +
> > +/* COREPLL register definitions */
> > +#define CMU_COREPLL_EN BIT(9)
> > +#define CMU_COREPLL_HOSC_EN BIT(8)
> > +#define CMU_COREPLL_OUT (1104 / 24)
> > +
> > +/* DEVPLL register definitions */
> > +#define CMU_DEVPLL_CLK BIT(12)
> > +#define CMU_DEVPLL_EN BIT(8)
> > +#define CMU_DEVPLL_OUT (660 / 6)
> > +
> > +/* UARTCLK register definitions */
> > +#define CMU_UARTCLK_SRC_DEVPLL BIT(16)
> > +
> > +/* DEVCLKEN1 register definitions */
> > +#if defined(CONFIG_MACH_S900)
>
> Meh.
>
> > +#define CMU_DEVCLKEN1_UART5 BIT(21)
> > +#elif defined(CONFIG_MACH_S700)
> > +#define CMU_DEVCLKEN1_UART3 BIT(11)
> > +#endif
> > +
> > +#define PLL_STABILITY_WAIT_US 50
> > +
> > +#endif
> > diff --git a/arch/arm/include/asm/arch-owl/clk_s900.h b/arch/arm/include/asm/arch-owl/clk_s900.h
> > deleted file mode 100644
> > index 88e88f7..0000000
> > --- a/arch/arm/include/asm/arch-owl/clk_s900.h
> > +++ /dev/null
> > @@ -1,57 +0,0 @@
> > -/* SPDX-License-Identifier: GPL-2.0+ */
> > -/*
> > - * Actions Semi S900 Clock Definitions
> > - *
> > - * Copyright (C) 2015 Actions Semi Co., Ltd.
> > - * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > - *
> > - */
> > -
> > -#ifndef _OWL_CLK_S900_H_
> > -#define _OWL_CLK_S900_H_
> > -
> > -#include <clk-uclass.h>
> > -
> > -struct owl_clk_priv {
> > - phys_addr_t base;
> > -};
> > -
> > -/* BUSCLK register definitions */
> > -#define CMU_PDBGDIV_8 7
> > -#define CMU_PDBGDIV_SHIFT 26
> > -#define CMU_PDBGDIV_DIV (CMU_PDBGDIV_8 << CMU_PDBGDIV_SHIFT)
> > -#define CMU_PERDIV_8 7
> > -#define CMU_PERDIV_SHIFT 20
> > -#define CMU_PERDIV_DIV (CMU_PERDIV_8 << CMU_PERDIV_SHIFT)
> > -#define CMU_NOCDIV_2 1
> > -#define CMU_NOCDIV_SHIFT 19
> > -#define CMU_NOCDIV_DIV (CMU_NOCDIV_2 << CMU_NOCDIV_SHIFT)
> > -#define CMU_DMMCLK_SRC_APLL 2
> > -#define CMU_DMMCLK_SRC_SHIFT 10
> > -#define CMU_DMMCLK_SRC (CMU_DMMCLK_SRC_APLL << CMU_DMMCLK_SRC_SHIFT)
> > -#define CMU_APBCLK_DIV BIT(8)
> > -#define CMU_NOCCLK_SRC BIT(7)
> > -#define CMU_AHBCLK_DIV BIT(4)
> > -#define CMU_CORECLK_MASK 3
> > -#define CMU_CORECLK_CPLL BIT(1)
> > -#define CMU_CORECLK_HOSC BIT(0)
> > -
> > -/* COREPLL register definitions */
> > -#define CMU_COREPLL_EN BIT(9)
> > -#define CMU_COREPLL_HOSC_EN BIT(8)
> > -#define CMU_COREPLL_OUT (1104 / 24)
> > -
> > -/* DEVPLL register definitions */
> > -#define CMU_DEVPLL_CLK BIT(12)
> > -#define CMU_DEVPLL_EN BIT(8)
> > -#define CMU_DEVPLL_OUT (660 / 6)
> > -
> > -/* UARTCLK register definitions */
> > -#define CMU_UARTCLK_SRC_DEVPLL BIT(16)
> > -
> > -/* DEVCLKEN1 register definitions */
> > -#define CMU_DEVCLKEN1_UART5 BIT(21)
> > -
> > -#define PLL_STABILITY_WAIT_US 50
> > -
> > -#endif
> > diff --git a/arch/arm/include/asm/arch-owl/regs_s700.h b/arch/arm/include/asm/arch-owl/regs_s700.h
> > new file mode 100644
> > index 0000000..a0bd737
> > --- /dev/null
> > +++ b/arch/arm/include/asm/arch-owl/regs_s700.h
> > @@ -0,0 +1,56 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * Actions Semi S700 Register Definitions
> > + *
> > + */
> > +
> > +#ifndef _OWL_REGS_S700_H_
> > +#define _OWL_REGS_S700_H_
> > +
> > +#define CMU_COREPLL (0x0000)
> > +#define CMU_DEVPLL (0x0004)
> > +#define CMU_DDRPLL (0x0008)
> > +#define CMU_NANDPLL (0x000C)
> > +#define CMU_DISPLAYPLL (0x0010)
> > +#define CMU_AUDIOPLL (0x0014)
> > +#define CMU_TVOUTPLL (0x0018)
> > +#define CMU_BUSCLK (0x001C)
> > +#define CMU_SENSORCLK (0x0020)
> > +#define CMU_LCDCLK (0x0024)
> > +#define CMU_DSIPLLCLK (0x0028)
> > +#define CMU_CSICLK (0x002C)
> > +#define CMU_DECLK (0x0030)
> > +#define CMU_SICLK (0x0034)
> > +#define CMU_BUSCLK1 (0x0038)
> > +#define CMU_HDECLK (0x003C)
> > +#define CMU_VDECLK (0x0040)
> > +#define CMU_VCECLK (0x0044)
> > +#define CMU_NANDCCLK (0x004C)
> > +#define CMU_SD0CLK (0x0050)
> > +#define CMU_SD1CLK (0x0054)
> > +#define CMU_SD2CLK (0x0058)
> > +#define CMU_UART0CLK (0x005C)
> > +#define CMU_UART1CLK (0x0060)
> > +#define CMU_UART2CLK (0x0064)
> > +#define CMU_UART3CLK (0x0068)
> > +#define CMU_UART4CLK (0x006C)
> > +#define CMU_UART5CLK (0x0070)
> > +#define CMU_UART6CLK (0x0074)
> > +#define CMU_PWM0CLK (0x0078)
> > +#define CMU_PWM1CLK (0x007C)
> > +#define CMU_PWM2CLK (0x0080)
> > +#define CMU_PWM3CLK (0x0084)
> > +#define CMU_PWM4CLK (0x0088)
> > +#define CMU_PWM5CLK (0x008C)
> > +#define CMU_GPU3DCLK (0x0090)
> > +#define CMU_CORECTL (0x009C)
> > +#define CMU_DEVCLKEN0 (0x00A0)
> > +#define CMU_DEVCLKEN1 (0x00A4)
> > +#define CMU_DEVRST0 (0x00A8)
> > +#define CMU_DEVRST1 (0x00AC)
> > +#define CMU_USBPLL (0x00B0)
> > +#define CMU_ETHERNETPLL (0x00B4)
> > +#define CMU_CVBSPLL (0x00B8)
> > +#define CMU_SSTSCLK (0x00C0)
> > +
> > +#endif
> > diff --git a/configs/bubblegum_96_defconfig b/configs/bubblegum_96_defconfig
> > index d1f403f..6803f04 100644
> > --- a/configs/bubblegum_96_defconfig
> > +++ b/configs/bubblegum_96_defconfig
> > @@ -15,6 +15,3 @@ CONFIG_CMD_MEMINFO=y
> > CONFIG_CMD_CACHE=y
> > CONFIG_CMD_TIMER=y
> > CONFIG_DEFAULT_DEVICE_TREE="bubblegum_96"
> > -CONFIG_CLK=y
> > -CONFIG_CLK_OWL=y
> > -CONFIG_CLK_S900=y
> > diff --git a/drivers/clk/owl/Kconfig b/drivers/clk/owl/Kconfig
> > index 661f198..dabac85 100644
> > --- a/drivers/clk/owl/Kconfig
> > +++ b/drivers/clk/owl/Kconfig
> > @@ -1,12 +1,8 @@
> > config CLK_OWL
> > bool "Actions Semi OWL clock drivers"
> > - depends on CLK && ARCH_OWL
> > + depends on CLK && ARCH_OWL && ARM64
>
> Why this change? Is there a 32-bit config that would break? I think even
> supporting the S500 would not work like this.
>
> > help
> > Enable support for clock managemet unit present in Actions Semi
> > - OWL SoCs.
> > + S900/S700 SoCs.
> > +
> >
> > -config CLK_S900
> > - bool "Actions Semi S900 clock driver"
> > - depends on CLK_OWL && ARM64
> > - help
> > - Enable support for the clocks in Actions Semi S900 SoC.
> > diff --git a/drivers/clk/owl/Makefile b/drivers/clk/owl/Makefile
> > index 63ab573..5218b6b 100644
> > --- a/drivers/clk/owl/Makefile
> > +++ b/drivers/clk/owl/Makefile
> > @@ -1,3 +1,3 @@
> > # SPDX-License-Identifier: GPL-2.0+
> >
> > -obj-$(CONFIG_CLK_S900) += clk_s900.o
> > +obj-$(CONFIG_CLK_OWL) += clk_owl.o
> > diff --git a/drivers/clk/owl/clk_owl.c b/drivers/clk/owl/clk_owl.c
> > new file mode 100644
> > index 0000000..f8d2102
> > --- /dev/null
> > +++ b/drivers/clk/owl/clk_owl.c
> > @@ -0,0 +1,132 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Common clock driver for Actions Semi SoCs.
> > + *
> > + * Copyright (C) 2015 Actions Semi Co., Ltd.
> > + * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > + */
> > +
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <asm/arch-owl/clk_owl.h>
> > +#include <asm/io.h>
> > +#if defined(CONFIG_MACH_S900)
> > +#include <asm/arch-owl/regs_s900.h>
> > +#elif defined(CONFIG_MACH_S700)
> > +#include <asm/arch-owl/regs_s700.h>
> > +#endif
> > +
> > +void owl_clk_init(struct owl_clk_priv *priv)
> > +{
> > + u32 bus_clk = 0, core_pll, dev_pll;
> > +
> > +#if defined(CONFIG_MACH_S900)
> > + /* Enable ASSIST_PLL */
> > + setbits_le32(priv->base + CMU_ASSISTPLL, BIT(0));
> > +
> > + udelay(PLL_STABILITY_WAIT_US);
> > +#endif
> > +
> > + /* Source HOSC to DEV_CLK */
> > + clrbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
> > +
> > + /* Configure BUS_CLK */
> > + bus_clk |= (CMU_PDBGDIV_DIV | CMU_PERDIV_DIV | CMU_NOCDIV_DIV |
> > + CMU_DMMCLK_SRC | CMU_APBCLK_DIV | CMU_AHBCLK_DIV |
> > + CMU_NOCCLK_SRC | CMU_CORECLK_HOSC);
> > + writel(bus_clk, priv->base + CMU_BUSCLK);
> > +
> > + udelay(PLL_STABILITY_WAIT_US);
> > +
> > + /* Configure CORE_PLL */
> > + core_pll = readl(priv->base + CMU_COREPLL);
> > + core_pll |= (CMU_COREPLL_EN | CMU_COREPLL_HOSC_EN | CMU_COREPLL_OUT);
> > + writel(core_pll, priv->base + CMU_COREPLL);
> > +
> > + udelay(PLL_STABILITY_WAIT_US);
> > +
> > + /* Configure DEV_PLL */
> > + dev_pll = readl(priv->base + CMU_DEVPLL);
> > + dev_pll |= (CMU_DEVPLL_EN | CMU_DEVPLL_OUT);
> > + writel(dev_pll, priv->base + CMU_DEVPLL);
> > +
> > + udelay(PLL_STABILITY_WAIT_US);
> > +
> > + /* Source CORE_PLL for CORE_CLK */
> > + clrsetbits_le32(priv->base + CMU_BUSCLK, CMU_CORECLK_MASK,
> > + CMU_CORECLK_CPLL);
> > +
> > + /* Source DEV_PLL for DEV_CLK */
> > + setbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
> > +
> > + udelay(PLL_STABILITY_WAIT_US);
> > +}
> > +
> > +int owl_clk_enable(struct clk *clk)
> > +{
> > + struct owl_clk_priv *priv = dev_get_priv(clk->dev);
> > +
> > +#if defined(CONFIG_MACH_S900)
>
> This is somewhat obsoleted by my above note, but this changes the code,
> so that owl_clk_enable/disable *always* affects the UART clock,
> regardless of the struct clk passed in.
> You would at least need to check for the clk->id.
>
> > + /* Source HOSC for UART5 interface */
> > + clrbits_le32(priv->base + CMU_UART5CLK, CMU_UARTCLK_SRC_DEVPLL);
> > +
> > + /* Enable UART5 interface clock */
> > + setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
> > +#elif defined(CONFIG_MACH_S700)
> > + /* Source HOSC for UART3 interface */
> > + clrbits_le32(priv->base + CMU_UART3CLK, CMU_UARTCLK_SRC_DEVPLL);
> > +
> > + /* Enable UART3 interface clock */
> > + setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART3);
> > +#endif
> > +
> > + return 0;
> > +}
> > +
> > +int owl_clk_disable(struct clk *clk)
> > +{
> > + struct owl_clk_priv *priv = dev_get_priv(clk->dev);
> > +#if defined(CONFIG_MACH_S900)
> > + /* Disable UART5 interface clock */
> > + clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
> > +#elif defined(CONFIG_MACH_S700)
> > + /* Disable UART3 interface clock */
> > + clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART3);
> > +#endif
> > +
> > + return 0;
> > +}
> > +
> > +static int owl_clk_probe(struct udevice *dev)
> > +{
> > + struct owl_clk_priv *priv = dev_get_priv(dev);
> > +
> > + priv->base = dev_read_addr(dev);
> > + if (priv->base == FDT_ADDR_T_NONE)
> > + return -EINVAL;
> > +
> > + /* setup necessary clocks */
> > + owl_clk_init(priv);
> > +
> > + return 0;
> > +}
> > +
> > +static struct clk_ops owl_clk_ops = {
> > + .enable = owl_clk_enable,
> > + .disable = owl_clk_disable,
> > +};
> > +
> > +static const struct udevice_id owl_clk_ids[] = {
> > + { .compatible = "actions,s900-cmu" },
> > + { .compatible = "actions,s700-cmu" },
>
> For the records: This is dodgy part. You claim to support both devices,
> but actually don't.
>
> Can you try to add a .data member with the clock type, then replace the
> #ifdef's above with comparing this type? That would be much cleaner,
> still keep the code relatively small and simple.
>
> > + { }
> > +};
> > +
> > +U_BOOT_DRIVER(clk_owl) = {
> > + .name = "clk_s900",
> > + .id = UCLASS_CLK,
> > + .of_match = owl_clk_ids,
> > + .ops = &owl_clk_ops,
> > + .priv_auto_alloc_size = sizeof(struct owl_clk_priv),
> > + .probe = owl_clk_probe,
> > +};
> > diff --git a/drivers/clk/owl/clk_s900.c b/drivers/clk/owl/clk_s900.c
> > deleted file mode 100644
> > index a7c15d2..0000000
> > --- a/drivers/clk/owl/clk_s900.c
>
> So actually this file doesn't look too big, so I wonder if we could live
> with two separate files for S700 and S900.
>
> Cheers,
> Andre.
>
> > +++ /dev/null
> > @@ -1,137 +0,0 @@
> > -// SPDX-License-Identifier: GPL-2.0+
> > -/*
> > - * Actions Semi S900 clock driver
> > - *
> > - * Copyright (C) 2015 Actions Semi Co., Ltd.
> > - * Copyright (C) 2018 Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > - */
> > -
> > -#include <common.h>
> > -#include <dm.h>
> > -#include <asm/arch-owl/clk_s900.h>
> > -#include <asm/arch-owl/regs_s900.h>
> > -#include <asm/io.h>
> > -
> > -#include <dt-bindings/clock/s900_cmu.h>
> > -
> > -void owl_clk_init(struct owl_clk_priv *priv)
> > -{
> > - u32 bus_clk = 0, core_pll, dev_pll;
> > -
> > - /* Enable ASSIST_PLL */
> > - setbits_le32(priv->base + CMU_ASSISTPLL, BIT(0));
> > -
> > - udelay(PLL_STABILITY_WAIT_US);
> > -
> > - /* Source HOSC to DEV_CLK */
> > - clrbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
> > -
> > - /* Configure BUS_CLK */
> > - bus_clk |= (CMU_PDBGDIV_DIV | CMU_PERDIV_DIV | CMU_NOCDIV_DIV |
> > - CMU_DMMCLK_SRC | CMU_APBCLK_DIV | CMU_AHBCLK_DIV |
> > - CMU_NOCCLK_SRC | CMU_CORECLK_HOSC);
> > - writel(bus_clk, priv->base + CMU_BUSCLK);
> > -
> > - udelay(PLL_STABILITY_WAIT_US);
> > -
> > - /* Configure CORE_PLL */
> > - core_pll = readl(priv->base + CMU_COREPLL);
> > - core_pll |= (CMU_COREPLL_EN | CMU_COREPLL_HOSC_EN | CMU_COREPLL_OUT);
> > - writel(core_pll, priv->base + CMU_COREPLL);
> > -
> > - udelay(PLL_STABILITY_WAIT_US);
> > -
> > - /* Configure DEV_PLL */
> > - dev_pll = readl(priv->base + CMU_DEVPLL);
> > - dev_pll |= (CMU_DEVPLL_EN | CMU_DEVPLL_OUT);
> > - writel(dev_pll, priv->base + CMU_DEVPLL);
> > -
> > - udelay(PLL_STABILITY_WAIT_US);
> > -
> > - /* Source CORE_PLL for CORE_CLK */
> > - clrsetbits_le32(priv->base + CMU_BUSCLK, CMU_CORECLK_MASK,
> > - CMU_CORECLK_CPLL);
> > -
> > - /* Source DEV_PLL for DEV_CLK */
> > - setbits_le32(priv->base + CMU_DEVPLL, CMU_DEVPLL_CLK);
> > -
> > - udelay(PLL_STABILITY_WAIT_US);
> > -}
> > -
> > -void owl_uart_clk_enable(struct owl_clk_priv *priv)
> > -{
> > - /* Source HOSC for UART5 interface */
> > - clrbits_le32(priv->base + CMU_UART5CLK, CMU_UARTCLK_SRC_DEVPLL);
> > -
> > - /* Enable UART5 interface clock */
> > - setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
> > -}
> > -
> > -void owl_uart_clk_disable(struct owl_clk_priv *priv)
> > -{
> > - /* Disable UART5 interface clock */
> > - clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART5);
> > -}
> > -
> > -int owl_clk_enable(struct clk *clk)
> > -{
> > - struct owl_clk_priv *priv = dev_get_priv(clk->dev);
> > -
> > - switch (clk->id) {
> > - case CLOCK_UART5:
> > - owl_uart_clk_enable(priv);
> > - break;
> > - default:
> > - return 0;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -int owl_clk_disable(struct clk *clk)
> > -{
> > - struct owl_clk_priv *priv = dev_get_priv(clk->dev);
> > -
> > - switch (clk->id) {
> > - case CLOCK_UART5:
> > - owl_uart_clk_disable(priv);
> > - break;
> > - default:
> > - return 0;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -static int owl_clk_probe(struct udevice *dev)
> > -{
> > - struct owl_clk_priv *priv = dev_get_priv(dev);
> > -
> > - priv->base = dev_read_addr(dev);
> > - if (priv->base == FDT_ADDR_T_NONE)
> > - return -EINVAL;
> > -
> > - /* setup necessary clocks */
> > - owl_clk_init(priv);
> > -
> > - return 0;
> > -}
> > -
> > -static struct clk_ops owl_clk_ops = {
> > - .enable = owl_clk_enable,
> > - .disable = owl_clk_disable,
> > -};
> > -
> > -static const struct udevice_id owl_clk_ids[] = {
> > - { .compatible = "actions,s900-cmu" },
> > - { }
> > -};
> > -
> > -U_BOOT_DRIVER(clk_owl) = {
> > - .name = "clk_s900",
> > - .id = UCLASS_CLK,
> > - .of_match = owl_clk_ids,
> > - .ops = &owl_clk_ops,
> > - .priv_auto_alloc_size = sizeof(struct owl_clk_priv),
> > - .probe = owl_clk_probe,
> > -};
> >
>
More information about the U-Boot
mailing list