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:
Stephen Boyd 2023-10-30 14:12:20 -07:00
28 changed files with 1313 additions and 183 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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__);

View file

@ -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--;

View 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");

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,
};

View file

@ -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,

View file

@ -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];

View file

@ -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,
};

View file

@ -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,

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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),

View file

@ -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);

View file

@ -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),
};

View file

@ -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),

View 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,
};

View file

@ -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,

View file

@ -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 2b01 (533 MHz)
* to 2b10 (400 MHz) or vice versa, Switch to 2b11 (266 MHz) first,
* and then switch to the target setting (2b01 (533 MHz) or 2b10
* (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 2b01 (533 MHz)
* to 2b10 (400 MHz) or vice versa, Switch to 2b11 (266 MHz) first,
* and then switch to the target setting (2b01 (533 MHz) or 2b10
* (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",

View file

@ -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

View 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__ */