* [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
@ 2023-11-22 14:28 Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 01/11] dt-bindings: clock: Add Renesas versa3 clock generator bindings Biju Das
` (12 more replies)
0 siblings, 13 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
This patch series aims to add versa3 clk generator support on
RZ/G2{L,LC,UL}/RZ/Five SMARC EVKs.
All the patches are cherry-picked from the mainline.
Biju Das (7):
dt-bindings: clock: Add Renesas versa3 clock generator bindings
dt-bindings: clock: versaclock3: Add description for #clock-cells
property
clk: Add support for versa3 clock driver
clk: vc3: Fix 64 by 64 division
clk: vc3: Fix output clock mapping
clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum
arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk
Daniel Palmer (1):
clk: fixed: add devm helper for clk_hw_register_fixed_factor()
Marek Vasut (1):
clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index()
Marijn Suijten (1):
clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
Samuel Holland (1):
clk: fixed: Remove Allwinner A10 special-case logic
.../bindings/clock/renesas,5p35023.yaml | 89 ++
.../boot/dts/renesas/rz-smarc-common.dtsi | 14 +-
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 20 +
arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi | 20 +
arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi | 24 +
drivers/clk/Kconfig | 9 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-fixed-factor.c | 111 +-
drivers/clk/clk-versaclock3.c | 1140 +++++++++++++++++
include/linux/clk-provider.h | 13 +
10 files changed, 1416 insertions(+), 25 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
create mode 100644 drivers/clk/clk-versaclock3.c
--
2.25.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 01/11] dt-bindings: clock: Add Renesas versa3 clock generator bindings
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 02/11] dt-bindings: clock: versaclock3: Add description for #clock-cells property Biju Das
` (11 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit a03d23f860eb438c7da88f934448e6caa0f92851 upstream.
Document Renesas versa3 clock generator(5P35023) bindings.
The 5P35023 is a VersaClock programmable clock generator and
is designed for low-power, consumer, and high-performance PCI
Express applications. The 5P35023 device is a three PLL
architecture design, and each PLL is individually programmable
and allowing for up to 6 unique frequency outputs.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20230705171000.85786-2-biju.das.jz@bp.renesas.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
.../bindings/clock/renesas,5p35023.yaml | 86 +++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
diff --git a/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml b/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
new file mode 100644
index 000000000000..839648e753d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/renesas,5p35023.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas 5p35023 VersaClock 3 programmable I2C clock generator
+
+maintainers:
+ - Biju Das <biju.das.jz@bp.renesas.com>
+
+description: |
+ The 5P35023 is a VersaClock programmable clock generator and
+ is designed for low-power, consumer, and high-performance PCI
+ express applications. The 5P35023 device is a three PLL
+ architecture design, and each PLL is individually programmable
+ and allowing for up to 6 unique frequency outputs.
+
+ An internal OTP memory allows the user to store the configuration
+ in the device. After power up, the user can change the device register
+ settings through the I2C interface when I2C mode is selected.
+
+ The driver can read a full register map from the DT, and will use that
+ register map to initialize the attached part (via I2C) when the system
+ boots. Any configuration not supported by the common clock framework
+ must be done via the full register map, including optimized settings.
+
+ Link to datasheet:
+ https://www.renesas.com/us/en/products/clocks-timing/clock-generation/programmable-clocks/5p35023-versaclock-3s-programmable-clock-generator
+
+properties:
+ compatible:
+ enum:
+ - renesas,5p35023
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ maxItems: 1
+
+ renesas,settings:
+ description: Optional, complete register map of the device.
+ Optimized settings for the device must be provided in full
+ and are written during initialization.
+ $ref: /schemas/types.yaml#/definitions/uint8-array
+ maxItems: 37
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+
+ clocks = <&x1_x2>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <12288000>, <25000000>,
+ <12000000>, <11289600>,
+ <11289600>, <24000000>;
+ };
+ };
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 02/11] dt-bindings: clock: versaclock3: Add description for #clock-cells property
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 01/11] dt-bindings: clock: Add Renesas versa3 clock generator bindings Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 03/11] clk: fixed: add devm helper for clk_hw_register_fixed_factor() Biju Das
` (10 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit 1aa2a9f27627447da247997c34c71af9402fa237 upstream.
Add description for "#clock-cells" property to map indexes to the clock
output in the Table 3. ("Output Source") in the 5P35023 datasheet
(ie: {REF,SE1,SE2,SE3,DIFF1,DIFF2}. Also update the "assigned-clock-rates"
in the example.
While at it, replace clocks phandle in the example from x1_x2->x1 as
X2 is a different 32768 kHz crystal.
Suggested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20230824104812.147775-2-biju.das.jz@bp.renesas.com
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
.../devicetree/bindings/clock/renesas,5p35023.yaml | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml b/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
index 839648e753d4..42b6f80613f3 100644
--- a/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
@@ -37,6 +37,9 @@ properties:
maxItems: 1
'#clock-cells':
+ description:
+ The index in the assigned-clocks is mapped to the output clock as below
+ 0 - REF, 1 - SE1, 2 - SE2, 3 - SE3, 4 - DIFF1, 5 - DIFF2.
const: 1
clocks:
@@ -68,7 +71,7 @@ examples:
reg = <0x68>;
#clock-cells = <1>;
- clocks = <&x1_x2>;
+ clocks = <&x1>;
renesas,settings = [
80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
@@ -79,8 +82,8 @@ examples:
assigned-clocks = <&versa3 0>, <&versa3 1>,
<&versa3 2>, <&versa3 3>,
<&versa3 4>, <&versa3 5>;
- assigned-clock-rates = <12288000>, <25000000>,
- <12000000>, <11289600>,
- <11289600>, <24000000>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
};
};
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 03/11] clk: fixed: add devm helper for clk_hw_register_fixed_factor()
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 01/11] dt-bindings: clock: Add Renesas versa3 clock generator bindings Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 02/11] dt-bindings: clock: versaclock3: Add description for #clock-cells property Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 04/11] clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index() Biju Das
` (9 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
From: Daniel Palmer <daniel@0x0f.com>
commit 0b9266d295cee170509539635b8d572abe5267af upstream.
Add a devm helper for clk_hw_register_fixed_factor() so that drivers that internally
register fixed factor clocks for things like dividers don't need to manually unregister
them on remove or if probe fails.
Signed-off-by: Daniel Palmer <daniel@0x0f.com>
Link: https://lore.kernel.org/r/20210211052206.2955988-4-daniel@0x0f.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-fixed-factor.c | 39 ++++++++++++++++++++++++++++------
include/linux/clk-provider.h | 4 +++-
2 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 910e6e74ae90..4f7bf3929d6d 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -64,10 +64,16 @@ const struct clk_ops clk_fixed_factor_ops = {
};
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
+static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
+{
+ clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw);
+}
+
static struct clk_hw *
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
const char *name, const char *parent_name, int index,
- unsigned long flags, unsigned int mult, unsigned int div)
+ unsigned long flags, unsigned int mult, unsigned int div,
+ bool devm)
{
struct clk_fixed_factor *fix;
struct clk_init_data init = { };
@@ -75,7 +81,15 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
struct clk_hw *hw;
int ret;
- fix = kmalloc(sizeof(*fix), GFP_KERNEL);
+ /* You can't use devm without a dev */
+ if (devm && !dev)
+ return ERR_PTR(-EINVAL);
+
+ if (devm)
+ fix = devres_alloc(devm_clk_hw_register_fixed_factor_release,
+ sizeof(*fix), GFP_KERNEL);
+ else
+ fix = kmalloc(sizeof(*fix), GFP_KERNEL);
if (!fix)
return ERR_PTR(-ENOMEM);
@@ -99,9 +113,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
else
ret = of_clk_hw_register(np, hw);
if (ret) {
- kfree(fix);
+ if (devm)
+ devres_free(fix);
+ else
+ kfree(fix);
hw = ERR_PTR(ret);
- }
+ } else if (devm)
+ devres_add(dev, fix);
return hw;
}
@@ -111,7 +129,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
unsigned int mult, unsigned int div)
{
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
- flags, mult, div);
+ flags, mult, div, false);
}
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
@@ -153,6 +171,15 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
}
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
+struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
+ const char *name, const char *parent_name, unsigned long flags,
+ unsigned int mult, unsigned int div)
+{
+ return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
+ flags, mult, div, true);
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
+
#ifdef CONFIG_OF
static const struct of_device_id set_rate_parent_matches[] = {
{ .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
@@ -185,7 +212,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
flags |= CLK_SET_RATE_PARENT;
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
- flags, mult, div);
+ flags, mult, div, false);
if (IS_ERR(hw)) {
/*
* Clear OF_POPULATED flag so that clock registration can be
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 311d343d2358..59dc4d73b6a3 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -954,7 +954,9 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
-
+struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
+ const char *name, const char *parent_name, unsigned long flags,
+ unsigned int mult, unsigned int div);
/**
* struct clk_fractional_divider - adjustable fractional divider clock
*
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 04/11] clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index()
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (2 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 03/11] clk: fixed: add devm helper for clk_hw_register_fixed_factor() Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic Biju Das
` (8 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
From: Marek Vasut <marex@denx.de>
commit 0c125f87a84097c182c481be7497af9f816e5db5 upstream.
Add an API for a fixed factor clk that uses an index for the parent
instead of a string name. This allows us to move drivers away from the
string based method of describing parents and use the DT/firmware based
method instead.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Link: https://lore.kernel.org/r/20220226040723.143705-2-marex@denx.de
[sboyd@kernel.org: Expose a new API instead of internal function]
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-fixed-factor.c | 22 ++++++++++++++++++++++
include/linux/clk-provider.h | 3 +++
2 files changed, 25 insertions(+)
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 4f7bf3929d6d..b65f027dd40c 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -124,6 +124,28 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
return hw;
}
+/**
+ * devm_clk_hw_register_fixed_factor_index - Register a fixed factor clock with
+ * parent from DT index
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @index: index of phandle in @dev 'clocks' property
+ * @flags: fixed factor flags
+ * @mult: multiplier
+ * @div: divider
+ *
+ * Return: Pointer to fixed factor clk_hw structure that was registered or
+ * an error pointer.
+ */
+struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
+ const char *name, unsigned int index, unsigned long flags,
+ unsigned int mult, unsigned int div)
+{
+ return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, index,
+ flags, mult, div, true);
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
+
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 59dc4d73b6a3..0b0055359bbb 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -957,6 +957,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div);
+struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
+ const char *name, unsigned int index, unsigned long flags,
+ unsigned int mult, unsigned int div);
/**
* struct clk_fractional_divider - adjustable fractional divider clock
*
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (3 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 04/11] clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index() Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 21:04 ` Pavel Machek
2023-11-22 14:28 ` [PATCH 5.10.y-cip 06/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw() Biju Das
` (7 subsequent siblings)
12 siblings, 1 reply; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
From: Samuel Holland <samuel@sholland.org>
commit c33ed61249dc54e7cf2137c04462883560375b77 upstream.
This compatible is part of the legacy sunxi clock support, and has not
been used since commit 6b48644b1d29 ("ARM: gr8: Convert to CCU") in
October 2016. Since supporting this compatible adds some overhead to
generic clock code, let's clean it up.
Signed-off-by: Samuel Holland <samuel@sholland.org>
Link: https://lore.kernel.org/r/20220531051742.43273-1-samuel@sholland.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-fixed-factor.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index b65f027dd40c..67229bfec4c0 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -203,16 +203,10 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
#ifdef CONFIG_OF
-static const struct of_device_id set_rate_parent_matches[] = {
- { .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
- { /* Sentinel */ },
-};
-
static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
{
struct clk_hw *hw;
const char *clk_name = node->name;
- unsigned long flags = 0;
u32 div, mult;
int ret;
@@ -230,11 +224,8 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
of_property_read_string(node, "clock-output-names", &clk_name);
- if (of_match_node(set_rate_parent_matches, node))
- flags |= CLK_SET_RATE_PARENT;
-
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
- flags, mult, div, false);
+ 0, mult, div, false);
if (IS_ERR(hw)) {
/*
* Clear OF_POPULATED flag so that clock registration can be
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 06/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (4 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver Biju Das
` (6 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
From: Marijn Suijten <marijn.suijten@somainline.org>
commit 6ebd5247ad2aa210b3ff4481c6ed8aa32a032b12 upstream.
Add the devres and non-devres variant of
clk_hw_register_fixed_factor_parent_hw() for registering a fixed factor
clock with clk_hw parent pointer instead of parent name.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Link: https://lore.kernel.org/r/20220629225331.357308-4-marijn.suijten@somainline.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-fixed-factor.c | 45 ++++++++++++++++++++++++++++++----
include/linux/clk-provider.h | 8 ++++++
2 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 67229bfec4c0..bf55b9b71c6a 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -71,7 +71,8 @@ static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *
static struct clk_hw *
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
- const char *name, const char *parent_name, int index,
+ const char *name, const char *parent_name,
+ const struct clk_hw *parent_hw, int index,
unsigned long flags, unsigned int mult, unsigned int div,
bool devm)
{
@@ -103,6 +104,8 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
init.flags = flags;
if (parent_name)
init.parent_names = &parent_name;
+ else if (parent_hw)
+ init.parent_hws = &parent_hw;
else
init.parent_data = &pdata;
init.num_parents = 1;
@@ -141,16 +144,48 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
const char *name, unsigned int index, unsigned long flags,
unsigned int mult, unsigned int div)
{
- return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, index,
+ return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, NULL, index,
flags, mult, div, true);
}
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
+/**
+ * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with
+ * pointer to parent clock
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: fixed factor flags
+ * @mult: multiplier
+ * @div: divider
+ *
+ * Return: Pointer to fixed factor clk_hw structure that was registered or
+ * an error pointer.
+ */
+struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev,
+ const char *name, const struct clk_hw *parent_hw,
+ unsigned long flags, unsigned int mult, unsigned int div)
+{
+ return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw,
+ -1, flags, mult, div, true);
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw);
+
+struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,
+ const char *name, const struct clk_hw *parent_hw,
+ unsigned long flags, unsigned int mult, unsigned int div)
+{
+ return __clk_hw_register_fixed_factor(dev, NULL, name, NULL,
+ parent_hw, -1, flags, mult, div,
+ false);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw);
+
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)
{
- return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
+ return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
flags, mult, div, false);
}
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
@@ -197,7 +232,7 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned int mult, unsigned int div)
{
- return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
+ return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL, -1,
flags, mult, div, true);
}
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
@@ -224,7 +259,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
of_property_read_string(node, "clock-output-names", &clk_name);
- hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
+ hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, NULL, 0,
0, mult, div, false);
if (IS_ERR(hw)) {
/*
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 0b0055359bbb..c002f80e885a 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -960,6 +960,14 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
const char *name, unsigned int index, unsigned long flags,
unsigned int mult, unsigned int div);
+
+struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev,
+ const char *name, const struct clk_hw *parent_hw,
+ unsigned long flags, unsigned int mult, unsigned int div);
+
+struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,
+ const char *name, const struct clk_hw *parent_hw,
+ unsigned long flags, unsigned int mult, unsigned int div);
/**
* struct clk_fractional_divider - adjustable fractional divider clock
*
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (5 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 06/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw() Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 21:07 ` Pavel Machek
2023-11-22 14:28 ` [PATCH 5.10.y-cip 08/11] clk: vc3: Fix 64 by 64 division Biju Das
` (5 subsequent siblings)
12 siblings, 1 reply; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit 6e9aff555db7b6816076121ac3feebc3006de9ad upstream.
Add support for Renesas versa3 clock driver(5p35023).
The clock generator provides 6 output clocks.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230705171000.85786-3-biju.das.jz@bp.renesas.com
[sboyd@kernel.org: Add newline to printk]
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
[biju: Dropped clk_hw_determine_rate_no_reparent() as support
is not available in 5.10]
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/Kconfig | 9 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-versaclock3.c | 1141 +++++++++++++++++++++++++++++++++
3 files changed, 1151 insertions(+)
create mode 100644 drivers/clk/clk-versaclock3.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index df739665f206..d485010ee11d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -311,6 +311,15 @@ config COMMON_CLK_OXNAS
help
Support for the OXNAS SoC Family clocks.
+config COMMON_CLK_VC3
+ tristate "Clock driver for Renesas VersaClock 3 devices"
+ depends on I2C
+ depends on OF
+ select REGMAP_I2C
+ help
+ This driver supports the Renesas VersaClock 3 programmable clock
+ generators.
+
config COMMON_CLK_VC5
tristate "Clock driver for IDT VersaClock 5,6 devices"
depends on I2C
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index da8fcf147eb1..b3bb196bb117 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
+obj-$(CONFIG_COMMON_CLK_VC3) += clk-versaclock3.o
obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c
new file mode 100644
index 000000000000..ca0921510a70
--- /dev/null
+++ b/drivers/clk/clk-versaclock3.c
@@ -0,0 +1,1141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Renesas Versaclock 3
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/i2c.h>
+#include <linux/limits.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#define NUM_CONFIG_REGISTERS 37
+
+#define VC3_GENERAL_CTR 0x0
+#define VC3_GENERAL_CTR_DIV1_SRC_SEL BIT(3)
+#define VC3_GENERAL_CTR_PLL3_REFIN_SEL BIT(2)
+
+#define VC3_PLL3_M_DIVIDER 0x3
+#define VC3_PLL3_M_DIV1 BIT(7)
+#define VC3_PLL3_M_DIV2 BIT(6)
+#define VC3_PLL3_M_DIV(n) ((n) & GENMASK(5, 0))
+
+#define VC3_PLL3_N_DIVIDER 0x4
+#define VC3_PLL3_LOOP_FILTER_N_DIV_MSB 0x5
+
+#define VC3_PLL3_CHARGE_PUMP_CTRL 0x6
+#define VC3_PLL3_CHARGE_PUMP_CTRL_OUTDIV3_SRC_SEL BIT(7)
+
+#define VC3_PLL1_CTRL_OUTDIV5 0x7
+#define VC3_PLL1_CTRL_OUTDIV5_PLL1_MDIV_DOUBLER BIT(7)
+
+#define VC3_PLL1_M_DIVIDER 0x8
+#define VC3_PLL1_M_DIV1 BIT(7)
+#define VC3_PLL1_M_DIV2 BIT(6)
+#define VC3_PLL1_M_DIV(n) ((n) & GENMASK(5, 0))
+
+#define VC3_PLL1_VCO_N_DIVIDER 0x9
+#define VC3_PLL1_LOOP_FILTER_N_DIV_MSB 0x0a
+
+#define VC3_OUT_DIV1_DIV2_CTRL 0xf
+
+#define VC3_PLL2_FB_INT_DIV_MSB 0x10
+#define VC3_PLL2_FB_INT_DIV_LSB 0x11
+#define VC3_PLL2_FB_FRC_DIV_MSB 0x12
+#define VC3_PLL2_FB_FRC_DIV_LSB 0x13
+
+#define VC3_PLL2_M_DIVIDER 0x1a
+#define VC3_PLL2_MDIV_DOUBLER BIT(7)
+#define VC3_PLL2_M_DIV1 BIT(6)
+#define VC3_PLL2_M_DIV2 BIT(5)
+#define VC3_PLL2_M_DIV(n) ((n) & GENMASK(4, 0))
+
+#define VC3_OUT_DIV3_DIV4_CTRL 0x1b
+
+#define VC3_PLL_OP_CTRL 0x1c
+#define VC3_PLL_OP_CTRL_PLL2_REFIN_SEL 6
+
+#define VC3_OUTPUT_CTR 0x1d
+#define VC3_OUTPUT_CTR_DIV4_SRC_SEL BIT(3)
+
+#define VC3_SE2_CTRL_REG0 0x1f
+#define VC3_SE2_CTRL_REG0_SE2_CLK_SEL BIT(6)
+
+#define VC3_SE3_DIFF1_CTRL_REG 0x21
+#define VC3_SE3_DIFF1_CTRL_REG_SE3_CLK_SEL BIT(6)
+
+#define VC3_DIFF1_CTRL_REG 0x22
+#define VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL BIT(7)
+
+#define VC3_DIFF2_CTRL_REG 0x23
+#define VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL BIT(7)
+
+#define VC3_SE1_DIV4_CTRL 0x24
+#define VC3_SE1_DIV4_CTRL_SE1_CLK_SEL BIT(3)
+
+#define VC3_PLL1_VCO_MIN 300000000UL
+#define VC3_PLL1_VCO_MAX 600000000UL
+
+#define VC3_PLL2_VCO_MIN 400000000UL
+#define VC3_PLL2_VCO_MAX 1200000000UL
+
+#define VC3_PLL3_VCO_MIN 300000000UL
+#define VC3_PLL3_VCO_MAX 800000000UL
+
+#define VC3_2_POW_16 (U16_MAX + 1)
+#define VC3_DIV_MASK(width) ((1 << (width)) - 1)
+
+enum vc3_pfd_mux {
+ VC3_PFD2_MUX,
+ VC3_PFD3_MUX,
+};
+
+enum vc3_pfd {
+ VC3_PFD1,
+ VC3_PFD2,
+ VC3_PFD3,
+};
+
+enum vc3_pll {
+ VC3_PLL1,
+ VC3_PLL2,
+ VC3_PLL3,
+};
+
+enum vc3_div_mux {
+ VC3_DIV1_MUX,
+ VC3_DIV3_MUX,
+ VC3_DIV4_MUX,
+};
+
+enum vc3_div {
+ VC3_DIV1,
+ VC3_DIV2,
+ VC3_DIV3,
+ VC3_DIV4,
+ VC3_DIV5,
+};
+
+enum vc3_clk_mux {
+ VC3_DIFF2_MUX,
+ VC3_DIFF1_MUX,
+ VC3_SE3_MUX,
+ VC3_SE2_MUX,
+ VC3_SE1_MUX,
+};
+
+enum vc3_clk {
+ VC3_DIFF2,
+ VC3_DIFF1,
+ VC3_SE3,
+ VC3_SE2,
+ VC3_SE1,
+ VC3_REF,
+};
+
+struct vc3_clk_data {
+ u8 offs;
+ u8 bitmsk;
+};
+
+struct vc3_pfd_data {
+ u8 num;
+ u8 offs;
+ u8 mdiv1_bitmsk;
+ u8 mdiv2_bitmsk;
+};
+
+struct vc3_pll_data {
+ u8 num;
+ u8 int_div_msb_offs;
+ u8 int_div_lsb_offs;
+ unsigned long vco_min;
+ unsigned long vco_max;
+};
+
+struct vc3_div_data {
+ u8 offs;
+ const struct clk_div_table *table;
+ u8 shift;
+ u8 width;
+ u8 flags;
+};
+
+struct vc3_hw_data {
+ struct clk_hw hw;
+ struct regmap *regmap;
+ const void *data;
+
+ u32 div_int;
+ u32 div_frc;
+};
+
+static const struct clk_div_table div1_divs[] = {
+ { .val = 0, .div = 1, }, { .val = 1, .div = 4, },
+ { .val = 2, .div = 5, }, { .val = 3, .div = 6, },
+ { .val = 4, .div = 2, }, { .val = 5, .div = 8, },
+ { .val = 6, .div = 10, }, { .val = 7, .div = 12, },
+ { .val = 8, .div = 4, }, { .val = 9, .div = 16, },
+ { .val = 10, .div = 20, }, { .val = 11, .div = 24, },
+ { .val = 12, .div = 8, }, { .val = 13, .div = 32, },
+ { .val = 14, .div = 40, }, { .val = 15, .div = 48, },
+ {}
+};
+
+static const struct clk_div_table div245_divs[] = {
+ { .val = 0, .div = 1, }, { .val = 1, .div = 3, },
+ { .val = 2, .div = 5, }, { .val = 3, .div = 10, },
+ { .val = 4, .div = 2, }, { .val = 5, .div = 6, },
+ { .val = 6, .div = 10, }, { .val = 7, .div = 20, },
+ { .val = 8, .div = 4, }, { .val = 9, .div = 12, },
+ { .val = 10, .div = 20, }, { .val = 11, .div = 40, },
+ { .val = 12, .div = 5, }, { .val = 13, .div = 15, },
+ { .val = 14, .div = 25, }, { .val = 15, .div = 50, },
+ {}
+};
+
+static const struct clk_div_table div3_divs[] = {
+ { .val = 0, .div = 1, }, { .val = 1, .div = 3, },
+ { .val = 2, .div = 5, }, { .val = 3, .div = 10, },
+ { .val = 4, .div = 2, }, { .val = 5, .div = 6, },
+ { .val = 6, .div = 10, }, { .val = 7, .div = 20, },
+ { .val = 8, .div = 4, }, { .val = 9, .div = 12, },
+ { .val = 10, .div = 20, }, { .val = 11, .div = 40, },
+ { .val = 12, .div = 8, }, { .val = 13, .div = 24, },
+ { .val = 14, .div = 40, }, { .val = 15, .div = 80, },
+ {}
+};
+
+static struct clk_hw *clk_out[6];
+
+static unsigned char vc3_pfd_mux_get_parent(struct clk_hw *hw)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *pfd_mux = vc3->data;
+ u32 src;
+
+ regmap_read(vc3->regmap, pfd_mux->offs, &src);
+
+ return !!(src & pfd_mux->bitmsk);
+}
+
+static int vc3_pfd_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *pfd_mux = vc3->data;
+
+ regmap_update_bits(vc3->regmap, pfd_mux->offs, pfd_mux->bitmsk,
+ index ? pfd_mux->bitmsk : 0);
+ return 0;
+}
+
+static const struct clk_ops vc3_pfd_mux_ops = {
+ .set_parent = vc3_pfd_mux_set_parent,
+ .get_parent = vc3_pfd_mux_get_parent,
+};
+
+static unsigned long vc3_pfd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pfd_data *pfd = vc3->data;
+ unsigned int prediv, premul;
+ unsigned long rate;
+ u8 mdiv;
+
+ regmap_read(vc3->regmap, pfd->offs, &prediv);
+ if (pfd->num == VC3_PFD1) {
+ /* The bypass_prediv is set, PLL fed from Ref_in directly. */
+ if (prediv & pfd->mdiv1_bitmsk) {
+ /* check doubler is set or not */
+ regmap_read(vc3->regmap, VC3_PLL1_CTRL_OUTDIV5, &premul);
+ if (premul & VC3_PLL1_CTRL_OUTDIV5_PLL1_MDIV_DOUBLER)
+ parent_rate *= 2;
+ return parent_rate;
+ }
+ mdiv = VC3_PLL1_M_DIV(prediv);
+ } else if (pfd->num == VC3_PFD2) {
+ /* The bypass_prediv is set, PLL fed from Ref_in directly. */
+ if (prediv & pfd->mdiv1_bitmsk) {
+ regmap_read(vc3->regmap, VC3_PLL2_M_DIVIDER, &premul);
+ /* check doubler is set or not */
+ if (premul & VC3_PLL2_MDIV_DOUBLER)
+ parent_rate *= 2;
+ return parent_rate;
+ }
+
+ mdiv = VC3_PLL2_M_DIV(prediv);
+ } else {
+ /* The bypass_prediv is set, PLL fed from Ref_in directly. */
+ if (prediv & pfd->mdiv1_bitmsk)
+ return parent_rate;
+
+ mdiv = VC3_PLL3_M_DIV(prediv);
+ }
+
+ if (prediv & pfd->mdiv2_bitmsk)
+ rate = parent_rate / 2;
+ else
+ rate = parent_rate / mdiv;
+
+ return rate;
+}
+
+static long vc3_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pfd_data *pfd = vc3->data;
+ unsigned long idiv;
+
+ /* PLL cannot operate with input clock above 50 MHz. */
+ if (rate > 50000000)
+ return -EINVAL;
+
+ /* CLKIN within range of PLL input, feed directly to PLL. */
+ if (*parent_rate <= 50000000)
+ return *parent_rate;
+
+ idiv = DIV_ROUND_UP(*parent_rate, rate);
+ if (pfd->num == VC3_PFD1 || pfd->num == VC3_PFD3) {
+ if (idiv > 63)
+ return -EINVAL;
+ } else {
+ if (idiv > 31)
+ return -EINVAL;
+ }
+
+ return *parent_rate / idiv;
+}
+
+static int vc3_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pfd_data *pfd = vc3->data;
+ unsigned long idiv;
+ u8 div;
+
+ /* CLKIN within range of PLL input, feed directly to PLL. */
+ if (parent_rate <= 50000000) {
+ regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv1_bitmsk,
+ pfd->mdiv1_bitmsk);
+ regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv2_bitmsk, 0);
+ return 0;
+ }
+
+ idiv = DIV_ROUND_UP(parent_rate, rate);
+ /* We have dedicated div-2 predivider. */
+ if (idiv == 2) {
+ regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv2_bitmsk,
+ pfd->mdiv2_bitmsk);
+ regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv1_bitmsk, 0);
+ } else {
+ if (pfd->num == VC3_PFD1)
+ div = VC3_PLL1_M_DIV(idiv);
+ else if (pfd->num == VC3_PFD2)
+ div = VC3_PLL2_M_DIV(idiv);
+ else
+ div = VC3_PLL3_M_DIV(idiv);
+
+ regmap_write(vc3->regmap, pfd->offs, div);
+ }
+
+ return 0;
+}
+
+static const struct clk_ops vc3_pfd_ops = {
+ .recalc_rate = vc3_pfd_recalc_rate,
+ .round_rate = vc3_pfd_round_rate,
+ .set_rate = vc3_pfd_set_rate,
+};
+
+static unsigned long vc3_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pll_data *pll = vc3->data;
+ u32 div_int, div_frc, val;
+ unsigned long rate;
+
+ regmap_read(vc3->regmap, pll->int_div_msb_offs, &val);
+ div_int = (val & GENMASK(2, 0)) << 8;
+ regmap_read(vc3->regmap, pll->int_div_lsb_offs, &val);
+ div_int |= val;
+
+ if (pll->num == VC3_PLL2) {
+ regmap_read(vc3->regmap, VC3_PLL2_FB_FRC_DIV_MSB, &val);
+ div_frc = val << 8;
+ regmap_read(vc3->regmap, VC3_PLL2_FB_FRC_DIV_LSB, &val);
+ div_frc |= val;
+ rate = (parent_rate *
+ (div_int * VC3_2_POW_16 + div_frc) / VC3_2_POW_16);
+ } else {
+ rate = parent_rate * div_int;
+ }
+
+ return rate;
+}
+
+static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pll_data *pll = vc3->data;
+ u64 div_frc;
+
+ if (rate < pll->vco_min)
+ rate = pll->vco_min;
+ if (rate > pll->vco_max)
+ rate = pll->vco_max;
+
+ vc3->div_int = rate / *parent_rate;
+
+ if (pll->num == VC3_PLL2) {
+ if (vc3->div_int > 0x7ff)
+ rate = *parent_rate * 0x7ff;
+
+ /* Determine best fractional part, which is 16 bit wide */
+ div_frc = rate % *parent_rate;
+ div_frc *= BIT(16) - 1;
+ do_div(div_frc, *parent_rate);
+
+ vc3->div_frc = (u32)div_frc;
+ rate = (*parent_rate *
+ (vc3->div_int * VC3_2_POW_16 + div_frc) / VC3_2_POW_16);
+ } else {
+ rate = *parent_rate * vc3->div_int;
+ }
+
+ return rate;
+}
+
+static int vc3_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_pll_data *pll = vc3->data;
+ u32 val;
+
+ regmap_read(vc3->regmap, pll->int_div_msb_offs, &val);
+ val = (val & 0xf8) | ((vc3->div_int >> 8) & 0x7);
+ regmap_write(vc3->regmap, pll->int_div_msb_offs, val);
+ regmap_write(vc3->regmap, pll->int_div_lsb_offs, vc3->div_int & 0xff);
+
+ if (pll->num == VC3_PLL2) {
+ regmap_write(vc3->regmap, VC3_PLL2_FB_FRC_DIV_MSB,
+ vc3->div_frc >> 8);
+ regmap_write(vc3->regmap, VC3_PLL2_FB_FRC_DIV_LSB,
+ vc3->div_frc & 0xff);
+ }
+
+ return 0;
+}
+
+static const struct clk_ops vc3_pll_ops = {
+ .recalc_rate = vc3_pll_recalc_rate,
+ .round_rate = vc3_pll_round_rate,
+ .set_rate = vc3_pll_set_rate,
+};
+
+static unsigned char vc3_div_mux_get_parent(struct clk_hw *hw)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *div_mux = vc3->data;
+ u32 src;
+
+ regmap_read(vc3->regmap, div_mux->offs, &src);
+
+ return !!(src & div_mux->bitmsk);
+}
+
+static int vc3_div_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *div_mux = vc3->data;
+
+ regmap_update_bits(vc3->regmap, div_mux->offs, div_mux->bitmsk,
+ index ? div_mux->bitmsk : 0);
+
+ return 0;
+}
+
+static const struct clk_ops vc3_div_mux_ops = {
+ .set_parent = vc3_div_mux_set_parent,
+ .get_parent = vc3_div_mux_get_parent,
+};
+
+static unsigned int vc3_get_div(const struct clk_div_table *table,
+ unsigned int val, unsigned long flag)
+{
+ const struct clk_div_table *clkt;
+
+ for (clkt = table; clkt->div; clkt++)
+ if (clkt->val == val)
+ return clkt->div;
+
+ return 0;
+}
+
+static unsigned long vc3_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_div_data *div_data = vc3->data;
+ unsigned int val;
+
+ regmap_read(vc3->regmap, div_data->offs, &val);
+ val >>= div_data->shift;
+ val &= VC3_DIV_MASK(div_data->width);
+
+ return divider_recalc_rate(hw, parent_rate, val, div_data->table,
+ div_data->flags, div_data->width);
+}
+
+static long vc3_div_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_div_data *div_data = vc3->data;
+ unsigned int bestdiv;
+
+ /* if read only, just return current value */
+ if (div_data->flags & CLK_DIVIDER_READ_ONLY) {
+ regmap_read(vc3->regmap, div_data->offs, &bestdiv);
+ bestdiv >>= div_data->shift;
+ bestdiv &= VC3_DIV_MASK(div_data->width);
+ bestdiv = vc3_get_div(div_data->table, bestdiv, div_data->flags);
+ return DIV_ROUND_UP(*parent_rate, bestdiv);
+ }
+
+ return divider_round_rate(hw, rate, parent_rate, div_data->table,
+ div_data->width, div_data->flags);
+}
+
+static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_div_data *div_data = vc3->data;
+ unsigned int value;
+
+ value = divider_get_val(rate, parent_rate, div_data->table,
+ div_data->width, div_data->flags);
+ regmap_update_bits(vc3->regmap, div_data->offs,
+ VC3_DIV_MASK(div_data->width) << div_data->shift,
+ value << div_data->shift);
+ return 0;
+}
+
+static const struct clk_ops vc3_div_ops = {
+ .recalc_rate = vc3_div_recalc_rate,
+ .round_rate = vc3_div_round_rate,
+ .set_rate = vc3_div_set_rate,
+};
+
+static int vc3_clk_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ int ret;
+ int frc;
+
+ ret = clk_mux_determine_rate_flags(hw, req, CLK_SET_RATE_PARENT);
+ if (ret) {
+ /* The below check is equivalent to (best_parent_rate/rate) */
+ if (req->best_parent_rate >= req->rate) {
+ frc = DIV_ROUND_CLOSEST_ULL(req->best_parent_rate,
+ req->rate);
+ req->rate *= frc;
+ return clk_mux_determine_rate_flags(hw, req,
+ CLK_SET_RATE_PARENT);
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static unsigned char vc3_clk_mux_get_parent(struct clk_hw *hw)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *clk_mux = vc3->data;
+ u32 val;
+
+ regmap_read(vc3->regmap, clk_mux->offs, &val);
+
+ return !!(val & clk_mux->bitmsk);
+}
+
+static int vc3_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw);
+ const struct vc3_clk_data *clk_mux = vc3->data;
+
+ regmap_update_bits(vc3->regmap, clk_mux->offs,
+ clk_mux->bitmsk, index ? clk_mux->bitmsk : 0);
+ return 0;
+}
+
+static const struct clk_ops vc3_clk_mux_ops = {
+ .determine_rate = vc3_clk_mux_determine_rate,
+ .set_parent = vc3_clk_mux_set_parent,
+ .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,
+ .max_register = 0x24,
+ .writeable_reg = vc3_regmap_is_writeable,
+};
+
+static struct vc3_hw_data clk_div[5];
+
+static const struct clk_parent_data pfd_mux_parent_data[] = {
+ { .index = 0, },
+ { .hw = &clk_div[VC3_DIV2].hw }
+};
+
+static struct vc3_hw_data clk_pfd_mux[] = {
+ [VC3_PFD2_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_PLL_OP_CTRL,
+ .bitmsk = BIT(VC3_PLL_OP_CTRL_PLL2_REFIN_SEL)
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pfd2_mux",
+ .ops = &vc3_pfd_mux_ops,
+ .parent_data = pfd_mux_parent_data,
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
+ }
+ },
+ [VC3_PFD3_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_GENERAL_CTR,
+ .bitmsk = BIT(VC3_GENERAL_CTR_PLL3_REFIN_SEL)
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pfd3_mux",
+ .ops = &vc3_pfd_mux_ops,
+ .parent_data = pfd_mux_parent_data,
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
+ }
+ }
+};
+
+static struct vc3_hw_data clk_pfd[] = {
+ [VC3_PFD1] = {
+ .data = &(struct vc3_pfd_data) {
+ .num = VC3_PFD1,
+ .offs = VC3_PLL1_M_DIVIDER,
+ .mdiv1_bitmsk = VC3_PLL1_M_DIV1,
+ .mdiv2_bitmsk = VC3_PLL1_M_DIV2
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pfd1",
+ .ops = &vc3_pfd_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .index = 0
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_PFD2] = {
+ .data = &(struct vc3_pfd_data) {
+ .num = VC3_PFD2,
+ .offs = VC3_PLL2_M_DIVIDER,
+ .mdiv1_bitmsk = VC3_PLL2_M_DIV1,
+ .mdiv2_bitmsk = VC3_PLL2_M_DIV2
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pfd2",
+ .ops = &vc3_pfd_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pfd_mux[VC3_PFD2_MUX].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_PFD3] = {
+ .data = &(struct vc3_pfd_data) {
+ .num = VC3_PFD3,
+ .offs = VC3_PLL3_M_DIVIDER,
+ .mdiv1_bitmsk = VC3_PLL3_M_DIV1,
+ .mdiv2_bitmsk = VC3_PLL3_M_DIV2
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pfd3",
+ .ops = &vc3_pfd_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pfd_mux[VC3_PFD3_MUX].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ }
+};
+
+static struct vc3_hw_data clk_pll[] = {
+ [VC3_PLL1] = {
+ .data = &(struct vc3_pll_data) {
+ .num = VC3_PLL1,
+ .int_div_msb_offs = VC3_PLL1_LOOP_FILTER_N_DIV_MSB,
+ .int_div_lsb_offs = VC3_PLL1_VCO_N_DIVIDER,
+ .vco_min = VC3_PLL1_VCO_MIN,
+ .vco_max = VC3_PLL1_VCO_MAX
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pll1",
+ .ops = &vc3_pll_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pfd[VC3_PFD1].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_PLL2] = {
+ .data = &(struct vc3_pll_data) {
+ .num = VC3_PLL2,
+ .int_div_msb_offs = VC3_PLL2_FB_INT_DIV_MSB,
+ .int_div_lsb_offs = VC3_PLL2_FB_INT_DIV_LSB,
+ .vco_min = VC3_PLL2_VCO_MIN,
+ .vco_max = VC3_PLL2_VCO_MAX
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pll2",
+ .ops = &vc3_pll_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pfd[VC3_PFD2].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_PLL3] = {
+ .data = &(struct vc3_pll_data) {
+ .num = VC3_PLL3,
+ .int_div_msb_offs = VC3_PLL3_LOOP_FILTER_N_DIV_MSB,
+ .int_div_lsb_offs = VC3_PLL3_N_DIVIDER,
+ .vco_min = VC3_PLL3_VCO_MIN,
+ .vco_max = VC3_PLL3_VCO_MAX
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "pll3",
+ .ops = &vc3_pll_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pfd[VC3_PFD3].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ }
+};
+
+static const struct clk_parent_data div_mux_parent_data[][2] = {
+ [VC3_DIV1_MUX] = {
+ { .hw = &clk_pll[VC3_PLL1].hw },
+ { .index = 0 }
+ },
+ [VC3_DIV3_MUX] = {
+ { .hw = &clk_pll[VC3_PLL2].hw },
+ { .hw = &clk_pll[VC3_PLL3].hw }
+ },
+ [VC3_DIV4_MUX] = {
+ { .hw = &clk_pll[VC3_PLL2].hw },
+ { .index = 0 }
+ }
+};
+
+static struct vc3_hw_data clk_div_mux[] = {
+ [VC3_DIV1_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_GENERAL_CTR,
+ .bitmsk = VC3_GENERAL_CTR_DIV1_SRC_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div1_mux",
+ .ops = &vc3_div_mux_ops,
+ .parent_data = div_mux_parent_data[VC3_DIV1_MUX],
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
+ }
+ },
+ [VC3_DIV3_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_PLL3_CHARGE_PUMP_CTRL,
+ .bitmsk = VC3_PLL3_CHARGE_PUMP_CTRL_OUTDIV3_SRC_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div3_mux",
+ .ops = &vc3_div_mux_ops,
+ .parent_data = div_mux_parent_data[VC3_DIV3_MUX],
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
+ }
+ },
+ [VC3_DIV4_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_OUTPUT_CTR,
+ .bitmsk = VC3_OUTPUT_CTR_DIV4_SRC_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div4_mux",
+ .ops = &vc3_div_mux_ops,
+ .parent_data = div_mux_parent_data[VC3_DIV4_MUX],
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
+ }
+ }
+};
+
+static struct vc3_hw_data clk_div[] = {
+ [VC3_DIV1] = {
+ .data = &(struct vc3_div_data) {
+ .offs = VC3_OUT_DIV1_DIV2_CTRL,
+ .table = div1_divs,
+ .shift = 4,
+ .width = 4,
+ .flags = CLK_DIVIDER_READ_ONLY
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div1",
+ .ops = &vc3_div_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div_mux[VC3_DIV1_MUX].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_DIV2] = {
+ .data = &(struct vc3_div_data) {
+ .offs = VC3_OUT_DIV1_DIV2_CTRL,
+ .table = div245_divs,
+ .shift = 0,
+ .width = 4,
+ .flags = CLK_DIVIDER_READ_ONLY
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div2",
+ .ops = &vc3_div_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pll[VC3_PLL1].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_DIV3] = {
+ .data = &(struct vc3_div_data) {
+ .offs = VC3_OUT_DIV3_DIV4_CTRL,
+ .table = div3_divs,
+ .shift = 4,
+ .width = 4,
+ .flags = CLK_DIVIDER_READ_ONLY
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div3",
+ .ops = &vc3_div_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div_mux[VC3_DIV3_MUX].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_DIV4] = {
+ .data = &(struct vc3_div_data) {
+ .offs = VC3_OUT_DIV3_DIV4_CTRL,
+ .table = div245_divs,
+ .shift = 0,
+ .width = 4,
+ .flags = CLK_DIVIDER_READ_ONLY
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div4",
+ .ops = &vc3_div_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div_mux[VC3_DIV4_MUX].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_DIV5] = {
+ .data = &(struct vc3_div_data) {
+ .offs = VC3_PLL1_CTRL_OUTDIV5,
+ .table = div245_divs,
+ .shift = 0,
+ .width = 4,
+ .flags = CLK_DIVIDER_READ_ONLY
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "div5",
+ .ops = &vc3_div_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_pll[VC3_PLL3].hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ }
+};
+
+static struct vc3_hw_data clk_mux[] = {
+ [VC3_DIFF2_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_DIFF2_CTRL_REG,
+ .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "diff2_mux",
+ .ops = &vc3_clk_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div[VC3_DIV1].hw,
+ &clk_div[VC3_DIV3].hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_DIFF1_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_DIFF1_CTRL_REG,
+ .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "diff1_mux",
+ .ops = &vc3_clk_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div[VC3_DIV1].hw,
+ &clk_div[VC3_DIV3].hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_SE3_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_SE3_DIFF1_CTRL_REG,
+ .bitmsk = VC3_SE3_DIFF1_CTRL_REG_SE3_CLK_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "se3_mux",
+ .ops = &vc3_clk_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div[VC3_DIV2].hw,
+ &clk_div[VC3_DIV4].hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_SE2_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_SE2_CTRL_REG0,
+ .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "se2_mux",
+ .ops = &vc3_clk_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div[VC3_DIV5].hw,
+ &clk_div[VC3_DIV4].hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ },
+ [VC3_SE1_MUX] = {
+ .data = &(struct vc3_clk_data) {
+ .offs = VC3_SE1_DIV4_CTRL,
+ .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "se1_mux",
+ .ops = &vc3_clk_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &clk_div[VC3_DIV5].hw,
+ &clk_div[VC3_DIV4].hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT
+ }
+ }
+};
+
+static struct clk_hw *vc3_of_clk_get(struct of_phandle_args *clkspec,
+ void *data)
+{
+ unsigned int idx = clkspec->args[0];
+ struct clk_hw **clkout_hw = data;
+
+ if (idx >= ARRAY_SIZE(clk_out)) {
+ pr_err("invalid clk index %u for provider %pOF\n", idx, clkspec->np);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return clkout_hw[idx];
+}
+
+static int vc3_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ u8 settings[NUM_CONFIG_REGISTERS];
+ struct regmap *regmap;
+ const char *name;
+ int ret, i;
+
+ regmap = devm_regmap_init_i2c(client, &vc3_regmap_config);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap),
+ "failed to allocate register map\n");
+
+ ret = of_property_read_u8_array(dev->of_node, "renesas,settings",
+ settings, ARRAY_SIZE(settings));
+ if (!ret) {
+ /*
+ * A raw settings array was specified in the DT. Write the
+ * settings to the device immediately.
+ */
+ for (i = 0; i < NUM_CONFIG_REGISTERS; i++) {
+ ret = regmap_write(regmap, i, settings[i]);
+ if (ret) {
+ dev_err(dev, "error writing to chip (%i)\n", ret);
+ return ret;
+ }
+ }
+ } else if (ret == -EOVERFLOW) {
+ dev_err(&client->dev, "EOVERFLOW reg settings. ARRAY_SIZE: %zu\n",
+ ARRAY_SIZE(settings));
+ return ret;
+ }
+
+ /* Register pfd muxes */
+ for (i = 0; i < ARRAY_SIZE(clk_pfd_mux); i++) {
+ clk_pfd_mux[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_pfd_mux[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_pfd_mux[i].hw.init->name);
+ }
+
+ /* Register pfd's */
+ for (i = 0; i < ARRAY_SIZE(clk_pfd); i++) {
+ clk_pfd[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_pfd[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_pfd[i].hw.init->name);
+ }
+
+ /* Register pll's */
+ for (i = 0; i < ARRAY_SIZE(clk_pll); i++) {
+ clk_pll[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_pll[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_pll[i].hw.init->name);
+ }
+
+ /* Register divider muxes */
+ for (i = 0; i < ARRAY_SIZE(clk_div_mux); i++) {
+ clk_div_mux[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_div_mux[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_div_mux[i].hw.init->name);
+ }
+
+ /* Register dividers */
+ for (i = 0; i < ARRAY_SIZE(clk_div); i++) {
+ clk_div[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_div[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_div[i].hw.init->name);
+ }
+
+ /* Register clk muxes */
+ for (i = 0; i < ARRAY_SIZE(clk_mux); i++) {
+ clk_mux[i].regmap = regmap;
+ ret = devm_clk_hw_register(dev, &clk_mux[i].hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "%s failed\n",
+ clk_mux[i].hw.init->name);
+ }
+
+ /* Register clk outputs */
+ for (i = 0; i < ARRAY_SIZE(clk_out); i++) {
+ switch (i) {
+ case VC3_DIFF2:
+ name = "diff2";
+ break;
+ case VC3_DIFF1:
+ name = "diff1";
+ break;
+ case VC3_SE3:
+ name = "se3";
+ break;
+ case VC3_SE2:
+ name = "se2";
+ break;
+ case VC3_SE1:
+ name = "se1";
+ break;
+ case VC3_REF:
+ name = "ref";
+ break;
+ default:
+ return dev_err_probe(dev, -EINVAL, "invalid clk output %d\n", i);
+ }
+
+ if (i == VC3_REF)
+ clk_out[i] = devm_clk_hw_register_fixed_factor_index(dev,
+ name, 0, CLK_SET_RATE_PARENT, 1, 1);
+ else
+ clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+ name, &clk_mux[i].hw, CLK_SET_RATE_PARENT, 1, 1);
+
+ if (IS_ERR(clk_out[i]))
+ return PTR_ERR(clk_out[i]);
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, vc3_of_clk_get, clk_out);
+ if (ret)
+ return dev_err_probe(dev, ret, "unable to add clk provider\n");
+
+ return ret;
+}
+
+static const struct of_device_id dev_ids[] = {
+ { .compatible = "renesas,5p35023" },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dev_ids);
+
+static struct i2c_driver vc3_driver = {
+ .driver = {
+ .name = "vc3",
+ .of_match_table = of_match_ptr(dev_ids),
+ },
+ .probe_new = vc3_probe,
+};
+module_i2c_driver(vc3_driver);
+
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_DESCRIPTION("Renesas VersaClock 3 driver");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 08/11] clk: vc3: Fix 64 by 64 division
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (6 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 09/11] clk: vc3: Fix output clock mapping Biju Das
` (4 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit 576418e3417267e93ffee09c46f56434108c4548 upstream.
Fix the below cocci warnings by replacing do_div()->div64_ul() and
bound the result with a max value of U16_MAX.
cocci warnings:
drivers/clk/clk-versaclock3.c:404:2-8: WARNING: do_div() does a
64-by-32 division, please consider using div64_ul instead.
Reported-by: Julia Lawall <julia.lawall@inria.fr>
Closes: https://lore.kernel.org/r/202307270841.yr5HxYIl-lkp@intel.com/
Fixes: 6e9aff555db7 ("clk: Add support for versa3 clock driver")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230824104812.147775-3-biju.das.jz@bp.renesas.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-versaclock3.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c
index ca0921510a70..4013b114bfdf 100644
--- a/drivers/clk/clk-versaclock3.c
+++ b/drivers/clk/clk-versaclock3.c
@@ -400,11 +400,10 @@ static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate,
/* Determine best fractional part, which is 16 bit wide */
div_frc = rate % *parent_rate;
div_frc *= BIT(16) - 1;
- do_div(div_frc, *parent_rate);
- vc3->div_frc = (u32)div_frc;
+ vc3->div_frc = min_t(u64, div64_ul(div_frc, *parent_rate), U16_MAX);
rate = (*parent_rate *
- (vc3->div_int * VC3_2_POW_16 + div_frc) / VC3_2_POW_16);
+ (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16);
} else {
rate = *parent_rate * vc3->div_int;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 09/11] clk: vc3: Fix output clock mapping
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (7 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 08/11] clk: vc3: Fix 64 by 64 division Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 10/11] clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum Biju Das
` (3 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit 6dcf03bcac31dec528867180f96580652fc3ac5b upstream.
According to Table 3. ("Output Source") in the 5P35023 datasheet,
the output clock mapping should be 0=REF, 1=SE1, 2=SE2, 3=SE3,
4=DIFF1, 5=DIFF2. But the code uses inverse. Fix this mapping issue.
Suggested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Closes: https://lore.kernel.org/all/CAMuHMdUHD+bEco=WYTYWsTAyRt3dTQQt4Xpaejss0Y2ZpLCMNg@mail.gmail.com/
Fixes: 6e9aff555db7 ("clk: Add support for versa3 clock driver")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20230824104812.147775-4-biju.das.jz@bp.renesas.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-versaclock3.c | 68 +++++++++++++++++------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c
index 4013b114bfdf..dd4c1f3b5863 100644
--- a/drivers/clk/clk-versaclock3.c
+++ b/drivers/clk/clk-versaclock3.c
@@ -119,20 +119,20 @@ enum vc3_div {
};
enum vc3_clk_mux {
- VC3_DIFF2_MUX,
- VC3_DIFF1_MUX,
- VC3_SE3_MUX,
- VC3_SE2_MUX,
VC3_SE1_MUX,
+ VC3_SE2_MUX,
+ VC3_SE3_MUX,
+ VC3_DIFF1_MUX,
+ VC3_DIFF2_MUX,
};
enum vc3_clk {
- VC3_DIFF2,
- VC3_DIFF1,
- VC3_SE3,
- VC3_SE2,
- VC3_SE1,
VC3_REF,
+ VC3_SE1,
+ VC3_SE2,
+ VC3_SE3,
+ VC3_DIFF1,
+ VC3_DIFF2,
};
struct vc3_clk_data {
@@ -894,33 +894,33 @@ static struct vc3_hw_data clk_div[] = {
};
static struct vc3_hw_data clk_mux[] = {
- [VC3_DIFF2_MUX] = {
+ [VC3_SE1_MUX] = {
.data = &(struct vc3_clk_data) {
- .offs = VC3_DIFF2_CTRL_REG,
- .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL
+ .offs = VC3_SE1_DIV4_CTRL,
+ .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL
},
.hw.init = &(struct clk_init_data){
- .name = "diff2_mux",
+ .name = "se1_mux",
.ops = &vc3_clk_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
- &clk_div[VC3_DIV1].hw,
- &clk_div[VC3_DIV3].hw
+ &clk_div[VC3_DIV5].hw,
+ &clk_div[VC3_DIV4].hw
},
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT
}
},
- [VC3_DIFF1_MUX] = {
+ [VC3_SE2_MUX] = {
.data = &(struct vc3_clk_data) {
- .offs = VC3_DIFF1_CTRL_REG,
- .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL
+ .offs = VC3_SE2_CTRL_REG0,
+ .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL
},
.hw.init = &(struct clk_init_data){
- .name = "diff1_mux",
+ .name = "se2_mux",
.ops = &vc3_clk_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
- &clk_div[VC3_DIV1].hw,
- &clk_div[VC3_DIV3].hw
+ &clk_div[VC3_DIV5].hw,
+ &clk_div[VC3_DIV4].hw
},
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT
@@ -942,33 +942,33 @@ static struct vc3_hw_data clk_mux[] = {
.flags = CLK_SET_RATE_PARENT
}
},
- [VC3_SE2_MUX] = {
+ [VC3_DIFF1_MUX] = {
.data = &(struct vc3_clk_data) {
- .offs = VC3_SE2_CTRL_REG0,
- .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL
+ .offs = VC3_DIFF1_CTRL_REG,
+ .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL
},
.hw.init = &(struct clk_init_data){
- .name = "se2_mux",
+ .name = "diff1_mux",
.ops = &vc3_clk_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
- &clk_div[VC3_DIV5].hw,
- &clk_div[VC3_DIV4].hw
+ &clk_div[VC3_DIV1].hw,
+ &clk_div[VC3_DIV3].hw
},
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT
}
},
- [VC3_SE1_MUX] = {
+ [VC3_DIFF2_MUX] = {
.data = &(struct vc3_clk_data) {
- .offs = VC3_SE1_DIV4_CTRL,
- .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL
+ .offs = VC3_DIFF2_CTRL_REG,
+ .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL
},
.hw.init = &(struct clk_init_data){
- .name = "se1_mux",
+ .name = "diff2_mux",
.ops = &vc3_clk_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
- &clk_div[VC3_DIV5].hw,
- &clk_div[VC3_DIV4].hw
+ &clk_div[VC3_DIV1].hw,
+ &clk_div[VC3_DIV3].hw
},
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT
@@ -1107,7 +1107,7 @@ static int vc3_probe(struct i2c_client *client)
name, 0, CLK_SET_RATE_PARENT, 1, 1);
else
clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev,
- name, &clk_mux[i].hw, CLK_SET_RATE_PARENT, 1, 1);
+ name, &clk_mux[i - 1].hw, CLK_SET_RATE_PARENT, 1, 1);
if (IS_ERR(clk_out[i]))
return PTR_ERR(clk_out[i]);
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 10/11] clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (8 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 09/11] clk: vc3: Fix output clock mapping Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 11/11] arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk Biju Das
` (2 subsequent siblings)
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit eec11486d191c6247e6ffdc898bc31da3cfadcce upstream.
Make vc3_clk_mux enum values depend upon vc3_clk enum values to avoid
any accidental breakage in the future.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230824104812.147775-5-biju.das.jz@bp.renesas.com
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/clk/clk-versaclock3.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c
index dd4c1f3b5863..aa36c68ea09a 100644
--- a/drivers/clk/clk-versaclock3.c
+++ b/drivers/clk/clk-versaclock3.c
@@ -118,14 +118,6 @@ enum vc3_div {
VC3_DIV5,
};
-enum vc3_clk_mux {
- VC3_SE1_MUX,
- VC3_SE2_MUX,
- VC3_SE3_MUX,
- VC3_DIFF1_MUX,
- VC3_DIFF2_MUX,
-};
-
enum vc3_clk {
VC3_REF,
VC3_SE1,
@@ -135,6 +127,14 @@ enum vc3_clk {
VC3_DIFF2,
};
+enum vc3_clk_mux {
+ VC3_SE1_MUX = VC3_SE1 - 1,
+ VC3_SE2_MUX = VC3_SE2 - 1,
+ VC3_SE3_MUX = VC3_SE3 - 1,
+ VC3_DIFF1_MUX = VC3_DIFF1 - 1,
+ VC3_DIFF2_MUX = VC3_DIFF2 - 1,
+};
+
struct vc3_clk_data {
u8 offs;
u8 bitmsk;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5.10.y-cip 11/11] arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (9 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 10/11] clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum Biju Das
@ 2023-11-22 14:28 ` Biju Das
2023-11-22 21:03 ` [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Pavel Machek
2023-11-23 22:15 ` nobuhiro1.iwamatsu
12 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-22 14:28 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek; +Cc: Biju Das, Claudiu Beznea
commit feab6a13ae63101e62a9f3b0e552f13067218e6f upstream.
Currently audio mclk uses a fixed clk of 11.2896MHz (multiple of 44.1kHz).
Replace this fixed clk with the programmable versa3 clk that can provide
the clocking to support both 44.1kHz (with a clock of 11.2896MHz) and
48kHz (with a clock of 12.2880MHz), based on audio sampling rate for
playback and record.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20230825090518.87394-1-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
.../boot/dts/renesas/rz-smarc-common.dtsi | 14 +++++------
arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi | 20 ++++++++++++++++
arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi | 20 ++++++++++++++++
arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi | 24 +++++++++++++++++++
4 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
index 3962d47b3e59..48b839a6eae4 100644
--- a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi
@@ -32,12 +32,6 @@ chosen {
stdout-path = "serial0:115200n8";
};
- audio_mclock: audio_mclock {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <11289600>;
- };
-
snd_rzg2l: sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
@@ -55,7 +49,7 @@ cpu_dai: simple-audio-card,cpu {
};
codec_dai: simple-audio-card,codec {
- clocks = <&audio_mclock>;
+ clocks = <&versa3 2>;
sound-dai = <&wm8978>;
};
};
@@ -76,6 +70,12 @@ vccq_sdhi1: regulator-vccq-sdhi1 {
gpios-states = <1>;
states = <3300000 1>, <1800000 0>;
};
+
+ x1: x1-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
};
&audio_clk1{
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
index 018c34f841bf..9b5a368da40b 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -31,6 +31,26 @@ wm8978: codec@1a {
#sound-dai-cells = <0>;
reg = <0x1a>;
};
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
};
#if PMOD_MTU3
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
index 664318e3dfb6..35777e97999b 100644
--- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
@@ -47,6 +47,26 @@ wm8978: codec@1a {
#sound-dai-cells = <0>;
reg = <0x1a>;
};
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
};
#if PMOD_MTU3
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
index b672e3474705..c6981bea40a4 100644
--- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
@@ -34,6 +34,30 @@ &cpu_dai {
sound-dai = <&ssi1>;
};
+&i2c0 {
+ clock-frequency = <400000>;
+
+ versa3: clock-generator@68 {
+ compatible = "renesas,5p35023";
+ reg = <0x68>;
+ #clock-cells = <1>;
+ clocks = <&x1>;
+
+ renesas,settings = [
+ 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf
+ 00 14 7a e1 00 00 00 00 01 55 59 bb 3f 30 90 b6
+ 80 b0 45 c4 95
+ ];
+
+ assigned-clocks = <&versa3 0>, <&versa3 1>,
+ <&versa3 2>, <&versa3 3>,
+ <&versa3 4>, <&versa3 5>;
+ assigned-clock-rates = <24000000>, <11289600>,
+ <11289600>, <12000000>,
+ <25000000>, <12288000>;
+ };
+};
+
&i2c1 {
wm8978: codec@1a {
compatible = "wlf,wm8978";
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (10 preceding siblings ...)
2023-11-22 14:28 ` [PATCH 5.10.y-cip 11/11] arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk Biju Das
@ 2023-11-22 21:03 ` Pavel Machek
2023-11-23 7:25 ` Biju Das
2023-11-23 22:15 ` nobuhiro1.iwamatsu
12 siblings, 1 reply; 19+ messages in thread
From: Pavel Machek @ 2023-11-22 21:03 UTC (permalink / raw)
To: Biju Das; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek, Claudiu Beznea
[-- Attachment #1: Type: text/plain, Size: 585 bytes --]
Hi!
> This patch series aims to add versa3 clk generator support on
> RZ/G2{L,LC,UL}/RZ/Five SMARC EVKs.
>
> All the patches are cherry-picked from the mainline.
Thanks for patches. Both this and 6.1 version looks okay to me, and I
have only very minor comments. I can apply them if there are no other
commens and if they pass testing. (But I'd preffer to have
5.10.101-cip release, first).
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic
2023-11-22 14:28 ` [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic Biju Das
@ 2023-11-22 21:04 ` Pavel Machek
0 siblings, 0 replies; 19+ messages in thread
From: Pavel Machek @ 2023-11-22 21:04 UTC (permalink / raw)
To: Biju Das; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek, Claudiu Beznea
[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]
Hi!
> From: Samuel Holland <samuel@sholland.org>
>
> commit c33ed61249dc54e7cf2137c04462883560375b77 upstream.
>
> This compatible is part of the legacy sunxi clock support, and has not
> been used since commit 6b48644b1d29 ("ARM: gr8: Convert to CCU") in
> October 2016. Since supporting this compatible adds some overhead to
> generic clock code, let's clean it up.
> +++ b/drivers/clk/clk-fixed-factor.c
> @@ -203,16 +203,10 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
> EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
>
> #ifdef CONFIG_OF
> -static const struct of_device_id set_rate_parent_matches[] = {
> - { .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
> - { /* Sentinel */ },
> -};
This is still mentioned in
Documentation/devicetree/bindings/clock/fixed-factor-clock.yaml.
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver
2023-11-22 14:28 ` [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver Biju Das
@ 2023-11-22 21:07 ` Pavel Machek
2023-11-23 8:30 ` Biju Das
0 siblings, 1 reply; 19+ messages in thread
From: Pavel Machek @ 2023-11-22 21:07 UTC (permalink / raw)
To: Biju Das; +Cc: cip-dev, Nobuhiro Iwamatsu, Pavel Machek, Claudiu Beznea
[-- Attachment #1: Type: text/plain, Size: 628 bytes --]
Hi!
> Add support for Renesas versa3 clock driver(5p35023).
> The clock generator provides 6 output clocks.
> + if (!ret) {
> + /*
> + * A raw settings array was specified in the DT. Write the
> + * settings to the device immediately.
> + */
> + for (i = 0; i < NUM_CONFIG_REGISTERS; i++) {
> + ret = regmap_write(regmap, i, settings[i]);
One space is enough after "for", but I'm not sure that's worth
separate patch.
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
2023-11-22 21:03 ` [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Pavel Machek
@ 2023-11-23 7:25 ` Biju Das
0 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-23 7:25 UTC (permalink / raw)
To: Pavel Machek
Cc: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu, Claudiu Beznea
Hi Pavel,
> Subject: Re: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
>
> Hi!
>
> > This patch series aims to add versa3 clk generator support on
> > RZ/G2{L,LC,UL}/RZ/Five SMARC EVKs.
> >
> > All the patches are cherry-picked from the mainline.
>
> Thanks for patches. Both this and 6.1 version looks okay to me, and I have
> only very minor comments. I can apply them if there are no other commens
> and if they pass testing. (But I'd preffer to have 5.10.101-cip release,
> first).
There is a plan to rebase upcoming VLP release with latest CIP kernel, so it
would be nice to have this driver in 5.10 so that it will be part of upcoming
Renesas VLP release.
Cheers,
Biju
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver
2023-11-22 21:07 ` Pavel Machek
@ 2023-11-23 8:30 ` Biju Das
0 siblings, 0 replies; 19+ messages in thread
From: Biju Das @ 2023-11-23 8:30 UTC (permalink / raw)
To: Pavel Machek
Cc: cip-dev@lists.cip-project.org, Nobuhiro Iwamatsu, Claudiu Beznea
Hi Pavel,
Thanks for the feedback.
> Subject: Re: [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock
> driver
>
> Hi!
>
> > Add support for Renesas versa3 clock driver(5p35023).
> > The clock generator provides 6 output clocks.
>
>
> > + if (!ret) {
> > + /*
> > + * A raw settings array was specified in the DT. Write the
> > + * settings to the device immediately.
> > + */
> > + for (i = 0; i < NUM_CONFIG_REGISTERS; i++) {
> > + ret = regmap_write(regmap, i, settings[i]);
>
> One space is enough after "for", but I'm not sure that's worth separate
> patch.
I have sent some cleanup patches yesterday. If there is a v2, I will include this as well.
https://patchwork.kernel.org/project/linux-renesas-soc/list/?series=803310
Cheers,
Biju
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
` (11 preceding siblings ...)
2023-11-22 21:03 ` [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Pavel Machek
@ 2023-11-23 22:15 ` nobuhiro1.iwamatsu
2023-11-24 8:42 ` Pavel Machek
12 siblings, 1 reply; 19+ messages in thread
From: nobuhiro1.iwamatsu @ 2023-11-23 22:15 UTC (permalink / raw)
To: biju.das.jz, cip-dev, pavel; +Cc: claudiu.beznea.uj
Hi,
> -----Original Message-----
> From: Biju Das <biju.das.jz@bp.renesas.com>
> Sent: Wednesday, November 22, 2023 11:28 PM
> To: cip-dev@lists.cip-project.org; iwamatsu nobuhiro(岩松 信洋 ○DITC□
> DIT○OST) <nobuhiro1.iwamatsu@toshiba.co.jp>; Pavel Machek
> <pavel@denx.de>
> Cc: Biju Das <biju.das.jz@bp.renesas.com>; Claudiu Beznea
> <claudiu.beznea.uj@bp.renesas.com>
> Subject: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
>
> This patch series aims to add versa3 clk generator support on
> RZ/G2{L,LC,UL}/RZ/Five SMARC EVKs.
>
> All the patches are cherry-picked from the mainline.
>
> Biju Das (7):
> dt-bindings: clock: Add Renesas versa3 clock generator bindings
> dt-bindings: clock: versaclock3: Add description for #clock-cells
> property
> clk: Add support for versa3 clock driver
> clk: vc3: Fix 64 by 64 division
> clk: vc3: Fix output clock mapping
> clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum
> arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk
>
> Daniel Palmer (1):
> clk: fixed: add devm helper for clk_hw_register_fixed_factor()
>
> Marek Vasut (1):
> clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index()
>
> Marijn Suijten (1):
> clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
>
> Samuel Holland (1):
> clk: fixed: Remove Allwinner A10 special-case logic
>
I reviewed this series, LGTM. So, I can apply this series.
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support
2023-11-23 22:15 ` nobuhiro1.iwamatsu
@ 2023-11-24 8:42 ` Pavel Machek
0 siblings, 0 replies; 19+ messages in thread
From: Pavel Machek @ 2023-11-24 8:42 UTC (permalink / raw)
To: nobuhiro1.iwamatsu; +Cc: biju.das.jz, cip-dev, pavel, claudiu.beznea.uj
[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]
Hi!
> > All the patches are cherry-picked from the mainline.
> >
> > Biju Das (7):
> > dt-bindings: clock: Add Renesas versa3 clock generator bindings
> > dt-bindings: clock: versaclock3: Add description for #clock-cells
> > property
> > clk: Add support for versa3 clock driver
> > clk: vc3: Fix 64 by 64 division
> > clk: vc3: Fix output clock mapping
> > clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum
> > arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk
> >
> > Daniel Palmer (1):
> > clk: fixed: add devm helper for clk_hw_register_fixed_factor()
> >
> > Marek Vasut (1):
> > clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index()
> >
> > Marijn Suijten (1):
> > clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()
> >
> > Samuel Holland (1):
> > clk: fixed: Remove Allwinner A10 special-case logic
> >
>
> I reviewed this series, LGTM. So, I can apply this series.
>
> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Thanks for review, applied.
Best regards,
Pavel
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2023-11-24 8:42 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-22 14:28 [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 01/11] dt-bindings: clock: Add Renesas versa3 clock generator bindings Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 02/11] dt-bindings: clock: versaclock3: Add description for #clock-cells property Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 03/11] clk: fixed: add devm helper for clk_hw_register_fixed_factor() Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 04/11] clk: fixed-factor: Introduce devm_clk_hw_register_fixed_factor_index() Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 05/11] clk: fixed: Remove Allwinner A10 special-case logic Biju Das
2023-11-22 21:04 ` Pavel Machek
2023-11-22 14:28 ` [PATCH 5.10.y-cip 06/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw() Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 07/11] clk: Add support for versa3 clock driver Biju Das
2023-11-22 21:07 ` Pavel Machek
2023-11-23 8:30 ` Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 08/11] clk: vc3: Fix 64 by 64 division Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 09/11] clk: vc3: Fix output clock mapping Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 10/11] clk: vc3: Make vc3_clk_mux enum values based on vc3_clk enum Biju Das
2023-11-22 14:28 ` [PATCH 5.10.y-cip 11/11] arm64: dts: renesas: rz-smarc: Use versa3 clk for audio mclk Biju Das
2023-11-22 21:03 ` [PATCH 5.10.y-cip 00/11] Add versa3 clk generator support Pavel Machek
2023-11-23 7:25 ` Biju Das
2023-11-23 22:15 ` nobuhiro1.iwamatsu
2023-11-24 8:42 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox