diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2021-06-01 16:57:52 +0300 |
---|---|---|
committer | Emil Renner Berthing <kernel@esmil.dk> | 2021-06-07 01:55:57 +0300 |
commit | 09a73a6fbb30a868682b2d6178743d0da3e5e8ae (patch) | |
tree | 7732adf282ae16b06c8a751ea24b72f28a3290a9 | |
parent | e0369eaac760ae5cdc07e434143bcf7239fc9a0e (diff) | |
download | linux-09a73a6fbb30a868682b2d6178743d0da3e5e8ae.tar.xz |
[WIP] clk: starfive: Add preliminary JH7100 Clock Generator Driver
Add a preliminary driver for the StarFive JH7100 Clock Generator.
For now, all clocks are implemented as fixed-factor clocks relative to
osc0, based on the list of fixed-frequency clocks defined in
jh7100.dtsi.
To be updated when the documentation becomes available.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | drivers/clk/Kconfig | 1 | ||||
-rw-r--r-- | drivers/clk/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/starfive/Kconfig | 9 | ||||
-rw-r--r-- | drivers/clk/starfive/Makefile | 3 | ||||
-rw-r--r-- | drivers/clk/starfive/clk-starfive-jh7100.c | 124 |
5 files changed, 138 insertions, 0 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e80918be8e9c..61b243a14f42 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -397,6 +397,7 @@ source "drivers/clk/samsung/Kconfig" source "drivers/clk/sifive/Kconfig" source "drivers/clk/socfpga/Kconfig" source "drivers/clk/sprd/Kconfig" +source "drivers/clk/starfive/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5f06879d7fe9..c154596d1ab5 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -109,6 +109,7 @@ obj-y += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-y += sprd/ obj-$(CONFIG_ARCH_STI) += st/ +obj-$(CONFIG_SOC_STARFIVE_VIC7100) += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig new file mode 100644 index 000000000000..0e23c9a8a663 --- /dev/null +++ b/drivers/clk/starfive/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +config CLK_STARFIVE_JH7100 + bool "StarFive JH7100 clock support" + depends on SOC_STARFIVE_VIC7100 || COMPILE_TEST + default y if SOC_STARFIVE_VIC7100 + help + Say yes here to support the clock controller on the StarFive JH7100 + SoC. diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile new file mode 100644 index 000000000000..09759cc73530 --- /dev/null +++ b/drivers/clk/starfive/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +# StarFive Clock +obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c new file mode 100644 index 000000000000..a768394c28f0 --- /dev/null +++ b/drivers/clk/starfive/clk-starfive-jh7100.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * StarFive JH7100 Clock Generator Driver + * This is part of the PCR (Power/Clock/Reset) Management Unit Driver + * + * FIXME PRELIMINARY + * For now, all clocks are implemented as fixed-factor clocks relative to osc0 + * + * TODO Real clock topology, clock register programming + * PLL0 used for system main logic, including CPU, bus + * PLL1 output to support DDR, DLA and DSP + * PLL2 output to support slow speed peripherals, video input and video output + * + * Copyright (C) 2021 Glider bv + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/overflow.h> +#include <linux/platform_device.h> + +#include <dt-bindings/clock/starfive-jh7100-clkgen.h> + +static const struct jh7100_clk { + const char *name; + unsigned int mult; + unsigned int div; +} jh7100_clks[] = { + [JH7100_CLK_AXI] = { "axi", .mult = 20, .div = 1 }, + [JH7100_CLK_AHB0] = { "ahb0", .mult = 10, .div = 1 }, + [JH7100_CLK_AHB2] = { "ahb2", .mult = 5, .div = 1 }, + [JH7100_CLK_APB1] = { "apb1", .mult = 5, .div = 1 }, + [JH7100_CLK_APB2] = { "apb2", .mult = 5, .div = 1 }, + [JH7100_CLK_VPU] = { "vpu", .mult = 16, .div = 1 }, + [JH7100_CLK_JPU] = { "jpu", .mult = 40, .div = 3 }, + [JH7100_CLK_PWM] = { "pwm", .mult = 5, .div = 1 }, + [JH7100_CLK_DWMMC_BIU] = { "dwmmc-biu", .mult = 4, .div = 1 }, + [JH7100_CLK_DWMMC_CIU] = { "dwmmc-ciu", .mult = 4, .div = 1 }, + [JH7100_CLK_UART] = { "uart", .mult = 4, .div = 1 }, + [JH7100_CLK_HS_UART] = { "hs_uart", .mult = 297, .div = 100 }, + [JH7100_CLK_I2C0] = { "i2c0", .mult = 99, .div = 50 }, + [JH7100_CLK_I2C2] = { "i2c2", .mult = 2, .div = 1 }, + [JH7100_CLK_QSPI] = { "qspi", .mult = 2, .div = 1 }, + [JH7100_CLK_SPI] = { "spi", .mult = 2, .div = 1 }, + [JH7100_CLK_GMAC] = { "gmac", .mult = 1, .div = 1 }, + [JH7100_CLK_HF] = { "hf", .mult = 1, .div = 1 }, + [JH7100_CLK_RTC] = { "rtc", .mult = 1, .div = 4 } +}; + +struct clk_starfive_jh7100_priv { + struct clk_onecell_data data; + void __iomem *base; + struct clk *clks[]; +}; + +static int __init clk_starfive_jh7100_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + unsigned int nclks = ARRAY_SIZE(jh7100_clks); + struct clk_starfive_jh7100_priv *priv; + const char *osc0_name; + struct clk_hw *hw; + struct clk *osc0; + unsigned int i; + + priv = devm_kzalloc(dev, struct_size(priv, clks, nclks), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + osc0 = devm_clk_get(dev, "osc0"); + if (IS_ERR(osc0)) + return PTR_ERR(osc0); + + osc0_name = __clk_get_name(osc0); + + for (i = 0; i < nclks; i++) { + hw = devm_clk_hw_register_fixed_factor(dev, + jh7100_clks[i].name, osc0_name, 0, jh7100_clks[i].mult, + jh7100_clks[i].div); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + priv->clks[i] = hw->clk; + } + + priv->data.clks = priv->clks; + priv->data.clk_num = nclks; + + return of_clk_add_provider(np, of_clk_src_onecell_get, &priv->data); +} + +static const struct of_device_id clk_starfive_jh7100_match[] = { + { + .compatible = "starfive,jh7100-clkgen", + }, + { /* sentinel */ } +}; +static struct platform_driver clk_starfive_jh7100_driver = { + .driver = { + .name = "clk-starfive-jh7100", + .of_match_table = clk_starfive_jh7100_match, + }, +}; + +static int __init clk_starfive_jh7100_init(void) +{ + return platform_driver_probe(&clk_starfive_jh7100_driver, + clk_starfive_jh7100_probe); +} + +subsys_initcall(clk_starfive_jh7100_init); + +MODULE_DESCRIPTION("StarFive JH7100 Clock Generator Driver"); +MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>"); +MODULE_LICENSE("GPL v2"); |