18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * MVEBU Core divider clock
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2013 Marvell
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
138c2ecf20Sopenharmony_ci#include <linux/io.h>
148c2ecf20Sopenharmony_ci#include <linux/of_address.h>
158c2ecf20Sopenharmony_ci#include <linux/slab.h>
168c2ecf20Sopenharmony_ci#include <linux/delay.h>
178c2ecf20Sopenharmony_ci#include "common.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#define CORE_CLK_DIV_RATIO_MASK		0xff
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * This structure describes the hardware details (bit offset and mask)
238c2ecf20Sopenharmony_ci * to configure one particular core divider clock. Those hardware
248c2ecf20Sopenharmony_ci * details may differ from one SoC to another. This structure is
258c2ecf20Sopenharmony_ci * therefore typically instantiated statically to describe the
268c2ecf20Sopenharmony_ci * hardware details.
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_cistruct clk_corediv_desc {
298c2ecf20Sopenharmony_ci	unsigned int mask;
308c2ecf20Sopenharmony_ci	unsigned int offset;
318c2ecf20Sopenharmony_ci	unsigned int fieldbit;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci * This structure describes the hardware details to configure the core
368c2ecf20Sopenharmony_ci * divider clocks on a given SoC. Amongst others, it points to the
378c2ecf20Sopenharmony_ci * array of core divider clock descriptors for this SoC, as well as
388c2ecf20Sopenharmony_ci * the corresponding operations to manipulate them.
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_cistruct clk_corediv_soc_desc {
418c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *descs;
428c2ecf20Sopenharmony_ci	unsigned int ndescs;
438c2ecf20Sopenharmony_ci	const struct clk_ops ops;
448c2ecf20Sopenharmony_ci	u32 ratio_reload;
458c2ecf20Sopenharmony_ci	u32 enable_bit_offset;
468c2ecf20Sopenharmony_ci	u32 ratio_offset;
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/*
508c2ecf20Sopenharmony_ci * This structure represents one core divider clock for the clock
518c2ecf20Sopenharmony_ci * framework, and is dynamically allocated for each core divider clock
528c2ecf20Sopenharmony_ci * existing in the current SoC.
538c2ecf20Sopenharmony_ci */
548c2ecf20Sopenharmony_cistruct clk_corediv {
558c2ecf20Sopenharmony_ci	struct clk_hw hw;
568c2ecf20Sopenharmony_ci	void __iomem *reg;
578c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc;
588c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc;
598c2ecf20Sopenharmony_ci	spinlock_t lock;
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic struct clk_onecell_data clk_data;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/*
658c2ecf20Sopenharmony_ci * Description of the core divider clocks available. For now, we
668c2ecf20Sopenharmony_ci * support only NAND, and it is available at the same register
678c2ecf20Sopenharmony_ci * locations regardless of the SoC.
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_cistatic const struct clk_corediv_desc mvebu_corediv_desc[] = {
708c2ecf20Sopenharmony_ci	{ .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic const struct clk_corediv_desc mv98dx3236_corediv_desc[] = {
748c2ecf20Sopenharmony_ci	{ .mask = 0x0f, .offset = 6, .fieldbit = 27 }, /* NAND clock */
758c2ecf20Sopenharmony_ci};
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic int clk_corediv_is_enabled(struct clk_hw *hwclk)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct clk_corediv *corediv = to_corediv_clk(hwclk);
828c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
838c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc = corediv->desc;
848c2ecf20Sopenharmony_ci	u32 enable_mask = BIT(desc->fieldbit) << soc_desc->enable_bit_offset;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	return !!(readl(corediv->reg) & enable_mask);
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic int clk_corediv_enable(struct clk_hw *hwclk)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	struct clk_corediv *corediv = to_corediv_clk(hwclk);
928c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
938c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc = corediv->desc;
948c2ecf20Sopenharmony_ci	unsigned long flags = 0;
958c2ecf20Sopenharmony_ci	u32 reg;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	spin_lock_irqsave(&corediv->lock, flags);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	reg = readl(corediv->reg);
1008c2ecf20Sopenharmony_ci	reg |= (BIT(desc->fieldbit) << soc_desc->enable_bit_offset);
1018c2ecf20Sopenharmony_ci	writel(reg, corediv->reg);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&corediv->lock, flags);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	return 0;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic void clk_corediv_disable(struct clk_hw *hwclk)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	struct clk_corediv *corediv = to_corediv_clk(hwclk);
1118c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
1128c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc = corediv->desc;
1138c2ecf20Sopenharmony_ci	unsigned long flags = 0;
1148c2ecf20Sopenharmony_ci	u32 reg;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	spin_lock_irqsave(&corediv->lock, flags);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	reg = readl(corediv->reg);
1198c2ecf20Sopenharmony_ci	reg &= ~(BIT(desc->fieldbit) << soc_desc->enable_bit_offset);
1208c2ecf20Sopenharmony_ci	writel(reg, corediv->reg);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&corediv->lock, flags);
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistatic unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
1268c2ecf20Sopenharmony_ci					 unsigned long parent_rate)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	struct clk_corediv *corediv = to_corediv_clk(hwclk);
1298c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
1308c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc = corediv->desc;
1318c2ecf20Sopenharmony_ci	u32 reg, div;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	reg = readl(corediv->reg + soc_desc->ratio_offset);
1348c2ecf20Sopenharmony_ci	div = (reg >> desc->offset) & desc->mask;
1358c2ecf20Sopenharmony_ci	return parent_rate / div;
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
1398c2ecf20Sopenharmony_ci			       unsigned long *parent_rate)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
1428c2ecf20Sopenharmony_ci	u32 div;
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	div = *parent_rate / rate;
1458c2ecf20Sopenharmony_ci	if (div < 4)
1468c2ecf20Sopenharmony_ci		div = 4;
1478c2ecf20Sopenharmony_ci	else if (div > 6)
1488c2ecf20Sopenharmony_ci		div = 8;
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	return *parent_rate / div;
1518c2ecf20Sopenharmony_ci}
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
1548c2ecf20Sopenharmony_ci			    unsigned long parent_rate)
1558c2ecf20Sopenharmony_ci{
1568c2ecf20Sopenharmony_ci	struct clk_corediv *corediv = to_corediv_clk(hwclk);
1578c2ecf20Sopenharmony_ci	const struct clk_corediv_soc_desc *soc_desc = corediv->soc_desc;
1588c2ecf20Sopenharmony_ci	const struct clk_corediv_desc *desc = corediv->desc;
1598c2ecf20Sopenharmony_ci	unsigned long flags = 0;
1608c2ecf20Sopenharmony_ci	u32 reg, div;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	div = parent_rate / rate;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	spin_lock_irqsave(&corediv->lock, flags);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	/* Write new divider to the divider ratio register */
1678c2ecf20Sopenharmony_ci	reg = readl(corediv->reg + soc_desc->ratio_offset);
1688c2ecf20Sopenharmony_ci	reg &= ~(desc->mask << desc->offset);
1698c2ecf20Sopenharmony_ci	reg |= (div & desc->mask) << desc->offset;
1708c2ecf20Sopenharmony_ci	writel(reg, corediv->reg + soc_desc->ratio_offset);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/* Set reload-force for this clock */
1738c2ecf20Sopenharmony_ci	reg = readl(corediv->reg) | BIT(desc->fieldbit);
1748c2ecf20Sopenharmony_ci	writel(reg, corediv->reg);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	/* Now trigger the clock update */
1778c2ecf20Sopenharmony_ci	reg = readl(corediv->reg) | soc_desc->ratio_reload;
1788c2ecf20Sopenharmony_ci	writel(reg, corediv->reg);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	/*
1818c2ecf20Sopenharmony_ci	 * Wait for clocks to settle down, and then clear all the
1828c2ecf20Sopenharmony_ci	 * ratios request and the reload request.
1838c2ecf20Sopenharmony_ci	 */
1848c2ecf20Sopenharmony_ci	udelay(1000);
1858c2ecf20Sopenharmony_ci	reg &= ~(CORE_CLK_DIV_RATIO_MASK | soc_desc->ratio_reload);
1868c2ecf20Sopenharmony_ci	writel(reg, corediv->reg);
1878c2ecf20Sopenharmony_ci	udelay(1000);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&corediv->lock, flags);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	return 0;
1928c2ecf20Sopenharmony_ci}
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic const struct clk_corediv_soc_desc armada370_corediv_soc = {
1958c2ecf20Sopenharmony_ci	.descs = mvebu_corediv_desc,
1968c2ecf20Sopenharmony_ci	.ndescs = ARRAY_SIZE(mvebu_corediv_desc),
1978c2ecf20Sopenharmony_ci	.ops = {
1988c2ecf20Sopenharmony_ci		.enable = clk_corediv_enable,
1998c2ecf20Sopenharmony_ci		.disable = clk_corediv_disable,
2008c2ecf20Sopenharmony_ci		.is_enabled = clk_corediv_is_enabled,
2018c2ecf20Sopenharmony_ci		.recalc_rate = clk_corediv_recalc_rate,
2028c2ecf20Sopenharmony_ci		.round_rate = clk_corediv_round_rate,
2038c2ecf20Sopenharmony_ci		.set_rate = clk_corediv_set_rate,
2048c2ecf20Sopenharmony_ci	},
2058c2ecf20Sopenharmony_ci	.ratio_reload = BIT(8),
2068c2ecf20Sopenharmony_ci	.enable_bit_offset = 24,
2078c2ecf20Sopenharmony_ci	.ratio_offset = 0x8,
2088c2ecf20Sopenharmony_ci};
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic const struct clk_corediv_soc_desc armada380_corediv_soc = {
2118c2ecf20Sopenharmony_ci	.descs = mvebu_corediv_desc,
2128c2ecf20Sopenharmony_ci	.ndescs = ARRAY_SIZE(mvebu_corediv_desc),
2138c2ecf20Sopenharmony_ci	.ops = {
2148c2ecf20Sopenharmony_ci		.enable = clk_corediv_enable,
2158c2ecf20Sopenharmony_ci		.disable = clk_corediv_disable,
2168c2ecf20Sopenharmony_ci		.is_enabled = clk_corediv_is_enabled,
2178c2ecf20Sopenharmony_ci		.recalc_rate = clk_corediv_recalc_rate,
2188c2ecf20Sopenharmony_ci		.round_rate = clk_corediv_round_rate,
2198c2ecf20Sopenharmony_ci		.set_rate = clk_corediv_set_rate,
2208c2ecf20Sopenharmony_ci	},
2218c2ecf20Sopenharmony_ci	.ratio_reload = BIT(8),
2228c2ecf20Sopenharmony_ci	.enable_bit_offset = 16,
2238c2ecf20Sopenharmony_ci	.ratio_offset = 0x4,
2248c2ecf20Sopenharmony_ci};
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_cistatic const struct clk_corediv_soc_desc armada375_corediv_soc = {
2278c2ecf20Sopenharmony_ci	.descs = mvebu_corediv_desc,
2288c2ecf20Sopenharmony_ci	.ndescs = ARRAY_SIZE(mvebu_corediv_desc),
2298c2ecf20Sopenharmony_ci	.ops = {
2308c2ecf20Sopenharmony_ci		.recalc_rate = clk_corediv_recalc_rate,
2318c2ecf20Sopenharmony_ci		.round_rate = clk_corediv_round_rate,
2328c2ecf20Sopenharmony_ci		.set_rate = clk_corediv_set_rate,
2338c2ecf20Sopenharmony_ci	},
2348c2ecf20Sopenharmony_ci	.ratio_reload = BIT(8),
2358c2ecf20Sopenharmony_ci	.ratio_offset = 0x4,
2368c2ecf20Sopenharmony_ci};
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cistatic const struct clk_corediv_soc_desc mv98dx3236_corediv_soc = {
2398c2ecf20Sopenharmony_ci	.descs = mv98dx3236_corediv_desc,
2408c2ecf20Sopenharmony_ci	.ndescs = ARRAY_SIZE(mv98dx3236_corediv_desc),
2418c2ecf20Sopenharmony_ci	.ops = {
2428c2ecf20Sopenharmony_ci		.recalc_rate = clk_corediv_recalc_rate,
2438c2ecf20Sopenharmony_ci		.round_rate = clk_corediv_round_rate,
2448c2ecf20Sopenharmony_ci		.set_rate = clk_corediv_set_rate,
2458c2ecf20Sopenharmony_ci	},
2468c2ecf20Sopenharmony_ci	.ratio_reload = BIT(10),
2478c2ecf20Sopenharmony_ci	.ratio_offset = 0x8,
2488c2ecf20Sopenharmony_ci};
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_cistatic void __init
2518c2ecf20Sopenharmony_cimvebu_corediv_clk_init(struct device_node *node,
2528c2ecf20Sopenharmony_ci		       const struct clk_corediv_soc_desc *soc_desc)
2538c2ecf20Sopenharmony_ci{
2548c2ecf20Sopenharmony_ci	struct clk_init_data init;
2558c2ecf20Sopenharmony_ci	struct clk_corediv *corediv;
2568c2ecf20Sopenharmony_ci	struct clk **clks;
2578c2ecf20Sopenharmony_ci	void __iomem *base;
2588c2ecf20Sopenharmony_ci	const char *parent_name;
2598c2ecf20Sopenharmony_ci	const char *clk_name;
2608c2ecf20Sopenharmony_ci	int i;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	base = of_iomap(node, 0);
2638c2ecf20Sopenharmony_ci	if (WARN_ON(!base))
2648c2ecf20Sopenharmony_ci		return;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	parent_name = of_clk_get_parent_name(node, 0);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	clk_data.clk_num = soc_desc->ndescs;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	/* clks holds the clock array */
2718c2ecf20Sopenharmony_ci	clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
2728c2ecf20Sopenharmony_ci				GFP_KERNEL);
2738c2ecf20Sopenharmony_ci	if (WARN_ON(!clks))
2748c2ecf20Sopenharmony_ci		goto err_unmap;
2758c2ecf20Sopenharmony_ci	/* corediv holds the clock specific array */
2768c2ecf20Sopenharmony_ci	corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
2778c2ecf20Sopenharmony_ci				GFP_KERNEL);
2788c2ecf20Sopenharmony_ci	if (WARN_ON(!corediv))
2798c2ecf20Sopenharmony_ci		goto err_free_clks;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	spin_lock_init(&corediv->lock);
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	for (i = 0; i < clk_data.clk_num; i++) {
2848c2ecf20Sopenharmony_ci		of_property_read_string_index(node, "clock-output-names",
2858c2ecf20Sopenharmony_ci					      i, &clk_name);
2868c2ecf20Sopenharmony_ci		init.num_parents = 1;
2878c2ecf20Sopenharmony_ci		init.parent_names = &parent_name;
2888c2ecf20Sopenharmony_ci		init.name = clk_name;
2898c2ecf20Sopenharmony_ci		init.ops = &soc_desc->ops;
2908c2ecf20Sopenharmony_ci		init.flags = 0;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci		corediv[i].soc_desc = soc_desc;
2938c2ecf20Sopenharmony_ci		corediv[i].desc = soc_desc->descs + i;
2948c2ecf20Sopenharmony_ci		corediv[i].reg = base;
2958c2ecf20Sopenharmony_ci		corediv[i].hw.init = &init;
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci		clks[i] = clk_register(NULL, &corediv[i].hw);
2988c2ecf20Sopenharmony_ci		WARN_ON(IS_ERR(clks[i]));
2998c2ecf20Sopenharmony_ci	}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	clk_data.clks = clks;
3028c2ecf20Sopenharmony_ci	of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
3038c2ecf20Sopenharmony_ci	return;
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_cierr_free_clks:
3068c2ecf20Sopenharmony_ci	kfree(clks);
3078c2ecf20Sopenharmony_cierr_unmap:
3088c2ecf20Sopenharmony_ci	iounmap(base);
3098c2ecf20Sopenharmony_ci}
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_cistatic void __init armada370_corediv_clk_init(struct device_node *node)
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	return mvebu_corediv_clk_init(node, &armada370_corediv_soc);
3148c2ecf20Sopenharmony_ci}
3158c2ecf20Sopenharmony_ciCLK_OF_DECLARE(armada370_corediv_clk, "marvell,armada-370-corediv-clock",
3168c2ecf20Sopenharmony_ci	       armada370_corediv_clk_init);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cistatic void __init armada375_corediv_clk_init(struct device_node *node)
3198c2ecf20Sopenharmony_ci{
3208c2ecf20Sopenharmony_ci	return mvebu_corediv_clk_init(node, &armada375_corediv_soc);
3218c2ecf20Sopenharmony_ci}
3228c2ecf20Sopenharmony_ciCLK_OF_DECLARE(armada375_corediv_clk, "marvell,armada-375-corediv-clock",
3238c2ecf20Sopenharmony_ci	       armada375_corediv_clk_init);
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_cistatic void __init armada380_corediv_clk_init(struct device_node *node)
3268c2ecf20Sopenharmony_ci{
3278c2ecf20Sopenharmony_ci	return mvebu_corediv_clk_init(node, &armada380_corediv_soc);
3288c2ecf20Sopenharmony_ci}
3298c2ecf20Sopenharmony_ciCLK_OF_DECLARE(armada380_corediv_clk, "marvell,armada-380-corediv-clock",
3308c2ecf20Sopenharmony_ci	       armada380_corediv_clk_init);
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_cistatic void __init mv98dx3236_corediv_clk_init(struct device_node *node)
3338c2ecf20Sopenharmony_ci{
3348c2ecf20Sopenharmony_ci	return mvebu_corediv_clk_init(node, &mv98dx3236_corediv_soc);
3358c2ecf20Sopenharmony_ci}
3368c2ecf20Sopenharmony_ciCLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock",
3378c2ecf20Sopenharmony_ci	       mv98dx3236_corediv_clk_init);
338