mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
Merge branches 'clk-renesas', 'clk-kunit', 'clk-regmap' and 'clk-frac-divider' into clk-next
- Make clk kunit tests work with lockdep - Fix clk gate kunit test for big-endian - Convert more than a handful of clk drivers to use regmap maple tree - Consider the CLK_FRAC_DIVIDER_ZERO_BASED in fractional divider clk implementation * clk-renesas: (23 commits) clk: renesas: r9a08g045: Add clock and reset support for SDHI1 and SDHI2 clk: renesas: rzg2l: Use %x format specifier to print CLK_ON_R() clk: renesas: Add minimal boot support for RZ/G3S SoC clk: renesas: rzg2l: Add divider clock for RZ/G3S clk: renesas: rzg2l: Refactor SD mux driver clk: renesas: rzg2l: Remove CPG_SDHI_DSEL from generic header clk: renesas: rzg2l: Add struct clk_hw_data clk: renesas: rzg2l: Add support for RZ/G3S PLL clk: renesas: rzg2l: Remove critical area clk: renesas: rzg2l: Fix computation formula clk: renesas: rzg2l: Trust value returned by hardware clk: renesas: rzg2l: Lock around writes to mux register clk: renesas: rzg2l: Wait for status bit of SD mux before continuing clk: renesas: rcar-gen3: Extend SDnH divider table dt-bindings: clock: renesas,rzg2l-cpg: Document RZ/G3S SoC clk: renesas: r8a7795: Constify r8a7795_*_clks clk: renesas: r9a06g032: Name anonymous structs clk: renesas: r9a06g032: Fix kerneldoc warning clk: renesas: rzg2l: Use u32 for flag and mux_flags clk: renesas: rzg2l: Use FIELD_GET() for PLL register fields ... * clk-kunit: clk: Fix clk gate kunit test on big-endian CPUs clk: Parameterize clk_leaf_mux_set_rate_parent clk: Drive clk_leaf_mux_set_rate_parent test from clk_ops * clk-regmap: clk: versaclock7: Convert to use maple tree register cache clk: versaclock5: Convert to use maple tree register cache clk: versaclock3: Convert to use maple tree register cache clk: versaclock3: Remove redundant _is_writeable() clk: si570: Convert to use maple tree register cache clk: si544: Convert to use maple tree register cache clk: si5351: Convert to use maple tree register cache clk: si5341: Convert to use maple tree register cache clk: si514: Convert to use maple tree register cache clk: cdce925: Convert to use maple tree register cache * clk-frac-divider: clk: fractional-divider: tests: Add test suite for edge cases clk: fractional-divider: Improve approximation when zero based and export
This commit is contained in:
commit
720e4a4a68
28 changed files with 1313 additions and 183 deletions
|
@ -27,6 +27,7 @@ properties:
|
|||
- renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2} and RZ/Five
|
||||
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-cpg # RZ/V2L
|
||||
- renesas,r9a08g045-cpg # RZ/G3S
|
||||
- renesas,r9a09g011-cpg # RZ/V2M
|
||||
|
||||
reg:
|
||||
|
|
|
@ -2,4 +2,5 @@ CONFIG_KUNIT=y
|
|||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_CLK_KUNIT_TEST=y
|
||||
CONFIG_CLK_GATE_KUNIT_TEST=y
|
||||
CONFIG_CLK_FD_KUNIT_TEST=y
|
||||
CONFIG_UML_PCI_OVER_VIRTIO=n
|
||||
|
|
|
@ -526,4 +526,11 @@ config CLK_GATE_KUNIT_TEST
|
|||
help
|
||||
Kunit test for the basic clk gate type.
|
||||
|
||||
config CLK_FD_KUNIT_TEST
|
||||
tristate "Basic fractional divider type Kunit test" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Kunit test for the clk-fractional-divider type.
|
||||
|
||||
endif
|
||||
|
|
|
@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o
|
|||
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
|
||||
obj-$(CONFIG_CLK_FD_KUNIT_TEST) += clk-fractional-divider_test.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-gpio.o
|
||||
ifeq ($(CONFIG_OF), y)
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-conf.o
|
||||
|
|
|
@ -647,7 +647,7 @@ static int cdce925_probe(struct i2c_client *client)
|
|||
.name = "configuration0",
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
dev_dbg(&client->dev, "%s\n", __func__);
|
||||
|
|
|
@ -123,6 +123,7 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
|
|||
unsigned long *m, unsigned long *n)
|
||||
{
|
||||
struct clk_fractional_divider *fd = to_clk_fd(hw);
|
||||
unsigned long max_m, max_n;
|
||||
|
||||
/*
|
||||
* Get rate closer to *parent_rate to guarantee there is no overflow
|
||||
|
@ -138,10 +139,17 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
|
|||
rate <<= scale - fd->nwidth;
|
||||
}
|
||||
|
||||
rational_best_approximation(rate, *parent_rate,
|
||||
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
|
||||
m, n);
|
||||
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
|
||||
max_m = 1 << fd->mwidth;
|
||||
max_n = 1 << fd->nwidth;
|
||||
} else {
|
||||
max_m = GENMASK(fd->mwidth - 1, 0);
|
||||
max_n = GENMASK(fd->nwidth - 1, 0);
|
||||
}
|
||||
|
||||
rational_best_approximation(rate, *parent_rate, max_m, max_n, m, n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation);
|
||||
|
||||
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
|
@ -169,13 +177,18 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_fractional_divider *fd = to_clk_fd(hw);
|
||||
unsigned long flags = 0;
|
||||
unsigned long m, n;
|
||||
unsigned long m, n, max_m, max_n;
|
||||
u32 mmask, nmask;
|
||||
u32 val;
|
||||
|
||||
rational_best_approximation(rate, parent_rate,
|
||||
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
|
||||
&m, &n);
|
||||
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
|
||||
max_m = 1 << fd->mwidth;
|
||||
max_n = 1 << fd->nwidth;
|
||||
} else {
|
||||
max_m = GENMASK(fd->mwidth - 1, 0);
|
||||
max_n = GENMASK(fd->nwidth - 1, 0);
|
||||
}
|
||||
rational_best_approximation(rate, parent_rate, max_m, max_n, &m, &n);
|
||||
|
||||
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
|
||||
m--;
|
||||
|
|
147
drivers/clk/clk-fractional-divider_test.c
Normal file
147
drivers/clk/clk-fractional-divider_test.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Kunit test for clock fractional divider
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include "clk-fractional-divider.h"
|
||||
|
||||
/*
|
||||
* Test the maximum denominator case for fd clock without flags.
|
||||
*
|
||||
* Expect the highest possible denominator to be used in order to get as close as possible to the
|
||||
* requested rate.
|
||||
*/
|
||||
static void clk_fd_test_approximation_max_denominator(struct kunit *test)
|
||||
{
|
||||
struct clk_fractional_divider *fd;
|
||||
unsigned long rate, parent_rate, parent_rate_before, m, n, max_n;
|
||||
|
||||
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, fd);
|
||||
|
||||
fd->mwidth = 3;
|
||||
fd->nwidth = 3;
|
||||
max_n = 7;
|
||||
|
||||
rate = 240000000;
|
||||
parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */
|
||||
parent_rate_before = parent_rate;
|
||||
|
||||
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
|
||||
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, m, 1);
|
||||
KUNIT_EXPECT_EQ(test, n, max_n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the maximum numerator case for fd clock without flags.
|
||||
*
|
||||
* Expect the highest possible numerator to be used in order to get as close as possible to the
|
||||
* requested rate.
|
||||
*/
|
||||
static void clk_fd_test_approximation_max_numerator(struct kunit *test)
|
||||
{
|
||||
struct clk_fractional_divider *fd;
|
||||
unsigned long rate, parent_rate, parent_rate_before, m, n, max_m;
|
||||
|
||||
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, fd);
|
||||
|
||||
fd->mwidth = 3;
|
||||
max_m = 7;
|
||||
fd->nwidth = 3;
|
||||
|
||||
rate = 240000000;
|
||||
parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */
|
||||
parent_rate_before = parent_rate;
|
||||
|
||||
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
|
||||
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, m, max_m);
|
||||
KUNIT_EXPECT_EQ(test, n, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the maximum denominator case for zero based fd clock.
|
||||
*
|
||||
* Expect the highest possible denominator to be used in order to get as close as possible to the
|
||||
* requested rate.
|
||||
*/
|
||||
static void clk_fd_test_approximation_max_denominator_zero_based(struct kunit *test)
|
||||
{
|
||||
struct clk_fractional_divider *fd;
|
||||
unsigned long rate, parent_rate, parent_rate_before, m, n, max_n;
|
||||
|
||||
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, fd);
|
||||
|
||||
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
|
||||
fd->mwidth = 3;
|
||||
fd->nwidth = 3;
|
||||
max_n = 8;
|
||||
|
||||
rate = 240000000;
|
||||
parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */
|
||||
parent_rate_before = parent_rate;
|
||||
|
||||
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
|
||||
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, m, 1);
|
||||
KUNIT_EXPECT_EQ(test, n, max_n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the maximum numerator case for zero based fd clock.
|
||||
*
|
||||
* Expect the highest possible numerator to be used in order to get as close as possible to the
|
||||
* requested rate.
|
||||
*/
|
||||
static void clk_fd_test_approximation_max_numerator_zero_based(struct kunit *test)
|
||||
{
|
||||
struct clk_fractional_divider *fd;
|
||||
unsigned long rate, parent_rate, parent_rate_before, m, n, max_m;
|
||||
|
||||
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, fd);
|
||||
|
||||
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
|
||||
fd->mwidth = 3;
|
||||
max_m = 8;
|
||||
fd->nwidth = 3;
|
||||
|
||||
rate = 240000000;
|
||||
parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */
|
||||
parent_rate_before = parent_rate;
|
||||
|
||||
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
|
||||
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, m, max_m);
|
||||
KUNIT_EXPECT_EQ(test, n, 1);
|
||||
}
|
||||
|
||||
static struct kunit_case clk_fd_approximation_test_cases[] = {
|
||||
KUNIT_CASE(clk_fd_test_approximation_max_denominator),
|
||||
KUNIT_CASE(clk_fd_test_approximation_max_numerator),
|
||||
KUNIT_CASE(clk_fd_test_approximation_max_denominator_zero_based),
|
||||
KUNIT_CASE(clk_fd_test_approximation_max_numerator_zero_based),
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Test suite for clk_fractional_divider_general_approximation().
|
||||
*/
|
||||
static struct kunit_suite clk_fd_approximation_suite = {
|
||||
.name = "clk-fd-approximation",
|
||||
.test_cases = clk_fd_approximation_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(
|
||||
&clk_fd_approximation_suite
|
||||
);
|
||||
MODULE_LICENSE("GPL");
|
|
@ -131,7 +131,7 @@ struct clk_gate_test_context {
|
|||
void __iomem *fake_mem;
|
||||
struct clk_hw *hw;
|
||||
struct clk_hw *parent;
|
||||
u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
|
||||
__le32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
|
||||
};
|
||||
|
||||
static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
|
||||
|
@ -166,7 +166,7 @@ static void clk_gate_test_enable(struct kunit *test)
|
|||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -183,10 +183,10 @@ static void clk_gate_test_disable(struct kunit *test)
|
|||
u32 disable_val = 0;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -246,7 +246,7 @@ static void clk_gate_test_invert_enable(struct kunit *test)
|
|||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -263,10 +263,10 @@ static void clk_gate_test_invert_disable(struct kunit *test)
|
|||
u32 disable_val = BIT(15);
|
||||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -290,7 +290,7 @@ static int clk_gate_test_invert_init(struct kunit *test)
|
|||
2000000);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
|
||||
|
||||
ctx->fake_reg = BIT(15); /* Default to off */
|
||||
ctx->fake_reg = cpu_to_le32(BIT(15)); /* Default to off */
|
||||
hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
|
||||
ctx->fake_mem, 15,
|
||||
CLK_GATE_SET_TO_DISABLE, NULL);
|
||||
|
@ -319,7 +319,7 @@ static void clk_gate_test_hiword_enable(struct kunit *test)
|
|||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -336,10 +336,10 @@ static void clk_gate_test_hiword_disable(struct kunit *test)
|
|||
u32 disable_val = BIT(9 + 16);
|
||||
|
||||
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
|
||||
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
|
||||
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
|
||||
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
|
||||
|
@ -387,7 +387,7 @@ static void clk_gate_test_is_enabled(struct kunit *test)
|
|||
struct clk_gate_test_context *ctx;
|
||||
|
||||
ctx = clk_gate_test_alloc_ctx(test);
|
||||
ctx->fake_reg = BIT(7);
|
||||
ctx->fake_reg = cpu_to_le32(BIT(7));
|
||||
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
|
||||
0, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
|
||||
|
@ -402,7 +402,7 @@ static void clk_gate_test_is_disabled(struct kunit *test)
|
|||
struct clk_gate_test_context *ctx;
|
||||
|
||||
ctx = clk_gate_test_alloc_ctx(test);
|
||||
ctx->fake_reg = BIT(4);
|
||||
ctx->fake_reg = cpu_to_le32(BIT(4));
|
||||
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
|
||||
0, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
|
||||
|
@ -417,7 +417,7 @@ static void clk_gate_test_is_enabled_inverted(struct kunit *test)
|
|||
struct clk_gate_test_context *ctx;
|
||||
|
||||
ctx = clk_gate_test_alloc_ctx(test);
|
||||
ctx->fake_reg = BIT(31);
|
||||
ctx->fake_reg = cpu_to_le32(BIT(31));
|
||||
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
|
||||
CLK_GATE_SET_TO_DISABLE, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
|
||||
|
@ -432,7 +432,7 @@ static void clk_gate_test_is_disabled_inverted(struct kunit *test)
|
|||
struct clk_gate_test_context *ctx;
|
||||
|
||||
ctx = clk_gate_test_alloc_ctx(test);
|
||||
ctx->fake_reg = BIT(29);
|
||||
ctx->fake_reg = cpu_to_le32(BIT(29));
|
||||
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
|
||||
CLK_GATE_SET_TO_DISABLE, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
|
||||
|
|
|
@ -321,7 +321,7 @@ static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg)
|
|||
static const struct regmap_config si514_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = SI514_REG_CONTROL,
|
||||
.writeable_reg = si514_regmap_is_writeable,
|
||||
.volatile_reg = si514_regmap_is_volatile,
|
||||
|
|
|
@ -1260,7 +1260,7 @@ static int si5341_wait_device_ready(struct i2c_client *client)
|
|||
static const struct regmap_config si5341_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.ranges = si5341_regmap_ranges,
|
||||
.num_ranges = ARRAY_SIZE(si5341_regmap_ranges),
|
||||
.max_register = SI5341_REGISTER_MAX,
|
||||
|
|
|
@ -206,7 +206,7 @@ static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
|
|||
static const struct regmap_config si5351_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = 187,
|
||||
.writeable_reg = si5351_regmap_is_writeable,
|
||||
.volatile_reg = si5351_regmap_is_volatile,
|
||||
|
|
|
@ -446,7 +446,7 @@ static bool si544_regmap_is_volatile(struct device *dev, unsigned int reg)
|
|||
static const struct regmap_config si544_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = SI544_REG_PAGE_SELECT,
|
||||
.volatile_reg = si544_regmap_is_volatile,
|
||||
};
|
||||
|
|
|
@ -392,7 +392,7 @@ static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
|
|||
static const struct regmap_config si570_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = 137,
|
||||
.writeable_reg = si570_regmap_is_writeable,
|
||||
.volatile_reg = si570_regmap_is_volatile,
|
||||
|
|
|
@ -585,17 +585,11 @@ static const struct clk_ops vc3_clk_mux_ops = {
|
|||
.get_parent = vc3_clk_mux_get_parent,
|
||||
};
|
||||
|
||||
static bool vc3_regmap_is_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct regmap_config vc3_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = 0x24,
|
||||
.writeable_reg = vc3_regmap_is_writeable,
|
||||
};
|
||||
|
||||
static struct vc3_hw_data clk_div[5];
|
||||
|
|
|
@ -217,7 +217,7 @@ static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
|
|||
static const struct regmap_config vc5_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.max_register = 0x76,
|
||||
.writeable_reg = vc5_regmap_is_writeable,
|
||||
};
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static const struct regmap_config vc7_regmap_config = {
|
|||
.ranges = vc7_range_cfg,
|
||||
.num_ranges = ARRAY_SIZE(vc7_range_cfg),
|
||||
.volatile_reg = vc7_volatile_reg,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.can_multi_write = true,
|
||||
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <kunit/test.h>
|
||||
|
||||
static const struct clk_ops empty_clk_ops = { };
|
||||
|
||||
#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000)
|
||||
#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
|
||||
#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
|
||||
|
@ -2155,6 +2157,31 @@ static struct kunit_suite clk_range_minimize_test_suite = {
|
|||
struct clk_leaf_mux_ctx {
|
||||
struct clk_multiple_parent_ctx mux_ctx;
|
||||
struct clk_hw hw;
|
||||
struct clk_hw parent;
|
||||
struct clk_rate_request *req;
|
||||
int (*determine_rate_func)(struct clk_hw *hw, struct clk_rate_request *req);
|
||||
};
|
||||
|
||||
static int clk_leaf_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_leaf_mux_ctx *ctx = container_of(hw, struct clk_leaf_mux_ctx, hw);
|
||||
int ret;
|
||||
struct clk_rate_request *parent_req = ctx->req;
|
||||
|
||||
clk_hw_forward_rate_request(hw, req, req->best_parent_hw, parent_req, req->rate);
|
||||
ret = ctx->determine_rate_func(req->best_parent_hw, parent_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->rate = parent_req->rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_leaf_mux_set_rate_parent_ops = {
|
||||
.determine_rate = clk_leaf_mux_determine_rate,
|
||||
.set_parent = clk_dummy_single_set_parent,
|
||||
.get_parent = clk_dummy_single_get_parent,
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -2193,8 +2220,14 @@ clk_leaf_mux_set_rate_parent_test_init(struct kunit *test)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->hw.init = CLK_HW_INIT_HW("test-clock", &ctx->mux_ctx.hw,
|
||||
&clk_dummy_single_parent_ops,
|
||||
ctx->parent.init = CLK_HW_INIT_HW("test-parent", &ctx->mux_ctx.hw,
|
||||
&empty_clk_ops, CLK_SET_RATE_PARENT);
|
||||
ret = clk_hw_register(NULL, &ctx->parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->hw.init = CLK_HW_INIT_HW("test-clock", &ctx->parent,
|
||||
&clk_leaf_mux_set_rate_parent_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
ret = clk_hw_register(NULL, &ctx->hw);
|
||||
if (ret)
|
||||
|
@ -2208,32 +2241,94 @@ static void clk_leaf_mux_set_rate_parent_test_exit(struct kunit *test)
|
|||
struct clk_leaf_mux_ctx *ctx = test->priv;
|
||||
|
||||
clk_hw_unregister(&ctx->hw);
|
||||
clk_hw_unregister(&ctx->parent);
|
||||
clk_hw_unregister(&ctx->mux_ctx.hw);
|
||||
clk_hw_unregister(&ctx->mux_ctx.parents_ctx[0].hw);
|
||||
clk_hw_unregister(&ctx->mux_ctx.parents_ctx[1].hw);
|
||||
}
|
||||
|
||||
struct clk_leaf_mux_set_rate_parent_determine_rate_test_case {
|
||||
const char *desc;
|
||||
int (*determine_rate_func)(struct clk_hw *hw, struct clk_rate_request *req);
|
||||
};
|
||||
|
||||
static void
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc(
|
||||
const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *t, char *desc)
|
||||
{
|
||||
strcpy(desc, t->desc);
|
||||
}
|
||||
|
||||
static const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_cases[] = {
|
||||
{
|
||||
/*
|
||||
* Test that __clk_determine_rate() on the parent that can't
|
||||
* change rate doesn't return a clk_rate_request structure with
|
||||
* the best_parent_hw pointer pointing to the parent.
|
||||
*/
|
||||
.desc = "clk_leaf_mux_set_rate_parent__clk_determine_rate_proper_parent",
|
||||
.determine_rate_func = __clk_determine_rate,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that __clk_mux_determine_rate() on the parent that
|
||||
* can't change rate doesn't return a clk_rate_request
|
||||
* structure with the best_parent_hw pointer pointing to
|
||||
* the parent.
|
||||
*/
|
||||
.desc = "clk_leaf_mux_set_rate_parent__clk_mux_determine_rate_proper_parent",
|
||||
.determine_rate_func = __clk_mux_determine_rate,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that __clk_mux_determine_rate_closest() on the parent
|
||||
* that can't change rate doesn't return a clk_rate_request
|
||||
* structure with the best_parent_hw pointer pointing to
|
||||
* the parent.
|
||||
*/
|
||||
.desc = "clk_leaf_mux_set_rate_parent__clk_mux_determine_rate_closest_proper_parent",
|
||||
.determine_rate_func = __clk_mux_determine_rate_closest,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that clk_hw_determine_rate_no_reparent() on the parent
|
||||
* that can't change rate doesn't return a clk_rate_request
|
||||
* structure with the best_parent_hw pointer pointing to
|
||||
* the parent.
|
||||
*/
|
||||
.desc = "clk_leaf_mux_set_rate_parent_clk_hw_determine_rate_no_reparent_proper_parent",
|
||||
.determine_rate_func = clk_hw_determine_rate_no_reparent,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM(clk_leaf_mux_set_rate_parent_determine_rate_test,
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_cases,
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc)
|
||||
|
||||
/*
|
||||
* Test that, for a clock that will forward any rate request to its
|
||||
* parent, the rate request structure returned by __clk_determine_rate
|
||||
* is sane and will be what we expect.
|
||||
* Test that when a clk that can't change rate itself calls a function like
|
||||
* __clk_determine_rate() on its parent it doesn't get back a clk_rate_request
|
||||
* structure that has the best_parent_hw pointer point to the clk_hw passed
|
||||
* into the determine rate function. See commit 262ca38f4b6e ("clk: Stop
|
||||
* forwarding clk_rate_requests to the parent") for more background.
|
||||
*/
|
||||
static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test)
|
||||
static void clk_leaf_mux_set_rate_parent_determine_rate_test(struct kunit *test)
|
||||
{
|
||||
struct clk_leaf_mux_ctx *ctx = test->priv;
|
||||
struct clk_hw *hw = &ctx->hw;
|
||||
struct clk *clk = clk_hw_get_clk(hw, NULL);
|
||||
struct clk_rate_request req;
|
||||
unsigned long rate;
|
||||
int ret;
|
||||
const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *test_param;
|
||||
|
||||
test_param = test->param_value;
|
||||
ctx->determine_rate_func = test_param->determine_rate_func;
|
||||
|
||||
ctx->req = &req;
|
||||
rate = clk_get_rate(clk);
|
||||
KUNIT_ASSERT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
|
||||
|
||||
clk_hw_init_rate_request(hw, &req, DUMMY_CLOCK_RATE_2);
|
||||
|
||||
ret = __clk_determine_rate(hw, &req);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
KUNIT_ASSERT_EQ(test, DUMMY_CLOCK_RATE_2, clk_round_rate(clk, DUMMY_CLOCK_RATE_2));
|
||||
|
||||
KUNIT_EXPECT_EQ(test, req.rate, DUMMY_CLOCK_RATE_2);
|
||||
KUNIT_EXPECT_EQ(test, req.best_parent_rate, DUMMY_CLOCK_RATE_2);
|
||||
|
@ -2243,15 +2338,16 @@ static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case clk_leaf_mux_set_rate_parent_test_cases[] = {
|
||||
KUNIT_CASE(clk_leaf_mux_set_rate_parent_determine_rate),
|
||||
KUNIT_CASE_PARAM(clk_leaf_mux_set_rate_parent_determine_rate_test,
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Test suite for a clock whose parent is a mux with multiple parents.
|
||||
* The leaf clock has CLK_SET_RATE_PARENT, and will forward rate
|
||||
* requests to the mux, which will then select which parent is the best
|
||||
* fit for a given rate.
|
||||
* Test suite for a clock whose parent is a pass-through clk whose parent is a
|
||||
* mux with multiple parents. The leaf and pass-through clocks have the
|
||||
* CLK_SET_RATE_PARENT flag, and will forward rate requests to the mux, which
|
||||
* will then select which parent is the best fit for a given rate.
|
||||
*
|
||||
* These tests exercise the behaviour of muxes, and the proper selection
|
||||
* of parents.
|
||||
|
|
|
@ -37,6 +37,7 @@ config CLK_RENESAS
|
|||
select CLK_R9A07G043 if ARCH_R9A07G043
|
||||
select CLK_R9A07G044 if ARCH_R9A07G044
|
||||
select CLK_R9A07G054 if ARCH_R9A07G054
|
||||
select CLK_R9A08G045 if ARCH_R9A08G045
|
||||
select CLK_R9A09G011 if ARCH_R9A09G011
|
||||
select CLK_SH73A0 if ARCH_SH73A0
|
||||
|
||||
|
@ -179,6 +180,10 @@ config CLK_R9A07G054
|
|||
bool "RZ/V2L clock support" if COMPILE_TEST
|
||||
select CLK_RZG2L
|
||||
|
||||
config CLK_R9A08G045
|
||||
bool "RZ/G3S clock support" if COMPILE_TEST
|
||||
select CLK_RZG2L
|
||||
|
||||
config CLK_R9A09G011
|
||||
bool "RZ/V2M clock support" if COMPILE_TEST
|
||||
select CLK_RZG2L
|
||||
|
@ -215,7 +220,7 @@ config CLK_RCAR_USB2_CLOCK_SEL
|
|||
This is a driver for R-Car USB2 clock selector
|
||||
|
||||
config CLK_RZG2L
|
||||
bool "Renesas RZ/{G2L,G2UL,V2L} family clock support" if COMPILE_TEST
|
||||
bool "Renesas RZ/{G2L,G2UL,G3S,V2L} family clock support" if COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
|
||||
# Generic
|
||||
|
|
|
@ -34,6 +34,7 @@ obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
|
|||
obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A07G054) += r9a07g044-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A08G045) += r9a08g045-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A09G011) += r9a09g011-cpg.o
|
||||
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ enum clk_ids {
|
|||
MOD_CLK_BASE
|
||||
};
|
||||
|
||||
static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
|
||||
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
DEF_INPUT("extalr", CLK_EXTALR),
|
||||
|
@ -128,7 +128,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
|
|||
DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
|
||||
};
|
||||
|
||||
static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
|
||||
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("3dge", 112, R8A7795_CLK_ZG),
|
||||
DEF_MOD("fdp1-1", 118, R8A7795_CLK_S0D1),
|
||||
DEF_MOD("fdp1-0", 119, R8A7795_CLK_S0D1),
|
||||
|
|
|
@ -102,19 +102,22 @@ enum gate_type {
|
|||
* @source: the ID+1 of the parent clock element.
|
||||
* Root clock uses ID of ~0 (PARENT_ID);
|
||||
* @gate: clock enable/disable
|
||||
* @div_min: smallest permitted clock divider
|
||||
* @div_max: largest permitted clock divider
|
||||
* @reg: clock divider register offset, in 32-bit words
|
||||
* @div_table: optional list of fixed clock divider values;
|
||||
* @div: substructure for clock divider
|
||||
* @div.min: smallest permitted clock divider
|
||||
* @div.max: largest permitted clock divider
|
||||
* @div.reg: clock divider register offset, in 32-bit words
|
||||
* @div.table: optional list of fixed clock divider values;
|
||||
* must be in ascending order, zero for unused
|
||||
* @div: divisor for fixed-factor clock
|
||||
* @mul: multiplier for fixed-factor clock
|
||||
* @group: UART group, 0=UART0/1/2, 1=UART3/4/5/6/7
|
||||
* @sel: select either g1/r1 or g2/r2 as clock source
|
||||
* @g1: 1st source gate (clock enable/disable)
|
||||
* @r1: 1st source reset (module reset)
|
||||
* @g2: 2nd source gate (clock enable/disable)
|
||||
* @r2: 2nd source reset (module reset)
|
||||
* @ffc: substructure for fixed-factor clocks
|
||||
* @ffc.div: divisor for fixed-factor clock
|
||||
* @ffc.mul: multiplier for fixed-factor clock
|
||||
* @dual: substructure for dual clock gates
|
||||
* @dual.group: UART group, 0=UART0/1/2, 1=UART3/4/5/6/7
|
||||
* @dual.sel: select either g1/r1 or g2/r2 as clock source
|
||||
* @dual.g1: 1st source gate (clock enable/disable)
|
||||
* @dual.r1: 1st source reset (module reset)
|
||||
* @dual.g2: 2nd source gate (clock enable/disable)
|
||||
* @dual.r2: 2nd source reset (module reset)
|
||||
*
|
||||
* Describes a single element in the clock tree hierarchy.
|
||||
* As there are quite a large number of clock elements, this
|
||||
|
@ -131,13 +134,13 @@ struct r9a06g032_clkdesc {
|
|||
struct r9a06g032_gate gate;
|
||||
/* type = K_DIV */
|
||||
struct {
|
||||
unsigned int div_min:10, div_max:10, reg:10;
|
||||
u16 div_table[4];
|
||||
};
|
||||
unsigned int min:10, max:10, reg:10;
|
||||
u16 table[4];
|
||||
} div;
|
||||
/* type = K_FFC */
|
||||
struct {
|
||||
u16 div, mul;
|
||||
};
|
||||
} ffc;
|
||||
/* type = K_DUALGATE */
|
||||
struct {
|
||||
uint16_t group:1;
|
||||
|
@ -178,26 +181,26 @@ struct r9a06g032_clkdesc {
|
|||
.type = K_FFC, \
|
||||
.index = R9A06G032_##_idx, \
|
||||
.name = _n, \
|
||||
.div = _div, \
|
||||
.mul = _mul \
|
||||
.ffc.div = _div, \
|
||||
.ffc.mul = _mul \
|
||||
}
|
||||
#define D_FFC(_idx, _n, _src, _div) { \
|
||||
.type = K_FFC, \
|
||||
.index = R9A06G032_##_idx, \
|
||||
.source = 1 + R9A06G032_##_src, \
|
||||
.name = _n, \
|
||||
.div = _div, \
|
||||
.mul = 1 \
|
||||
.ffc.div = _div, \
|
||||
.ffc.mul = 1 \
|
||||
}
|
||||
#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) { \
|
||||
.type = K_DIV, \
|
||||
.index = R9A06G032_##_idx, \
|
||||
.source = 1 + R9A06G032_##_src, \
|
||||
.name = _n, \
|
||||
.reg = _reg, \
|
||||
.div_min = _min, \
|
||||
.div_max = _max, \
|
||||
.div_table = { __VA_ARGS__ } \
|
||||
.div.reg = _reg, \
|
||||
.div.min = _min, \
|
||||
.div.max = _max, \
|
||||
.div.table = { __VA_ARGS__ } \
|
||||
}
|
||||
#define D_UGATE(_idx, _n, _src, _g, _g1, _r1, _g2, _r2) { \
|
||||
.type = K_DUALGATE, \
|
||||
|
@ -1063,14 +1066,14 @@ r9a06g032_register_div(struct r9a06g032_priv *clocks,
|
|||
|
||||
div->clocks = clocks;
|
||||
div->index = desc->index;
|
||||
div->reg = desc->reg;
|
||||
div->reg = desc->div.reg;
|
||||
div->hw.init = &init;
|
||||
div->min = desc->div_min;
|
||||
div->max = desc->div_max;
|
||||
div->min = desc->div.min;
|
||||
div->max = desc->div.max;
|
||||
/* populate (optional) divider table fixed values */
|
||||
for (i = 0; i < ARRAY_SIZE(div->table) &&
|
||||
i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) {
|
||||
div->table[div->table_size++] = desc->div_table[i];
|
||||
i < ARRAY_SIZE(desc->div.table) && desc->div.table[i]; i++) {
|
||||
div->table[div->table_size++] = desc->div.table[i];
|
||||
}
|
||||
|
||||
clk = clk_register(NULL, &div->hw);
|
||||
|
@ -1269,11 +1272,10 @@ static void r9a06g032_clocks_del_clk_provider(void *data)
|
|||
|
||||
static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks)
|
||||
{
|
||||
struct device_node *usbf_np = NULL;
|
||||
struct device_node *usbf_np;
|
||||
u32 usb;
|
||||
|
||||
while ((usbf_np = of_find_compatible_node(usbf_np, NULL,
|
||||
"renesas,rzn1-usbf"))) {
|
||||
for_each_compatible_node(usbf_np, NULL, "renesas,rzn1-usbf") {
|
||||
if (of_device_is_available(usbf_np))
|
||||
break;
|
||||
}
|
||||
|
@ -1333,7 +1335,8 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
|
|||
case K_FFC:
|
||||
clk = clk_register_fixed_factor(NULL, d->name,
|
||||
parent_name, 0,
|
||||
d->mul, d->div);
|
||||
d->ffc.mul,
|
||||
d->ffc.div);
|
||||
break;
|
||||
case K_GATE:
|
||||
clk = r9a06g032_register_gate(clocks, parent_name, d);
|
||||
|
|
|
@ -14,6 +14,17 @@
|
|||
|
||||
#include "rzg2l-cpg.h"
|
||||
|
||||
/* Specific registers. */
|
||||
#define CPG_PL2SDHI_DSEL (0x218)
|
||||
|
||||
/* Clock select configuration. */
|
||||
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||||
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||||
|
||||
/* Clock status configuration. */
|
||||
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||||
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A07G043_CLK_P0_DIV2,
|
||||
|
@ -78,6 +89,8 @@ static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
|||
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
||||
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||||
|
||||
static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||||
|
||||
static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
|
@ -123,8 +136,10 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
|||
DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||||
DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||||
DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||||
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, sel_shdi),
|
||||
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, sel_shdi),
|
||||
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
|
||||
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
|
||||
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
|
||||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
|
||||
};
|
||||
|
|
|
@ -15,6 +15,17 @@
|
|||
|
||||
#include "rzg2l-cpg.h"
|
||||
|
||||
/* Specific registers. */
|
||||
#define CPG_PL2SDHI_DSEL (0x218)
|
||||
|
||||
/* Clock select configuration. */
|
||||
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||||
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||||
|
||||
/* Clock status configuration. */
|
||||
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||||
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
|
||||
|
@ -98,6 +109,8 @@ static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
|||
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||||
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
|
||||
|
||||
static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||||
|
||||
static const struct {
|
||||
struct cpg_core_clk common[56];
|
||||
#ifdef CONFIG_CLK_R9A07G054
|
||||
|
@ -163,8 +176,10 @@ static const struct {
|
|||
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||||
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||||
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||||
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, sel_shdi),
|
||||
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, sel_shdi),
|
||||
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
|
||||
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
|
||||
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
|
||||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
|
||||
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8),
|
||||
|
|
248
drivers/clk/renesas/r9a08g045-cpg.c
Normal file
248
drivers/clk/renesas/r9a08g045-cpg.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* RZ/G3S CPG driver
|
||||
*
|
||||
* Copyright (C) 2023 Renesas Electronics Corp.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/clock/r9a08g045-cpg.h>
|
||||
|
||||
#include "rzg2l-cpg.h"
|
||||
|
||||
/* RZ/G3S Specific registers. */
|
||||
#define G3S_CPG_PL2_DDIV (0x204)
|
||||
#define G3S_CPG_SDHI_DDIV (0x218)
|
||||
#define G3S_CPG_PLL_DSEL (0x240)
|
||||
#define G3S_CPG_SDHI_DSEL (0x244)
|
||||
#define G3S_CLKDIVSTATUS (0x280)
|
||||
#define G3S_CLKSELSTATUS (0x284)
|
||||
|
||||
/* RZ/G3S Specific division configuration. */
|
||||
#define G3S_DIVPL2B DDIV_PACK(G3S_CPG_PL2_DDIV, 4, 3)
|
||||
#define G3S_DIV_SDHI0 DDIV_PACK(G3S_CPG_SDHI_DDIV, 0, 1)
|
||||
#define G3S_DIV_SDHI1 DDIV_PACK(G3S_CPG_SDHI_DDIV, 4, 1)
|
||||
#define G3S_DIV_SDHI2 DDIV_PACK(G3S_CPG_SDHI_DDIV, 8, 1)
|
||||
|
||||
/* RZ/G3S Clock status configuration. */
|
||||
#define G3S_DIVPL1A_STS DDIV_PACK(G3S_CLKDIVSTATUS, 0, 1)
|
||||
#define G3S_DIVPL2B_STS DDIV_PACK(G3S_CLKDIVSTATUS, 5, 1)
|
||||
#define G3S_DIVPL3A_STS DDIV_PACK(G3S_CLKDIVSTATUS, 8, 1)
|
||||
#define G3S_DIVPL3B_STS DDIV_PACK(G3S_CLKDIVSTATUS, 9, 1)
|
||||
#define G3S_DIVPL3C_STS DDIV_PACK(G3S_CLKDIVSTATUS, 10, 1)
|
||||
#define G3S_DIV_SDHI0_STS DDIV_PACK(G3S_CLKDIVSTATUS, 24, 1)
|
||||
#define G3S_DIV_SDHI1_STS DDIV_PACK(G3S_CLKDIVSTATUS, 25, 1)
|
||||
#define G3S_DIV_SDHI2_STS DDIV_PACK(G3S_CLKDIVSTATUS, 26, 1)
|
||||
|
||||
#define G3S_SEL_PLL4_STS SEL_PLL_PACK(G3S_CLKSELSTATUS, 6, 1)
|
||||
#define G3S_SEL_SDHI0_STS SEL_PLL_PACK(G3S_CLKSELSTATUS, 16, 1)
|
||||
#define G3S_SEL_SDHI1_STS SEL_PLL_PACK(G3S_CLKSELSTATUS, 17, 1)
|
||||
#define G3S_SEL_SDHI2_STS SEL_PLL_PACK(G3S_CLKSELSTATUS, 18, 1)
|
||||
|
||||
/* RZ/G3S Specific clocks select. */
|
||||
#define G3S_SEL_PLL4 SEL_PLL_PACK(G3S_CPG_PLL_DSEL, 6, 1)
|
||||
#define G3S_SEL_SDHI0 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 0, 2)
|
||||
#define G3S_SEL_SDHI1 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 4, 2)
|
||||
#define G3S_SEL_SDHI2 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 8, 2)
|
||||
|
||||
/* PLL 1/4/6 configuration registers macro. */
|
||||
#define G3S_PLL146_CONF(clk1, clk2) ((clk1) << 22 | (clk2) << 12)
|
||||
|
||||
#define DEF_G3S_MUX(_name, _id, _conf, _parent_names, _mux_flags, _clk_flags) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = (_conf), \
|
||||
.parent_names = (_parent_names), \
|
||||
.num_parents = ARRAY_SIZE((_parent_names)), \
|
||||
.mux_flags = CLK_MUX_HIWORD_MASK | (_mux_flags), \
|
||||
.flag = (_clk_flags))
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A08G045_SWD,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_EXTAL,
|
||||
|
||||
/* Internal Core Clocks */
|
||||
CLK_OSC_DIV1000,
|
||||
CLK_PLL1,
|
||||
CLK_PLL2,
|
||||
CLK_PLL2_DIV2,
|
||||
CLK_PLL2_DIV2_8,
|
||||
CLK_PLL2_DIV6,
|
||||
CLK_PLL3,
|
||||
CLK_PLL3_DIV2,
|
||||
CLK_PLL3_DIV2_4,
|
||||
CLK_PLL3_DIV2_8,
|
||||
CLK_PLL3_DIV6,
|
||||
CLK_PLL4,
|
||||
CLK_PLL6,
|
||||
CLK_PLL6_DIV2,
|
||||
CLK_SEL_SDHI0,
|
||||
CLK_SEL_SDHI1,
|
||||
CLK_SEL_SDHI2,
|
||||
CLK_SEL_PLL4,
|
||||
CLK_P1_DIV2,
|
||||
CLK_P3_DIV2,
|
||||
CLK_SD0_DIV4,
|
||||
CLK_SD1_DIV4,
|
||||
CLK_SD2_DIV4,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE,
|
||||
};
|
||||
|
||||
/* Divider tables */
|
||||
static const struct clk_div_table dtable_1_2[] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 2 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_1_8[] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 2 },
|
||||
{ 2, 4 },
|
||||
{ 3, 8 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_1_32[] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 2 },
|
||||
{ 2, 4 },
|
||||
{ 3, 8 },
|
||||
{ 4, 32 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
/* Mux clock names tables. */
|
||||
static const char * const sel_sdhi[] = { ".pll2_div2", ".pll6", ".pll2_div6" };
|
||||
static const char * const sel_pll4[] = { ".osc_div1000", ".pll4" };
|
||||
|
||||
/* Mux clock indices tables. */
|
||||
static const u32 mtable_sd[] = { 0, 2, 3 };
|
||||
static const u32 mtable_pll4[] = { 0, 1 };
|
||||
|
||||
static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
|
||||
/* Internal Core Clocks */
|
||||
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
|
||||
DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8)),
|
||||
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
|
||||
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
|
||||
DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 100, 3),
|
||||
DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),
|
||||
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
|
||||
DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8),
|
||||
DEF_FIXED(".pll2_div6", CLK_PLL2_DIV6, CLK_PLL2, 1, 6),
|
||||
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
|
||||
DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
|
||||
DEF_FIXED(".pll3_div2_8", CLK_PLL3_DIV2_8, CLK_PLL3_DIV2, 1, 8),
|
||||
DEF_FIXED(".pll3_div6", CLK_PLL3_DIV6, CLK_PLL3, 1, 6),
|
||||
DEF_FIXED(".pll6_div2", CLK_PLL6_DIV2, CLK_PLL6, 1, 2),
|
||||
DEF_SD_MUX(".sel_sd0", CLK_SEL_SDHI0, G3S_SEL_SDHI0, G3S_SEL_SDHI0_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_SD_MUX(".sel_sd1", CLK_SEL_SDHI1, G3S_SEL_SDHI1, G3S_SEL_SDHI1_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_SD_MUX(".sel_sd2", CLK_SEL_SDHI2, G3S_SEL_SDHI2, G3S_SEL_SDHI2_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_SD_MUX(".sel_pll4", CLK_SEL_PLL4, G3S_SEL_PLL4, G3S_SEL_PLL4_STS, sel_pll4,
|
||||
mtable_pll4, CLK_SET_PARENT_GATE, NULL),
|
||||
|
||||
/* Core output clk */
|
||||
DEF_G3S_DIV("I", R9A08G045_CLK_I, CLK_PLL1, DIVPL1A, G3S_DIVPL1A_STS, dtable_1_8,
|
||||
0, 0, 0, NULL),
|
||||
DEF_G3S_DIV("P0", R9A08G045_CLK_P0, CLK_PLL2_DIV2_8, G3S_DIVPL2B, G3S_DIVPL2B_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_G3S_DIV("SD0", R9A08G045_CLK_SD0, CLK_SEL_SDHI0, G3S_DIV_SDHI0, G3S_DIV_SDHI0_STS,
|
||||
dtable_1_2, 800000000UL, 500000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_G3S_DIV("SD1", R9A08G045_CLK_SD1, CLK_SEL_SDHI1, G3S_DIV_SDHI1, G3S_DIV_SDHI1_STS,
|
||||
dtable_1_2, 800000000UL, 500000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_G3S_DIV("SD2", R9A08G045_CLK_SD2, CLK_SEL_SDHI2, G3S_DIV_SDHI2, G3S_DIV_SDHI2_STS,
|
||||
dtable_1_2, 800000000UL, 500000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_FIXED(".sd0_div4", CLK_SD0_DIV4, R9A08G045_CLK_SD0, 1, 4),
|
||||
DEF_FIXED(".sd1_div4", CLK_SD1_DIV4, R9A08G045_CLK_SD1, 1, 4),
|
||||
DEF_FIXED(".sd2_div4", CLK_SD2_DIV4, R9A08G045_CLK_SD2, 1, 4),
|
||||
DEF_FIXED("M0", R9A08G045_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
|
||||
DEF_G3S_DIV("P1", R9A08G045_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3A, G3S_DIVPL3A_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A08G045_CLK_P1, 1, 2),
|
||||
DEF_G3S_DIV("P2", R9A08G045_CLK_P2, CLK_PLL3_DIV2_8, DIVPL3B, G3S_DIVPL3B_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_G3S_DIV("P3", R9A08G045_CLK_P3, CLK_PLL3_DIV2_4, DIVPL3C, G3S_DIVPL3C_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_FIXED("P3_DIV2", CLK_P3_DIV2, R9A08G045_CLK_P3, 1, 2),
|
||||
DEF_FIXED("S0", R9A08G045_CLK_S0, CLK_SEL_PLL4, 1, 2),
|
||||
DEF_FIXED("OSC", R9A08G045_OSCCLK, CLK_EXTAL, 1, 1),
|
||||
DEF_FIXED("OSC2", R9A08G045_OSCCLK2, CLK_EXTAL, 1, 3),
|
||||
};
|
||||
|
||||
static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
|
||||
DEF_MOD("gic_gicclk", R9A08G045_GIC600_GICCLK, R9A08G045_CLK_P1, 0x514, 0),
|
||||
DEF_MOD("ia55_clk", R9A08G045_IA55_CLK, R9A08G045_CLK_P1, 0x518, 1),
|
||||
DEF_MOD("dmac_aclk", R9A08G045_DMAC_ACLK, R9A08G045_CLK_P3, 0x52c, 0),
|
||||
DEF_MOD("sdhi0_imclk", R9A08G045_SDHI0_IMCLK, CLK_SD0_DIV4, 0x554, 0),
|
||||
DEF_MOD("sdhi0_imclk2", R9A08G045_SDHI0_IMCLK2, CLK_SD0_DIV4, 0x554, 1),
|
||||
DEF_MOD("sdhi0_clk_hs", R9A08G045_SDHI0_CLK_HS, R9A08G045_CLK_SD0, 0x554, 2),
|
||||
DEF_MOD("sdhi0_aclk", R9A08G045_SDHI0_ACLK, R9A08G045_CLK_P1, 0x554, 3),
|
||||
DEF_MOD("sdhi1_imclk", R9A08G045_SDHI1_IMCLK, CLK_SD1_DIV4, 0x554, 4),
|
||||
DEF_MOD("sdhi1_imclk2", R9A08G045_SDHI1_IMCLK2, CLK_SD1_DIV4, 0x554, 5),
|
||||
DEF_MOD("sdhi1_clk_hs", R9A08G045_SDHI1_CLK_HS, R9A08G045_CLK_SD1, 0x554, 6),
|
||||
DEF_MOD("sdhi1_aclk", R9A08G045_SDHI1_ACLK, R9A08G045_CLK_P1, 0x554, 7),
|
||||
DEF_MOD("sdhi2_imclk", R9A08G045_SDHI2_IMCLK, CLK_SD2_DIV4, 0x554, 8),
|
||||
DEF_MOD("sdhi2_imclk2", R9A08G045_SDHI2_IMCLK2, CLK_SD2_DIV4, 0x554, 9),
|
||||
DEF_MOD("sdhi2_clk_hs", R9A08G045_SDHI2_CLK_HS, R9A08G045_CLK_SD2, 0x554, 10),
|
||||
DEF_MOD("sdhi2_aclk", R9A08G045_SDHI2_ACLK, R9A08G045_CLK_P1, 0x554, 11),
|
||||
DEF_MOD("scif0_clk_pck", R9A08G045_SCIF0_CLK_PCK, R9A08G045_CLK_P0, 0x584, 0),
|
||||
DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0),
|
||||
};
|
||||
|
||||
static const struct rzg2l_reset r9a08g045_resets[] = {
|
||||
DEF_RST(R9A08G045_GIC600_GICRESET_N, 0x814, 0),
|
||||
DEF_RST(R9A08G045_GIC600_DBG_GICRESET_N, 0x814, 1),
|
||||
DEF_RST(R9A08G045_SDHI0_IXRST, 0x854, 0),
|
||||
DEF_RST(R9A08G045_SDHI1_IXRST, 0x854, 1),
|
||||
DEF_RST(R9A08G045_SDHI2_IXRST, 0x854, 2),
|
||||
DEF_RST(R9A08G045_SCIF0_RST_SYSTEM_N, 0x884, 0),
|
||||
DEF_RST(R9A08G045_GPIO_RSTN, 0x898, 0),
|
||||
DEF_RST(R9A08G045_GPIO_PORT_RESETN, 0x898, 1),
|
||||
DEF_RST(R9A08G045_GPIO_SPARE_RESETN, 0x898, 2),
|
||||
};
|
||||
|
||||
static const unsigned int r9a08g045_crit_mod_clks[] __initconst = {
|
||||
MOD_CLK_BASE + R9A08G045_GIC600_GICCLK,
|
||||
MOD_CLK_BASE + R9A08G045_IA55_CLK,
|
||||
MOD_CLK_BASE + R9A08G045_DMAC_ACLK,
|
||||
};
|
||||
|
||||
const struct rzg2l_cpg_info r9a08g045_cpg_info = {
|
||||
/* Core Clocks */
|
||||
.core_clks = r9a08g045_core_clks,
|
||||
.num_core_clks = ARRAY_SIZE(r9a08g045_core_clks),
|
||||
.last_dt_core_clk = LAST_DT_CORE_CLK,
|
||||
.num_total_core_clks = MOD_CLK_BASE,
|
||||
|
||||
/* Critical Module Clocks */
|
||||
.crit_mod_clks = r9a08g045_crit_mod_clks,
|
||||
.num_crit_mod_clks = ARRAY_SIZE(r9a08g045_crit_mod_clks),
|
||||
|
||||
/* Module Clocks */
|
||||
.mod_clks = r9a08g045_mod_clks,
|
||||
.num_mod_clks = ARRAY_SIZE(r9a08g045_mod_clks),
|
||||
.num_hw_mod_clks = R9A08G045_VBAT_BCLK + 1,
|
||||
|
||||
/* Resets */
|
||||
.resets = r9a08g045_resets,
|
||||
.num_resets = R9A08G045_VBAT_BRESETN + 1, /* Last reset ID + 1 */
|
||||
|
||||
.has_clk_mon_regs = true,
|
||||
};
|
|
@ -70,8 +70,21 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
|
|||
#define STPnHCK BIT(9 - SDnSRCFC_SHIFT)
|
||||
|
||||
static const struct clk_div_table cpg_sdh_div_table[] = {
|
||||
/*
|
||||
* These values are recommended by the datasheet. Because they come
|
||||
* first, Linux will only use these.
|
||||
*/
|
||||
{ 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 },
|
||||
{ STPnHCK | 4, 16 }, { 0, 0 },
|
||||
{ STPnHCK | 4, 16 },
|
||||
/*
|
||||
* These values are not recommended because STPnHCK is wrong. But they
|
||||
* have been seen because of broken firmware. So, we support reading
|
||||
* them but Linux will sanitize them when initializing through
|
||||
* recalc_rate.
|
||||
*/
|
||||
{ STPnHCK | 0, 1 }, { STPnHCK | 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 },
|
||||
/* Sentinel */
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
struct clk * __init cpg_sdh_clk_register(const char *name,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Copyright (C) 2015 Renesas Electronics Corp.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
|
@ -38,14 +39,18 @@
|
|||
#define WARN_DEBUG(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define DIV_RSMASK(v, s, m) ((v >> s) & m)
|
||||
#define GET_SHIFT(val) ((val >> 12) & 0xff)
|
||||
#define GET_WIDTH(val) ((val >> 8) & 0xf)
|
||||
|
||||
#define KDIV(val) DIV_RSMASK(val, 16, 0xffff)
|
||||
#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff)
|
||||
#define PDIV(val) DIV_RSMASK(val, 0, 0x3f)
|
||||
#define SDIV(val) DIV_RSMASK(val, 0, 0x7)
|
||||
#define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), val))
|
||||
#define MDIV(val) FIELD_GET(GENMASK(15, 6), val)
|
||||
#define PDIV(val) FIELD_GET(GENMASK(5, 0), val)
|
||||
#define SDIV(val) FIELD_GET(GENMASK(2, 0), val)
|
||||
|
||||
#define RZG3S_DIV_P GENMASK(28, 26)
|
||||
#define RZG3S_DIV_M GENMASK(25, 22)
|
||||
#define RZG3S_DIV_NI GENMASK(21, 13)
|
||||
#define RZG3S_DIV_NF GENMASK(12, 1)
|
||||
|
||||
#define CLK_ON_R(reg) (reg)
|
||||
#define CLK_MON_R(reg) (0x180 + (reg))
|
||||
|
@ -56,15 +61,55 @@
|
|||
#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
|
||||
#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
|
||||
|
||||
#define CPG_WEN_BIT BIT(16)
|
||||
|
||||
#define MAX_VCLK_FREQ (148500000)
|
||||
|
||||
struct sd_hw_data {
|
||||
/**
|
||||
* struct clk_hw_data - clock hardware data
|
||||
* @hw: clock hw
|
||||
* @conf: clock configuration (register offset, shift, width)
|
||||
* @sconf: clock status configuration (register offset, shift, width)
|
||||
* @priv: CPG private data structure
|
||||
*/
|
||||
struct clk_hw_data {
|
||||
struct clk_hw hw;
|
||||
u32 conf;
|
||||
u32 sconf;
|
||||
struct rzg2l_cpg_priv *priv;
|
||||
};
|
||||
|
||||
#define to_sd_hw_data(_hw) container_of(_hw, struct sd_hw_data, hw)
|
||||
#define to_clk_hw_data(_hw) container_of(_hw, struct clk_hw_data, hw)
|
||||
|
||||
/**
|
||||
* struct sd_mux_hw_data - SD MUX clock hardware data
|
||||
* @hw_data: clock hw data
|
||||
* @mtable: clock mux table
|
||||
*/
|
||||
struct sd_mux_hw_data {
|
||||
struct clk_hw_data hw_data;
|
||||
const u32 *mtable;
|
||||
};
|
||||
|
||||
#define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data)
|
||||
|
||||
/**
|
||||
* struct div_hw_data - divider clock hardware data
|
||||
* @hw_data: clock hw data
|
||||
* @dtable: pointer to divider table
|
||||
* @invalid_rate: invalid rate for divider
|
||||
* @max_rate: maximum rate for divider
|
||||
* @width: divider width
|
||||
*/
|
||||
struct div_hw_data {
|
||||
struct clk_hw_data hw_data;
|
||||
const struct clk_div_table *dtable;
|
||||
unsigned long invalid_rate;
|
||||
unsigned long max_rate;
|
||||
u32 width;
|
||||
};
|
||||
|
||||
#define to_div_hw_data(_hw) container_of(_hw, struct div_hw_data, hw_data)
|
||||
|
||||
struct rzg2l_pll5_param {
|
||||
u32 pl5_fracin;
|
||||
|
@ -121,6 +166,241 @@ static void rzg2l_cpg_del_clk_provider(void *data)
|
|||
of_clk_del_provider(data);
|
||||
}
|
||||
|
||||
/* Must be called in atomic context. */
|
||||
static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf)
|
||||
{
|
||||
u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf);
|
||||
u32 off = GET_REG_OFFSET(conf);
|
||||
u32 val;
|
||||
|
||||
return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200);
|
||||
}
|
||||
|
||||
int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event,
|
||||
void *data)
|
||||
{
|
||||
struct clk_notifier_data *cnd = data;
|
||||
struct clk_hw *hw = __clk_get_hw(cnd->clk);
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||
const u32 clk_src_266 = 3;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
|
||||
/*
|
||||
* As per the HW manual, we should not directly switch from 533 MHz to
|
||||
* 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
||||
* to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
||||
* and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
||||
* (400 MHz)).
|
||||
* Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
||||
* switching register is prohibited.
|
||||
* The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
||||
* the index to value mapping is done by adding 1 to the index.
|
||||
*/
|
||||
|
||||
writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off);
|
||||
|
||||
/* Wait for the update done. */
|
||||
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
|
||||
if (ret)
|
||||
dev_err(priv->dev, "failed to switch to safe clk source\n");
|
||||
|
||||
return notifier_from_errno(ret);
|
||||
}
|
||||
|
||||
int rzg3s_cpg_div_clk_notifier(struct notifier_block *nb, unsigned long event,
|
||||
void *data)
|
||||
{
|
||||
struct clk_notifier_data *cnd = data;
|
||||
struct clk_hw *hw = __clk_get_hw(cnd->clk);
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate ||
|
||||
div_hw_data->invalid_rate % cnd->new_rate)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
|
||||
val = readl(priv->base + off);
|
||||
val >>= shift;
|
||||
val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);
|
||||
|
||||
/*
|
||||
* There are different constraints for the user of this notifiers as follows:
|
||||
* 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz
|
||||
* 2/ OCTA / SPI div cannot be 1 (val == 0) if parent rate is 400MHz
|
||||
* As SD can have only one parent having 800MHz and OCTA div can have
|
||||
* only one parent having 400MHz we took into account the parent rate
|
||||
* at the beginning of function (by checking invalid_rate % new_rate).
|
||||
* Now it is time to check the hardware divider and update it accordingly.
|
||||
*/
|
||||
if (!val) {
|
||||
writel((CPG_WEN_BIT | 1) << shift, priv->base + off);
|
||||
/* Wait for the update done. */
|
||||
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
|
||||
if (ret)
|
||||
dev_err(priv->dev, "Failed to downgrade the div\n");
|
||||
|
||||
return notifier_from_errno(ret);
|
||||
}
|
||||
|
||||
static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core,
|
||||
struct rzg2l_cpg_priv *priv)
|
||||
{
|
||||
struct notifier_block *nb;
|
||||
|
||||
if (!core->notifier)
|
||||
return 0;
|
||||
|
||||
nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL);
|
||||
if (!nb)
|
||||
return -ENOMEM;
|
||||
|
||||
nb->notifier_call = core->notifier;
|
||||
|
||||
return clk_notifier_register(hw->clk, nb);
|
||||
}
|
||||
|
||||
static unsigned long rzg3s_div_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 val;
|
||||
|
||||
val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));
|
||||
val >>= GET_SHIFT(clk_hw_data->conf);
|
||||
val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);
|
||||
|
||||
return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable,
|
||||
CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width);
|
||||
}
|
||||
|
||||
static int rzg3s_div_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);
|
||||
|
||||
if (div_hw_data->max_rate && req->rate > div_hw_data->max_rate)
|
||||
req->rate = div_hw_data->max_rate;
|
||||
|
||||
return divider_determine_rate(hw, req, div_hw_data->dtable, div_hw_data->width,
|
||||
CLK_DIVIDER_ROUND_CLOSEST);
|
||||
}
|
||||
|
||||
static int rzg3s_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width,
|
||||
CLK_DIVIDER_ROUND_CLOSEST);
|
||||
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
writel((CPG_WEN_BIT | val) << shift, priv->base + off);
|
||||
/* Wait for the update done. */
|
||||
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct clk_ops rzg3s_div_clk_ops = {
|
||||
.recalc_rate = rzg3s_div_clk_recalc_rate,
|
||||
.determine_rate = rzg3s_div_clk_determine_rate,
|
||||
.set_rate = rzg3s_div_clk_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct clk **clks,
|
||||
void __iomem *base, struct rzg2l_cpg_priv *priv)
|
||||
{
|
||||
struct div_hw_data *div_hw_data;
|
||||
struct clk_init_data init = {};
|
||||
const struct clk_div_table *clkt;
|
||||
struct clk_hw *clk_hw;
|
||||
const struct clk *parent;
|
||||
const char *parent_name;
|
||||
u32 max = 0;
|
||||
int ret;
|
||||
|
||||
parent = clks[core->parent & 0xffff];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
|
||||
div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL);
|
||||
if (!div_hw_data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = core->name;
|
||||
init.flags = core->flag;
|
||||
init.ops = &rzg3s_div_clk_ops;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
/* Get the maximum divider to retrieve div width. */
|
||||
for (clkt = core->dtable; clkt->div; clkt++) {
|
||||
if (max < clkt->div)
|
||||
max = clkt->div;
|
||||
}
|
||||
|
||||
div_hw_data->hw_data.priv = priv;
|
||||
div_hw_data->hw_data.conf = core->conf;
|
||||
div_hw_data->hw_data.sconf = core->sconf;
|
||||
div_hw_data->dtable = core->dtable;
|
||||
div_hw_data->invalid_rate = core->invalid_rate;
|
||||
div_hw_data->max_rate = core->max_rate;
|
||||
div_hw_data->width = fls(max) - 1;
|
||||
|
||||
clk_hw = &div_hw_data->hw_data.hw;
|
||||
clk_hw->init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = rzg2l_register_notifier(clk_hw, core, priv);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Failed to register notifier for %s\n",
|
||||
core->name);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk_hw->clk;
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
|
||||
struct clk **clks,
|
||||
|
@ -183,63 +463,44 @@ rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core,
|
|||
|
||||
static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
||||
struct rzg2l_cpg_priv *priv = hwdata->priv;
|
||||
u32 off = GET_REG_OFFSET(hwdata->conf);
|
||||
u32 shift = GET_SHIFT(hwdata->conf);
|
||||
const u32 clk_src_266 = 2;
|
||||
u32 bitmask;
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||||
u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* As per the HW manual, we should not directly switch from 533 MHz to
|
||||
* 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
||||
* to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
||||
* and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
||||
* (400 MHz)).
|
||||
* Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
||||
* switching register is prohibited.
|
||||
* The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
||||
* the index to value mapping is done by adding 1 to the index.
|
||||
*/
|
||||
bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16;
|
||||
if (index != clk_src_266) {
|
||||
u32 msk, val;
|
||||
int ret;
|
||||
val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index);
|
||||
|
||||
writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off);
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
|
||||
msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS;
|
||||
writel((CPG_WEN_BIT | val) << shift, priv->base + off);
|
||||
|
||||
ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val,
|
||||
!(val & msk), 100,
|
||||
CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "failed to switch clk source\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* Wait for the update done. */
|
||||
ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||||
|
||||
writel(bitmask | ((index + 1) << shift), priv->base + off);
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
|
||||
return 0;
|
||||
if (ret)
|
||||
dev_err(priv->dev, "Failed to switch parent\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
||||
struct rzg2l_cpg_priv *priv = hwdata->priv;
|
||||
u32 val = readl(priv->base + GET_REG_OFFSET(hwdata->conf));
|
||||
struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||||
struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||||
struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||||
u32 val;
|
||||
|
||||
val >>= GET_SHIFT(hwdata->conf);
|
||||
val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0);
|
||||
if (val) {
|
||||
val--;
|
||||
} else {
|
||||
/* Prohibited clk source, change it to 533 MHz(reset value) */
|
||||
rzg2l_cpg_sd_clk_mux_set_parent(hw, 0);
|
||||
}
|
||||
val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));
|
||||
val >>= GET_SHIFT(clk_hw_data->conf);
|
||||
val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);
|
||||
|
||||
return val;
|
||||
return clk_mux_val_to_index(hw, sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, val);
|
||||
}
|
||||
|
||||
static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {
|
||||
|
@ -253,31 +514,40 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core,
|
|||
void __iomem *base,
|
||||
struct rzg2l_cpg_priv *priv)
|
||||
{
|
||||
struct sd_hw_data *clk_hw_data;
|
||||
struct sd_mux_hw_data *sd_mux_hw_data;
|
||||
struct clk_init_data init;
|
||||
struct clk_hw *clk_hw;
|
||||
int ret;
|
||||
|
||||
clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
|
||||
if (!clk_hw_data)
|
||||
sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL);
|
||||
if (!sd_mux_hw_data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_hw_data->priv = priv;
|
||||
clk_hw_data->conf = core->conf;
|
||||
sd_mux_hw_data->hw_data.priv = priv;
|
||||
sd_mux_hw_data->hw_data.conf = core->conf;
|
||||
sd_mux_hw_data->hw_data.sconf = core->sconf;
|
||||
sd_mux_hw_data->mtable = core->mtable;
|
||||
|
||||
init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0";
|
||||
init.name = core->name;
|
||||
init.ops = &rzg2l_cpg_sd_clk_mux_ops;
|
||||
init.flags = 0;
|
||||
init.flags = core->flag;
|
||||
init.num_parents = core->num_parents;
|
||||
init.parent_names = core->parent_names;
|
||||
|
||||
clk_hw = &clk_hw_data->hw;
|
||||
clk_hw = &sd_mux_hw_data->hw_data.hw;
|
||||
clk_hw->init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = rzg2l_register_notifier(clk_hw, core, priv);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Failed to register notifier for %s\n",
|
||||
core->name);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk_hw->clk;
|
||||
}
|
||||
|
||||
|
@ -695,29 +965,61 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
|
|||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
struct rzg2l_cpg_priv *priv = pll_clk->priv;
|
||||
unsigned int val1, val2;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
u64 rate;
|
||||
|
||||
if (pll_clk->type != CLK_TYPE_SAM_PLL)
|
||||
return parent_rate;
|
||||
|
||||
val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
|
||||
val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
|
||||
mult = MDIV(val1) + KDIV(val1) / 65536;
|
||||
div = PDIV(val1) << SDIV(val2);
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
|
||||
rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1),
|
||||
16 + SDIV(val2));
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1));
|
||||
}
|
||||
|
||||
static const struct clk_ops rzg2l_cpg_pll_ops = {
|
||||
.recalc_rate = rzg2l_cpg_pll_clk_recalc_rate,
|
||||
};
|
||||
|
||||
static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
struct rzg2l_cpg_priv *priv = pll_clk->priv;
|
||||
u32 nir, nfr, mr, pr, val;
|
||||
u64 rate;
|
||||
|
||||
if (pll_clk->type != CLK_TYPE_G3S_PLL)
|
||||
return parent_rate;
|
||||
|
||||
val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
|
||||
|
||||
pr = 1 << FIELD_GET(RZG3S_DIV_P, val);
|
||||
/* Hardware interprets values higher than 8 as p = 16. */
|
||||
if (pr > 8)
|
||||
pr = 16;
|
||||
|
||||
mr = FIELD_GET(RZG3S_DIV_M, val) + 1;
|
||||
nir = FIELD_GET(RZG3S_DIV_NI, val) + 1;
|
||||
nfr = FIELD_GET(RZG3S_DIV_NF, val);
|
||||
|
||||
rate = mul_u64_u32_shr(parent_rate, 4096 * nir + nfr, 12);
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(rate, (mr * pr));
|
||||
}
|
||||
|
||||
static const struct clk_ops rzg3s_cpg_pll_ops = {
|
||||
.recalc_rate = rzg3s_cpg_pll_clk_recalc_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
|
||||
struct clk **clks,
|
||||
void __iomem *base,
|
||||
struct rzg2l_cpg_priv *priv)
|
||||
struct rzg2l_cpg_priv *priv,
|
||||
const struct clk_ops *ops)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
const struct clk *parent;
|
||||
|
@ -735,7 +1037,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
|
|||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.name = core->name;
|
||||
init.ops = &rzg2l_cpg_pll_ops;
|
||||
init.ops = ops;
|
||||
init.flags = 0;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
@ -830,8 +1132,12 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
|
|||
core->mult, div);
|
||||
break;
|
||||
case CLK_TYPE_SAM_PLL:
|
||||
clk = rzg2l_cpg_pll_clk_register(core, priv->clks,
|
||||
priv->base, priv);
|
||||
clk = rzg2l_cpg_pll_clk_register(core, priv->clks, priv->base, priv,
|
||||
&rzg2l_cpg_pll_ops);
|
||||
break;
|
||||
case CLK_TYPE_G3S_PLL:
|
||||
clk = rzg2l_cpg_pll_clk_register(core, priv->clks, priv->base, priv,
|
||||
&rzg3s_cpg_pll_ops);
|
||||
break;
|
||||
case CLK_TYPE_SIPLL5:
|
||||
clk = rzg2l_cpg_sipll5_register(core, priv->clks, priv);
|
||||
|
@ -840,6 +1146,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
|
|||
clk = rzg2l_cpg_div_clk_register(core, priv->clks,
|
||||
priv->base, priv);
|
||||
break;
|
||||
case CLK_TYPE_G3S_DIV:
|
||||
clk = rzg3s_cpg_div_clk_register(core, priv->clks, priv->base, priv);
|
||||
break;
|
||||
case CLK_TYPE_MUX:
|
||||
clk = rzg2l_cpg_mux_clk_register(core, priv->base, priv);
|
||||
break;
|
||||
|
@ -895,7 +1204,6 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
|
|||
struct rzg2l_cpg_priv *priv = clock->priv;
|
||||
unsigned int reg = clock->off;
|
||||
struct device *dev = priv->dev;
|
||||
unsigned long flags;
|
||||
u32 bitmask = BIT(clock->bit);
|
||||
u32 value;
|
||||
int error;
|
||||
|
@ -905,17 +1213,14 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk,
|
||||
dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk,
|
||||
enable ? "ON" : "OFF");
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
|
||||
value = bitmask << 16;
|
||||
if (enable)
|
||||
value = (bitmask << 16) | bitmask;
|
||||
else
|
||||
value = bitmask << 16;
|
||||
writel(value, priv->base + CLK_ON_R(reg));
|
||||
value |= bitmask;
|
||||
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
writel(value, priv->base + CLK_ON_R(reg));
|
||||
|
||||
if (!enable)
|
||||
return 0;
|
||||
|
@ -1401,6 +1706,12 @@ static const struct of_device_id rzg2l_cpg_match[] = {
|
|||
.data = &r9a07g054_cpg_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_R9A08G045
|
||||
{
|
||||
.compatible = "renesas,r9a08g045-cpg",
|
||||
.data = &r9a08g045_cpg_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_R9A09G011
|
||||
{
|
||||
.compatible = "renesas,r9a09g011-cpg",
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef __RENESAS_RZG2L_CPG_H__
|
||||
#define __RENESAS_RZG2L_CPG_H__
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define CPG_SIPLL5_STBY (0x140)
|
||||
#define CPG_SIPLL5_CLK1 (0x144)
|
||||
#define CPG_SIPLL5_CLK3 (0x14C)
|
||||
|
@ -19,7 +21,6 @@
|
|||
#define CPG_PL2_DDIV (0x204)
|
||||
#define CPG_PL3A_DDIV (0x208)
|
||||
#define CPG_PL6_DDIV (0x210)
|
||||
#define CPG_PL2SDHI_DSEL (0x218)
|
||||
#define CPG_CLKSTATUS (0x280)
|
||||
#define CPG_PL3_SSEL (0x408)
|
||||
#define CPG_PL6_SSEL (0x414)
|
||||
|
@ -43,8 +44,6 @@
|
|||
#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)
|
||||
#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29)
|
||||
|
||||
#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000
|
||||
|
||||
/* n = 0/1/2 for PLL1/4/6 */
|
||||
#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
|
||||
#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
|
||||
|
@ -69,9 +68,6 @@
|
|||
#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
|
||||
#define SEL_GPU2 SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)
|
||||
|
||||
#define SEL_SDHI0 DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||||
#define SEL_SDHI1 DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||||
|
||||
#define EXTAL_FREQ_IN_MEGA_HZ (24)
|
||||
|
||||
/**
|
||||
|
@ -90,10 +86,15 @@ struct cpg_core_clk {
|
|||
unsigned int mult;
|
||||
unsigned int type;
|
||||
unsigned int conf;
|
||||
unsigned int sconf;
|
||||
const struct clk_div_table *dtable;
|
||||
const u32 *mtable;
|
||||
const unsigned long invalid_rate;
|
||||
const unsigned long max_rate;
|
||||
const char * const *parent_names;
|
||||
int flag;
|
||||
int mux_flags;
|
||||
notifier_fn_t notifier;
|
||||
u32 flag;
|
||||
u32 mux_flags;
|
||||
int num_parents;
|
||||
};
|
||||
|
||||
|
@ -102,9 +103,11 @@ enum clk_types {
|
|||
CLK_TYPE_IN, /* External Clock Input */
|
||||
CLK_TYPE_FF, /* Fixed Factor Clock */
|
||||
CLK_TYPE_SAM_PLL,
|
||||
CLK_TYPE_G3S_PLL,
|
||||
|
||||
/* Clock with divider */
|
||||
CLK_TYPE_DIV,
|
||||
CLK_TYPE_G3S_DIV,
|
||||
|
||||
/* Clock with clock source selector */
|
||||
CLK_TYPE_MUX,
|
||||
|
@ -129,6 +132,8 @@ enum clk_types {
|
|||
DEF_TYPE(_name, _id, _type, .parent = _parent)
|
||||
#define DEF_SAMPLL(_name, _id, _parent, _conf) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
|
||||
#define DEF_G3S_PLL(_name, _id, _parent, _conf) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf)
|
||||
#define DEF_INPUT(_name, _id) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_IN)
|
||||
#define DEF_FIXED(_name, _id, _parent, _mult, _div) \
|
||||
|
@ -141,6 +146,13 @@ enum clk_types {
|
|||
DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
|
||||
.parent = _parent, .dtable = _dtable, \
|
||||
.flag = CLK_DIVIDER_READ_ONLY)
|
||||
#define DEF_G3S_DIV(_name, _id, _parent, _conf, _sconf, _dtable, _invalid_rate, \
|
||||
_max_rate, _clk_flags, _notif) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_G3S_DIV, .conf = _conf, .sconf = _sconf, \
|
||||
.parent = _parent, .dtable = _dtable, \
|
||||
.invalid_rate = _invalid_rate, \
|
||||
.max_rate = _max_rate, .flag = (_clk_flags), \
|
||||
.notifier = _notif)
|
||||
#define DEF_MUX(_name, _id, _conf, _parent_names) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
|
||||
.parent_names = _parent_names, \
|
||||
|
@ -151,10 +163,11 @@ enum clk_types {
|
|||
.parent_names = _parent_names, \
|
||||
.num_parents = ARRAY_SIZE(_parent_names), \
|
||||
.mux_flags = CLK_MUX_READ_ONLY)
|
||||
#define DEF_SD_MUX(_name, _id, _conf, _parent_names) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \
|
||||
#define DEF_SD_MUX(_name, _id, _conf, _sconf, _parent_names, _mtable, _clk_flags, _notifier) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, .sconf = _sconf, \
|
||||
.parent_names = _parent_names, \
|
||||
.num_parents = ARRAY_SIZE(_parent_names))
|
||||
.num_parents = ARRAY_SIZE(_parent_names), \
|
||||
.mtable = _mtable, .flag = _clk_flags, .notifier = _notifier)
|
||||
#define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent)
|
||||
#define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \
|
||||
|
@ -271,6 +284,10 @@ struct rzg2l_cpg_info {
|
|||
extern const struct rzg2l_cpg_info r9a07g043_cpg_info;
|
||||
extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
|
||||
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
|
||||
extern const struct rzg2l_cpg_info r9a08g045_cpg_info;
|
||||
extern const struct rzg2l_cpg_info r9a09g011_cpg_info;
|
||||
|
||||
int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event, void *data);
|
||||
int rzg3s_cpg_div_clk_notifier(struct notifier_block *nb, unsigned long event, void *data);
|
||||
|
||||
#endif
|
||||
|
|
242
include/dt-bindings/clock/r9a08g045-cpg.h
Normal file
242
include/dt-bindings/clock/r9a08g045-cpg.h
Normal file
|
@ -0,0 +1,242 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
*
|
||||
* Copyright (C) 2023 Renesas Electronics Corp.
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_CLOCK_R9A08G045_CPG_H__
|
||||
#define __DT_BINDINGS_CLOCK_R9A08G045_CPG_H__
|
||||
|
||||
#include <dt-bindings/clock/renesas-cpg-mssr.h>
|
||||
|
||||
/* R9A08G045 CPG Core Clocks */
|
||||
#define R9A08G045_CLK_I 0
|
||||
#define R9A08G045_CLK_I2 1
|
||||
#define R9A08G045_CLK_I3 2
|
||||
#define R9A08G045_CLK_S0 3
|
||||
#define R9A08G045_CLK_SPI0 4
|
||||
#define R9A08G045_CLK_SPI1 5
|
||||
#define R9A08G045_CLK_SD0 6
|
||||
#define R9A08G045_CLK_SD1 7
|
||||
#define R9A08G045_CLK_SD2 8
|
||||
#define R9A08G045_CLK_M0 9
|
||||
#define R9A08G045_CLK_HP 10
|
||||
#define R9A08G045_CLK_TSU 11
|
||||
#define R9A08G045_CLK_ZT 12
|
||||
#define R9A08G045_CLK_P0 13
|
||||
#define R9A08G045_CLK_P1 14
|
||||
#define R9A08G045_CLK_P2 15
|
||||
#define R9A08G045_CLK_P3 16
|
||||
#define R9A08G045_CLK_P4 17
|
||||
#define R9A08G045_CLK_P5 18
|
||||
#define R9A08G045_CLK_AT 19
|
||||
#define R9A08G045_CLK_OC0 20
|
||||
#define R9A08G045_CLK_OC1 21
|
||||
#define R9A08G045_OSCCLK 22
|
||||
#define R9A08G045_OSCCLK2 23
|
||||
#define R9A08G045_SWD 24
|
||||
|
||||
/* R9A08G045 Module Clocks */
|
||||
#define R9A08G045_OCTA_ACLK 0
|
||||
#define R9A08G045_OCTA_MCLK 1
|
||||
#define R9A08G045_CA55_SCLK 2
|
||||
#define R9A08G045_CA55_PCLK 3
|
||||
#define R9A08G045_CA55_ATCLK 4
|
||||
#define R9A08G045_CA55_GICCLK 5
|
||||
#define R9A08G045_CA55_PERICLK 6
|
||||
#define R9A08G045_CA55_ACLK 7
|
||||
#define R9A08G045_CA55_TSCLK 8
|
||||
#define R9A08G045_SRAM_ACPU_ACLK0 9
|
||||
#define R9A08G045_SRAM_ACPU_ACLK1 10
|
||||
#define R9A08G045_SRAM_ACPU_ACLK2 11
|
||||
#define R9A08G045_GIC600_GICCLK 12
|
||||
#define R9A08G045_IA55_CLK 13
|
||||
#define R9A08G045_IA55_PCLK 14
|
||||
#define R9A08G045_MHU_PCLK 15
|
||||
#define R9A08G045_SYC_CNT_CLK 16
|
||||
#define R9A08G045_DMAC_ACLK 17
|
||||
#define R9A08G045_DMAC_PCLK 18
|
||||
#define R9A08G045_OSTM0_PCLK 19
|
||||
#define R9A08G045_OSTM1_PCLK 20
|
||||
#define R9A08G045_OSTM2_PCLK 21
|
||||
#define R9A08G045_OSTM3_PCLK 22
|
||||
#define R9A08G045_OSTM4_PCLK 23
|
||||
#define R9A08G045_OSTM5_PCLK 24
|
||||
#define R9A08G045_OSTM6_PCLK 25
|
||||
#define R9A08G045_OSTM7_PCLK 26
|
||||
#define R9A08G045_MTU_X_MCK_MTU3 27
|
||||
#define R9A08G045_POE3_CLKM_POE 28
|
||||
#define R9A08G045_GPT_PCLK 29
|
||||
#define R9A08G045_POEG_A_CLKP 30
|
||||
#define R9A08G045_POEG_B_CLKP 31
|
||||
#define R9A08G045_POEG_C_CLKP 32
|
||||
#define R9A08G045_POEG_D_CLKP 33
|
||||
#define R9A08G045_WDT0_PCLK 34
|
||||
#define R9A08G045_WDT0_CLK 35
|
||||
#define R9A08G045_WDT1_PCLK 36
|
||||
#define R9A08G045_WDT1_CLK 37
|
||||
#define R9A08G045_WDT2_PCLK 38
|
||||
#define R9A08G045_WDT2_CLK 39
|
||||
#define R9A08G045_SPI_HCLK 40
|
||||
#define R9A08G045_SPI_ACLK 41
|
||||
#define R9A08G045_SPI_CLK 42
|
||||
#define R9A08G045_SPI_CLKX2 43
|
||||
#define R9A08G045_SDHI0_IMCLK 44
|
||||
#define R9A08G045_SDHI0_IMCLK2 45
|
||||
#define R9A08G045_SDHI0_CLK_HS 46
|
||||
#define R9A08G045_SDHI0_ACLK 47
|
||||
#define R9A08G045_SDHI1_IMCLK 48
|
||||
#define R9A08G045_SDHI1_IMCLK2 49
|
||||
#define R9A08G045_SDHI1_CLK_HS 50
|
||||
#define R9A08G045_SDHI1_ACLK 51
|
||||
#define R9A08G045_SDHI2_IMCLK 52
|
||||
#define R9A08G045_SDHI2_IMCLK2 53
|
||||
#define R9A08G045_SDHI2_CLK_HS 54
|
||||
#define R9A08G045_SDHI2_ACLK 55
|
||||
#define R9A08G045_SSI0_PCLK2 56
|
||||
#define R9A08G045_SSI0_PCLK_SFR 57
|
||||
#define R9A08G045_SSI1_PCLK2 58
|
||||
#define R9A08G045_SSI1_PCLK_SFR 59
|
||||
#define R9A08G045_SSI2_PCLK2 60
|
||||
#define R9A08G045_SSI2_PCLK_SFR 61
|
||||
#define R9A08G045_SSI3_PCLK2 62
|
||||
#define R9A08G045_SSI3_PCLK_SFR 63
|
||||
#define R9A08G045_SRC_CLKP 64
|
||||
#define R9A08G045_USB_U2H0_HCLK 65
|
||||
#define R9A08G045_USB_U2H1_HCLK 66
|
||||
#define R9A08G045_USB_U2P_EXR_CPUCLK 67
|
||||
#define R9A08G045_USB_PCLK 68
|
||||
#define R9A08G045_ETH0_CLK_AXI 69
|
||||
#define R9A08G045_ETH0_CLK_CHI 70
|
||||
#define R9A08G045_ETH0_REFCLK 71
|
||||
#define R9A08G045_ETH1_CLK_AXI 72
|
||||
#define R9A08G045_ETH1_CLK_CHI 73
|
||||
#define R9A08G045_ETH1_REFCLK 74
|
||||
#define R9A08G045_I2C0_PCLK 75
|
||||
#define R9A08G045_I2C1_PCLK 76
|
||||
#define R9A08G045_I2C2_PCLK 77
|
||||
#define R9A08G045_I2C3_PCLK 78
|
||||
#define R9A08G045_SCIF0_CLK_PCK 79
|
||||
#define R9A08G045_SCIF1_CLK_PCK 80
|
||||
#define R9A08G045_SCIF2_CLK_PCK 81
|
||||
#define R9A08G045_SCIF3_CLK_PCK 82
|
||||
#define R9A08G045_SCIF4_CLK_PCK 83
|
||||
#define R9A08G045_SCIF5_CLK_PCK 84
|
||||
#define R9A08G045_SCI0_CLKP 85
|
||||
#define R9A08G045_SCI1_CLKP 86
|
||||
#define R9A08G045_IRDA_CLKP 87
|
||||
#define R9A08G045_RSPI0_CLKB 88
|
||||
#define R9A08G045_RSPI1_CLKB 89
|
||||
#define R9A08G045_RSPI2_CLKB 90
|
||||
#define R9A08G045_RSPI3_CLKB 91
|
||||
#define R9A08G045_RSPI4_CLKB 92
|
||||
#define R9A08G045_CANFD_PCLK 93
|
||||
#define R9A08G045_CANFD_CLK_RAM 94
|
||||
#define R9A08G045_GPIO_HCLK 95
|
||||
#define R9A08G045_ADC_ADCLK 96
|
||||
#define R9A08G045_ADC_PCLK 97
|
||||
#define R9A08G045_TSU_PCLK 98
|
||||
#define R9A08G045_PDM_PCLK 99
|
||||
#define R9A08G045_PDM_CCLK 100
|
||||
#define R9A08G045_PCI_ACLK 101
|
||||
#define R9A08G045_PCI_CLKL1PM 102
|
||||
#define R9A08G045_SPDIF_PCLK 103
|
||||
#define R9A08G045_I3C_PCLK 104
|
||||
#define R9A08G045_I3C_TCLK 105
|
||||
#define R9A08G045_VBAT_BCLK 106
|
||||
|
||||
/* R9A08G045 Resets */
|
||||
#define R9A08G045_CA55_RST_1_0 0
|
||||
#define R9A08G045_CA55_RST_3_0 1
|
||||
#define R9A08G045_CA55_RST_4 2
|
||||
#define R9A08G045_CA55_RST_5 3
|
||||
#define R9A08G045_CA55_RST_6 4
|
||||
#define R9A08G045_CA55_RST_7 5
|
||||
#define R9A08G045_CA55_RST_8 6
|
||||
#define R9A08G045_CA55_RST_9 7
|
||||
#define R9A08G045_CA55_RST_10 8
|
||||
#define R9A08G045_CA55_RST_11 9
|
||||
#define R9A08G045_CA55_RST_12 10
|
||||
#define R9A08G045_SRAM_ACPU_ARESETN0 11
|
||||
#define R9A08G045_SRAM_ACPU_ARESETN1 12
|
||||
#define R9A08G045_SRAM_ACPU_ARESETN2 13
|
||||
#define R9A08G045_GIC600_GICRESET_N 14
|
||||
#define R9A08G045_GIC600_DBG_GICRESET_N 15
|
||||
#define R9A08G045_IA55_RESETN 16
|
||||
#define R9A08G045_MHU_RESETN 17
|
||||
#define R9A08G045_DMAC_ARESETN 18
|
||||
#define R9A08G045_DMAC_RST_ASYNC 19
|
||||
#define R9A08G045_SYC_RESETN 20
|
||||
#define R9A08G045_OSTM0_PRESETZ 21
|
||||
#define R9A08G045_OSTM1_PRESETZ 22
|
||||
#define R9A08G045_OSTM2_PRESETZ 23
|
||||
#define R9A08G045_OSTM3_PRESETZ 24
|
||||
#define R9A08G045_OSTM4_PRESETZ 25
|
||||
#define R9A08G045_OSTM5_PRESETZ 26
|
||||
#define R9A08G045_OSTM6_PRESETZ 27
|
||||
#define R9A08G045_OSTM7_PRESETZ 28
|
||||
#define R9A08G045_MTU_X_PRESET_MTU3 29
|
||||
#define R9A08G045_POE3_RST_M_REG 30
|
||||
#define R9A08G045_GPT_RST_C 31
|
||||
#define R9A08G045_POEG_A_RST 32
|
||||
#define R9A08G045_POEG_B_RST 33
|
||||
#define R9A08G045_POEG_C_RST 34
|
||||
#define R9A08G045_POEG_D_RST 35
|
||||
#define R9A08G045_WDT0_PRESETN 36
|
||||
#define R9A08G045_WDT1_PRESETN 37
|
||||
#define R9A08G045_WDT2_PRESETN 38
|
||||
#define R9A08G045_SPI_HRESETN 39
|
||||
#define R9A08G045_SPI_ARESETN 40
|
||||
#define R9A08G045_SDHI0_IXRST 41
|
||||
#define R9A08G045_SDHI1_IXRST 42
|
||||
#define R9A08G045_SDHI2_IXRST 43
|
||||
#define R9A08G045_SSI0_RST_M2_REG 44
|
||||
#define R9A08G045_SSI1_RST_M2_REG 45
|
||||
#define R9A08G045_SSI2_RST_M2_REG 46
|
||||
#define R9A08G045_SSI3_RST_M2_REG 47
|
||||
#define R9A08G045_SRC_RST 48
|
||||
#define R9A08G045_USB_U2H0_HRESETN 49
|
||||
#define R9A08G045_USB_U2H1_HRESETN 50
|
||||
#define R9A08G045_USB_U2P_EXL_SYSRST 51
|
||||
#define R9A08G045_USB_PRESETN 52
|
||||
#define R9A08G045_ETH0_RST_HW_N 53
|
||||
#define R9A08G045_ETH1_RST_HW_N 54
|
||||
#define R9A08G045_I2C0_MRST 55
|
||||
#define R9A08G045_I2C1_MRST 56
|
||||
#define R9A08G045_I2C2_MRST 57
|
||||
#define R9A08G045_I2C3_MRST 58
|
||||
#define R9A08G045_SCIF0_RST_SYSTEM_N 59
|
||||
#define R9A08G045_SCIF1_RST_SYSTEM_N 60
|
||||
#define R9A08G045_SCIF2_RST_SYSTEM_N 61
|
||||
#define R9A08G045_SCIF3_RST_SYSTEM_N 62
|
||||
#define R9A08G045_SCIF4_RST_SYSTEM_N 63
|
||||
#define R9A08G045_SCIF5_RST_SYSTEM_N 64
|
||||
#define R9A08G045_SCI0_RST 65
|
||||
#define R9A08G045_SCI1_RST 66
|
||||
#define R9A08G045_IRDA_RST 67
|
||||
#define R9A08G045_RSPI0_RST 68
|
||||
#define R9A08G045_RSPI1_RST 69
|
||||
#define R9A08G045_RSPI2_RST 70
|
||||
#define R9A08G045_RSPI3_RST 71
|
||||
#define R9A08G045_RSPI4_RST 72
|
||||
#define R9A08G045_CANFD_RSTP_N 73
|
||||
#define R9A08G045_CANFD_RSTC_N 74
|
||||
#define R9A08G045_GPIO_RSTN 75
|
||||
#define R9A08G045_GPIO_PORT_RESETN 76
|
||||
#define R9A08G045_GPIO_SPARE_RESETN 77
|
||||
#define R9A08G045_ADC_PRESETN 78
|
||||
#define R9A08G045_ADC_ADRST_N 79
|
||||
#define R9A08G045_TSU_PRESETN 80
|
||||
#define R9A08G045_OCTA_ARESETN 81
|
||||
#define R9A08G045_PDM0_PRESETNT 82
|
||||
#define R9A08G045_PCI_ARESETN 83
|
||||
#define R9A08G045_PCI_RST_B 84
|
||||
#define R9A08G045_PCI_RST_GP_B 85
|
||||
#define R9A08G045_PCI_RST_PS_B 86
|
||||
#define R9A08G045_PCI_RST_RSM_B 87
|
||||
#define R9A08G045_PCI_RST_CFG_B 88
|
||||
#define R9A08G045_PCI_RST_LOAD_B 89
|
||||
#define R9A08G045_SPDIF_RST 90
|
||||
#define R9A08G045_I3C_TRESETN 91
|
||||
#define R9A08G045_I3C_PRESETN 92
|
||||
#define R9A08G045_VBAT_BRESETN 93
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_R9A08G045_CPG_H__ */
|
Loading…
Reference in a new issue