diff options
author | Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 2018-06-14 23:38:35 +0530 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-07-09 15:25:31 -0400 |
commit | ae485b540f3b5555f5e043eaf2c8e859052f3b14 (patch) | |
tree | 334f7720f0e4dfb2c5d2656027a986fb2a06fb81 /drivers | |
parent | 69e62417c7d313ebb879eb4a8bd0130149d85949 (diff) |
clk: Add Actions Semi OWL clock support
This commit adds Actions Semi OWL family base clock and S900 SoC
specific clock support. For S900 peripheral clock support, only UART
clock has been added for now.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/Kconfig | 1 | ||||
-rw-r--r-- | drivers/clk/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/owl/Kconfig | 12 | ||||
-rw-r--r-- | drivers/clk/owl/Makefile | 3 | ||||
-rw-r--r-- | drivers/clk/owl/clk_s900.c | 138 |
5 files changed, 155 insertions, 0 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index edb4ca58ea..18bf8a6d28 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -89,6 +89,7 @@ source "drivers/clk/exynos/Kconfig" source "drivers/clk/at91/Kconfig" source "drivers/clk/renesas/Kconfig" source "drivers/clk/mvebu/Kconfig" +source "drivers/clk/owl/Kconfig" config ICS8N3QV01 bool "Enable ICS8N3QV01 VCXO driver" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 426c67db9b..146283c723 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o +obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o diff --git a/drivers/clk/owl/Kconfig b/drivers/clk/owl/Kconfig new file mode 100644 index 0000000000..661f1981b9 --- /dev/null +++ b/drivers/clk/owl/Kconfig @@ -0,0 +1,12 @@ +config CLK_OWL + bool "Actions Semi OWL clock drivers" + depends on CLK && ARCH_OWL + help + Enable support for clock managemet unit present in Actions Semi + OWL 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 new file mode 100644 index 0000000000..9132dcc175 --- /dev/null +++ b/drivers/clk/owl/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_CLK_S900) += clk_s900.o diff --git a/drivers/clk/owl/clk_s900.c b/drivers/clk/owl/clk_s900.c new file mode 100644 index 0000000000..2b39bb99af --- /dev/null +++ b/drivers/clk/owl/clk_s900.c @@ -0,0 +1,138 @@ +// 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@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, + .flags = DM_FLAG_PRE_RELOC, +}; |