* [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
@ 2025-04-29 8:19 ` Thierry Bultel
2025-04-29 14:48 ` Hugo Villeneuve
` (2 more replies)
2025-04-29 8:19 ` [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
` (9 subsequent siblings)
10 siblings, 3 replies; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Geert Uytterhoeven, linux-kernel, linux-serial, devicetree
At boot, the default clock is the PCLKM core lock (synchronous
clock, which is enabled by the bootloader).
For different baudrates, the asynchronous clock input must be used.
Clock selection is made by an internal register of RCSI.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
.../bindings/serial/renesas,rsci.yaml | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
index ea879db5f485..aa2428837a2f 100644
--- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
+++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
@@ -35,10 +35,14 @@ properties:
- const: tei
clocks:
- maxItems: 1
+ items:
+ - description: serial functional clock
+ - description: default core clock
clock-names:
- const: fck # UART functional clock
+ items:
+ - const: async
+ - const: bus
power-domains:
maxItems: 1
@@ -58,11 +62,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/clock/renesas-cpg-mssr.h>
-
- aliases {
- serial0 = &sci0;
- };
+ #include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
sci0: serial@80005000 {
compatible = "renesas,r9a09g077-rsci";
@@ -72,7 +72,7 @@ examples:
<GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "eri", "rxi", "txi", "tei";
- clocks = <&cpg CPG_MOD 108>;
- clock-names = "fck";
+ clocks = <&cpg CPG_MOD 108>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
+ clock-names = "async", "bus";
power-domains = <&cpg>;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 9:20 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
` (8 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Rob Herring, Geert Uytterhoeven, devicetree, linux-kernel
Add RZ/T2H (R9A09G077), its variants, and the rt2h-evk evaluation board in
documentation.
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
.../devicetree/bindings/soc/renesas/renesas.yaml | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index 51a4c48eea6d..6874f425bf1f 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -570,6 +570,16 @@ properties:
- const: renesas,r9a09g057h48
- const: renesas,r9a09g057
+ - description: RZ/T2H (R9A09G077)
+ items:
+ - enum:
+ - renesas,rzt2h-evk # RZ/T2H Evaluation Board
+ - enum:
+ - renesas,r9a09g077m04 # RZ/T2H with Single Cortex-A55 + Dual Cortex-R52 - no security
+ - renesas,r9a09g077m24 # RZ/T2H with Dual Cortex-A55 + Dual Cortex-R52 - no security
+ - renesas,r9a09g077m44 # RZ/T2H with Quad Cortex-A55 + Dual Cortex-R52 - no security
+ - const: renesas,r9a09g077
+
additionalProperties: true
...
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
2025-04-29 8:19 ` [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-04-29 15:01 ` Rob Herring (Arm)
2025-05-13 10:00 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 04/11] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
` (7 subsequent siblings)
10 siblings, 2 replies; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Geert Uytterhoeven, linux-clk, devicetree, linux-kernel
Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- extra parenthesis
- added loco
- renesas-cpg-mssr.h: removed unused clocks, added a macro for mstp
Changes v6->v7:
- Add description for reg property
Changes v5->v6:
- Set clock minItem constraint
- Moved additionalProperties after 'allOf' section
Changes v4->v5:
- Set reg minItems and maxItems defaults at top level
Changes v3->v4:
- Handle maxItems and clocks names properly in schema.
---
.../bindings/clock/renesas,cpg-mssr.yaml | 58 ++++++++++++++-----
.../clock/renesas,r9a09g077-cpg-mssr.h | 48 +++++++++++++++
2 files changed, 90 insertions(+), 16 deletions(-)
create mode 100644 include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
index 77ce3615c65a..464827f2067e 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
@@ -52,9 +52,15 @@ properties:
- renesas,r8a779f0-cpg-mssr # R-Car S4-8
- renesas,r8a779g0-cpg-mssr # R-Car V4H
- renesas,r8a779h0-cpg-mssr # R-Car V4M
+ - renesas,r9a09g077-cpg-mssr # RZ/T2H
reg:
- maxItems: 1
+ minItems: 1
+ items:
+ - description: base address of register block 0
+ - description: base address of register block 1
+ description: base addresses of clock controller. Some controllers
+ (like r9a09g077) use two blocks instead of a single one.
clocks:
minItems: 1
@@ -63,11 +69,6 @@ properties:
clock-names:
minItems: 1
maxItems: 2
- items:
- enum:
- - extal # All
- - extalr # Most R-Car Gen3 and RZ/G2
- - usb_extal # Most R-Car Gen2 and RZ/G1
'#clock-cells':
description: |
@@ -92,16 +93,6 @@ properties:
the datasheet.
const: 1
-if:
- not:
- properties:
- compatible:
- items:
- enum:
- - renesas,r7s9210-cpg-mssr
-then:
- required:
- - '#reset-cells'
required:
- compatible
@@ -111,6 +102,41 @@ required:
- '#clock-cells'
- '#power-domain-cells'
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a09g077-cpg-mssr
+ then:
+ properties:
+ reg:
+ minItems: 2
+ clock-names:
+ items:
+ - const: extal
+ else:
+ properties:
+ reg:
+ maxItems: 1
+ clock-names:
+ items:
+ enum:
+ - extal # All
+ - extalr # Most R-Car Gen3 and RZ/G2
+ - usb_extal # Most R-Car Gen2 and RZ/G1
+
+ - if:
+ not:
+ properties:
+ compatible:
+ items:
+ enum:
+ - renesas,r7s9210-cpg-mssr
+ then:
+ required:
+ - '#reset-cells'
+
additionalProperties: false
examples:
diff --git a/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
new file mode 100644
index 000000000000..d5b16d08e75d
--- /dev/null
+++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
+#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* R9A09G077 CPG Core Clocks */
+#define R9A09G077_CLK_CA55C0 0
+#define R9A09G077_CLK_CA55C1 1
+#define R9A09G077_CLK_CA55C2 2
+#define R9A09G077_CLK_CA55C3 3
+#define R9A09G077_CLK_CA55S 4
+#define R9A09G077_CLK_CR52_CPU0 5
+#define R9A09G077_CLK_CR52_CPU1 6
+#define R9A09G077_CLK_BSC 7
+#define R9A09G077_CLK_CKIO R9A09G077_CLK_BSC
+#define R9A09G077_CLK_PCLKAH 8
+#define R9A09G077_CLK_PCLKAM 9
+#define R9A09G077_CLK_PCLKAL 10
+#define R9A09G077_CLK_PCLKGPTL 11
+#define R9A09G077_CLK_PCLKH 12
+#define R9A09G077_CLK_PCLKM 13
+
+
+#define R9A09G077_MSTPCRA 0
+#define R9A09G077_MSTPCRB 1
+#define R9A09G077_MSTPCRC 2
+#define R9A09G077_MSTPCRD 3
+#define R9A09G077_MSTPCRE 4
+#define R9A09G077_MSTPCRG 7
+#define R9A09G077_MSTPCRI 8
+#define R9A09G077_MSTPCRJ 9
+#define R9A09G077_MSTPCRK 10
+#define R9A09G077_MSTPCRL 11
+#define R9A09G077_MSTPCRM 12
+#define R9A09G077_MSTPCRN 13
+
+#define R9A09G077_MSTP(mstp, idx) (100*(mstp)+(idx))
+
+/* R9A09G077 CPG Module Clocks */
+#define R9A09G077_PCLK_SCI0 R9A09G077_MSTP(R9A09G077_MSTPCRA, 8)
+
+#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */
+
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 04/11] soc: renesas: Add RZ/T2H (R9A09G077) config option
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (2 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-04-29 8:19 ` [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
` (6 subsequent siblings)
10 siblings, 0 replies; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Geert Uytterhoeven, linux-kernel
Add a configuration option for the RZ/T2H SoC.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8: none
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
- Sets ARCH_R9A09G077 to Y by default.
---
drivers/soc/renesas/Kconfig | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 49648cf28bd2..5ce646afa008 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -359,6 +359,12 @@ config ARCH_R9A09G057
help
This enables support for the Renesas RZ/V2H(P) SoC variants.
+config ARCH_R9A09G077
+ bool "ARM64 Platform support for RZ/T2H"
+ default y if ARCH_RENESAS
+ help
+ This enables support for the Renesas RZ/T2H SoC variants.
+
endif # ARM64
if RISCV
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (3 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 04/11] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 10:10 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
` (5 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
linux-clk, linux-kernel
In a subsequent patch, the registration callback will need more parameters
from cpg_mssr_priv (like another base address with clock controllers
with double register block, and also, notifiers and rmw_lock).
Instead of adding more parameters, move the needed parameters to a public
sub-struct.
Instead moving clks to this structure, which would have implied to add
an allocation (and cleanup) for it, keep the way the allocation is done
and just have a copy of the pointer in the public structure.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- moved struct cpg_mssr_pub pub to the beginning of struct cpg_mssr_priv
- make *core & *info fit on the same line
- order of doc tags
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4: none
---
drivers/clk/renesas/r7s9210-cpg-mssr.c | 7 +-
drivers/clk/renesas/r8a77970-cpg-mssr.c | 8 +-
drivers/clk/renesas/rcar-gen2-cpg.c | 5 +-
drivers/clk/renesas/rcar-gen2-cpg.h | 3 +-
drivers/clk/renesas/rcar-gen3-cpg.c | 6 +-
drivers/clk/renesas/rcar-gen3-cpg.h | 3 +-
drivers/clk/renesas/rcar-gen4-cpg.c | 6 +-
drivers/clk/renesas/rcar-gen4-cpg.h | 3 +-
drivers/clk/renesas/renesas-cpg-mssr.c | 98 ++++++++++++-------------
drivers/clk/renesas/renesas-cpg-mssr.h | 20 ++++-
10 files changed, 88 insertions(+), 71 deletions(-)
diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c
index e1812867a6da..a8ed87c11ba1 100644
--- a/drivers/clk/renesas/r7s9210-cpg-mssr.c
+++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c
@@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk,
static struct clk * __init rza2_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers)
+ struct cpg_mssr_pub *pub)
{
- struct clk *parent;
+ void __iomem *base = pub->base0;
+ struct clk **clks = pub->clks;
unsigned int mult = 1;
unsigned int div = 1;
+ struct clk *parent;
parent = clks[core->parent];
if (IS_ERR(parent))
diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
index 3cec0f501b94..e2bda2c10730 100644
--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
@@ -219,10 +219,11 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers)
+ struct cpg_mssr_pub *pub)
{
const struct clk_div_table *table;
+ void __iomem *base = pub->base0;
+ struct clk **clks = pub->clks;
const struct clk *parent;
unsigned int shift;
@@ -236,8 +237,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
shift = 4;
break;
default:
- return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
- notifiers);
+ return rcar_gen3_cpg_clk_register(dev, core, info, pub);
}
parent = clks[core->parent];
diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c
index 4c3764972bad..ab34bb8c3e07 100644
--- a/drivers/clk/renesas/rcar-gen2-cpg.c
+++ b/drivers/clk/renesas/rcar-gen2-cpg.c
@@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers)
+ struct cpg_mssr_pub *pub)
{
const struct clk_div_table *table = NULL;
+ void __iomem *base = pub->base0;
+ struct clk **clks = pub->clks;
const struct clk *parent;
const char *parent_name;
unsigned int mult = 1;
diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h
index bdcd4a38d48d..3d4b127fdeaf 100644
--- a/drivers/clk/renesas/rcar-gen2-cpg.h
+++ b/drivers/clk/renesas/rcar-gen2-cpg.h
@@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config {
struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers);
+ struct cpg_mssr_pub *pub);
int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config,
unsigned int pll0_div, u32 mode);
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 027100e84ee4..10ae20489df9 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -345,9 +345,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers)
+ struct cpg_mssr_pub *pub)
{
+ struct raw_notifier_head *notifiers = &pub->notifiers;
+ void __iomem *base = pub->base0;
+ struct clk **clks = pub->clks;
const struct clk *parent;
unsigned int mult = 1;
unsigned int div = 1;
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index bfdc649bdf12..d15a5d1df71c 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -81,8 +81,7 @@ struct rcar_gen3_cpg_pll_config {
struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers);
+ struct cpg_mssr_pub *pub);
int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
unsigned int clk_extalr, u32 mode);
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c
index 31aa790fd003..fb9a876aaba5 100644
--- a/drivers/clk/renesas/rcar-gen4-cpg.c
+++ b/drivers/clk/renesas/rcar-gen4-cpg.c
@@ -418,9 +418,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = {
struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers)
+ struct cpg_mssr_pub *pub)
{
+ struct raw_notifier_head *notifiers = &pub->notifiers;
+ void __iomem *base = pub->base0;
+ struct clk **clks = pub->clks;
const struct clk *parent;
unsigned int mult = 1;
unsigned int div = 1;
diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h
index 717fd148464f..6c8280b37c37 100644
--- a/drivers/clk/renesas/rcar-gen4-cpg.h
+++ b/drivers/clk/renesas/rcar-gen4-cpg.h
@@ -78,8 +78,7 @@ struct rcar_gen4_cpg_pll_config {
struct clk *rcar_gen4_cpg_clk_register(struct device *dev,
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers);
+ struct cpg_mssr_pub *pub);
int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config,
unsigned int clk_extalr, u32 mode);
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index da021ee446ec..d2080e326945 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -125,16 +125,14 @@ static const u16 srstclr_for_gen4[] = {
* struct cpg_mssr_priv - Clock Pulse Generator / Module Standby
* and Software Reset Private Data
*
+ * @pub: Data passed to clock registration callback
* @rcdev: Optional reset controller entity
* @dev: CPG/MSSR device
- * @base: CPG/MSSR register block base address
* @reg_layout: CPG/MSSR register layout
- * @rmw_lock: protects RMW register accesses
* @np: Device node in DT for this CPG/MSSR module
* @num_core_clks: Number of Core Clocks in clks[]
* @num_mod_clks: Number of Module Clocks in clks[]
* @last_dt_core_clk: ID of the last Core Clock exported to DT
- * @notifiers: Notifier chain to save/restore clock state for system resume
* @status_regs: Pointer to status registers array
* @control_regs: Pointer to control registers array
* @reset_regs: Pointer to reset registers array
@@ -146,20 +144,18 @@ static const u16 srstclr_for_gen4[] = {
* @clks: Array containing all Core and Module Clocks
*/
struct cpg_mssr_priv {
+ struct cpg_mssr_pub pub;
#ifdef CONFIG_RESET_CONTROLLER
struct reset_controller_dev rcdev;
#endif
struct device *dev;
- void __iomem *base;
enum clk_reg_layout reg_layout;
- spinlock_t rmw_lock;
struct device_node *np;
unsigned int num_core_clks;
unsigned int num_mod_clks;
unsigned int last_dt_core_clk;
- struct raw_notifier_head notifiers;
const u16 *status_regs;
const u16 *control_regs;
const u16 *reset_regs;
@@ -205,38 +201,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
enable ? "ON" : "OFF");
- spin_lock_irqsave(&priv->rmw_lock, flags);
+ spin_lock_irqsave(&priv->pub.rmw_lock, flags);
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
- value = readb(priv->base + priv->control_regs[reg]);
+ value = readb(priv->pub.base0 + priv->control_regs[reg]);
if (enable)
value &= ~bitmask;
else
value |= bitmask;
- writeb(value, priv->base + priv->control_regs[reg]);
+ writeb(value, priv->pub.base0 + priv->control_regs[reg]);
/* dummy read to ensure write has completed */
- readb(priv->base + priv->control_regs[reg]);
- barrier_data(priv->base + priv->control_regs[reg]);
+ readb(priv->pub.base0 + priv->control_regs[reg]);
+ barrier_data(priv->pub.base0 + priv->control_regs[reg]);
+
} else {
- value = readl(priv->base + priv->control_regs[reg]);
+ value = readl(priv->pub.base0 + priv->control_regs[reg]);
if (enable)
value &= ~bitmask;
else
value |= bitmask;
- writel(value, priv->base + priv->control_regs[reg]);
+ writel(value, priv->pub.base0 + priv->control_regs[reg]);
}
- spin_unlock_irqrestore(&priv->rmw_lock, flags);
+ spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
return 0;
- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
+ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
value, !(value & bitmask), 0, 10);
if (error)
dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
- priv->base + priv->control_regs[reg], bit);
+ priv->pub.base0 + priv->control_regs[reg], bit);
return error;
}
@@ -255,12 +252,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
{
struct mstp_clock *clock = to_mstp_clock(hw);
struct cpg_mssr_priv *priv = clock->priv;
+ unsigned int reg = clock->index / 32;
u32 value;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
- value = readb(priv->base + priv->control_regs[clock->index / 32]);
+ value = readb(priv->pub.base0 + priv->control_regs[reg]);
else
- value = readl(priv->base + priv->status_regs[clock->index / 32]);
+ value = readl(priv->pub.base0 + priv->status_regs[reg]);
return !(value & BIT(clock->index % 32));
}
@@ -347,7 +345,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
case CLK_TYPE_DIV6P1:
case CLK_TYPE_DIV6_RO:
WARN_DEBUG(core->parent >= priv->num_core_clks);
- parent = priv->clks[core->parent];
+ parent = priv->pub.clks[core->parent];
if (IS_ERR(parent)) {
clk = parent;
goto fail;
@@ -357,12 +355,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
if (core->type == CLK_TYPE_DIV6_RO)
/* Multiply with the DIV6 register value */
- div *= (readl(priv->base + core->offset) & 0x3f) + 1;
+ div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1;
if (core->type == CLK_TYPE_DIV6P1) {
clk = cpg_div6_register(core->name, 1, &parent_name,
- priv->base + core->offset,
- &priv->notifiers);
+ priv->pub.base0 + core->offset,
+ &priv->pub.notifiers);
} else {
clk = clk_register_fixed_factor(NULL, core->name,
parent_name, 0,
@@ -378,8 +376,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
default:
if (info->cpg_clk_register)
clk = info->cpg_clk_register(dev, core, info,
- priv->clks, priv->base,
- &priv->notifiers);
+ &priv->pub);
else
dev_err(dev, "%s has unsupported core clock type %u\n",
core->name, core->type);
@@ -390,7 +387,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
goto fail;
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
- priv->clks[id] = clk;
+ priv->pub.clks[id] = clk;
return;
fail:
@@ -413,14 +410,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
WARN_DEBUG(id < priv->num_core_clks);
WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
- WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
+ WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT);
if (!mod->name) {
/* Skip NULLified clock */
return;
}
- parent = priv->clks[mod->parent];
+ parent = priv->pub.clks[mod->parent];
if (IS_ERR(parent)) {
clk = parent;
goto fail;
@@ -622,13 +619,13 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
/* Reset module */
- writel(bitmask, priv->base + priv->reset_regs[reg]);
+ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
udelay(35);
/* Release module from reset state */
- writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
+ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
return 0;
}
@@ -642,7 +639,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
- writel(bitmask, priv->base + priv->reset_regs[reg]);
+ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
return 0;
}
@@ -656,7 +653,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
- writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
+ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
return 0;
}
@@ -668,7 +665,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
unsigned int bit = id % 32;
u32 bitmask = BIT(bit);
- return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
+ return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask);
}
static const struct reset_control_ops cpg_mssr_reset_ops = {
@@ -894,12 +891,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
if (priv->smstpcr_saved[reg].mask)
priv->smstpcr_saved[reg].val =
priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
- readb(priv->base + priv->control_regs[reg]) :
- readl(priv->base + priv->control_regs[reg]);
+ readb(priv->pub.base0 + priv->control_regs[reg]) :
+ readl(priv->pub.base0 + priv->control_regs[reg]);
}
/* Save core clocks */
- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
+ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL);
return 0;
}
@@ -916,7 +913,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
return 0;
/* Restore core clocks */
- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
+ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL);
/* Restore module clocks */
for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
@@ -925,29 +922,29 @@ static int cpg_mssr_resume_noirq(struct device *dev)
continue;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
- oldval = readb(priv->base + priv->control_regs[reg]);
+ oldval = readb(priv->pub.base0 + priv->control_regs[reg]);
else
- oldval = readl(priv->base + priv->control_regs[reg]);
+ oldval = readl(priv->pub.base0 + priv->control_regs[reg]);
newval = oldval & ~mask;
newval |= priv->smstpcr_saved[reg].val & mask;
if (newval == oldval)
continue;
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
- writeb(newval, priv->base + priv->control_regs[reg]);
+ writeb(newval, priv->pub.base0 + priv->control_regs[reg]);
/* dummy read to ensure write has completed */
- readb(priv->base + priv->control_regs[reg]);
- barrier_data(priv->base + priv->control_regs[reg]);
+ readb(priv->pub.base0 + priv->control_regs[reg]);
+ barrier_data(priv->pub.base0 + priv->control_regs[reg]);
continue;
} else
- writel(newval, priv->base + priv->control_regs[reg]);
+ writel(newval, priv->pub.base0 + priv->control_regs[reg]);
/* Wait until enabled clocks are really enabled */
mask &= ~priv->smstpcr_saved[reg].val;
if (!mask)
continue;
- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
+ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
oldval, !(oldval & mask), 0, 10);
if (error)
dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
@@ -1057,12 +1054,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
if (!priv)
return -ENOMEM;
+ priv->pub.clks = priv->clks;
priv->np = np;
priv->dev = dev;
- spin_lock_init(&priv->rmw_lock);
+ spin_lock_init(&priv->pub.rmw_lock);
- priv->base = of_iomap(np, 0);
- if (!priv->base) {
+ priv->pub.base0 = of_iomap(np, 0);
+ if (!priv->pub.base0) {
error = -ENOMEM;
goto out_err;
}
@@ -1070,7 +1068,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
priv->num_core_clks = info->num_total_core_clks;
priv->num_mod_clks = info->num_hw_mod_clks;
priv->last_dt_core_clk = info->last_dt_core_clk;
- RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
+ RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers);
priv->reg_layout = info->reg_layout;
if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
priv->status_regs = mstpsr;
@@ -1090,7 +1088,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
}
for (i = 0; i < nclks; i++)
- priv->clks[i] = ERR_PTR(-ENOENT);
+ priv->pub.clks[i] = ERR_PTR(-ENOENT);
error = cpg_mssr_reserved_init(priv, info);
if (error)
@@ -1107,8 +1105,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
reserve_err:
cpg_mssr_reserved_exit(priv);
out_err:
- if (priv->base)
- iounmap(priv->base);
+ if (priv->pub.base0)
+ iounmap(priv->pub.base0);
kfree(priv);
return error;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index a1d6e0cbcff9..7ce3cc9a64c1 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -8,6 +8,8 @@
#ifndef __CLK_RENESAS_CPG_MSSR_H__
#define __CLK_RENESAS_CPG_MSSR_H__
+#include <linux/notifier.h>
+
/*
* Definitions of CPG Core Clocks
*
@@ -29,6 +31,21 @@ struct cpg_core_clk {
unsigned int offset;
};
+/**
+ * struct cpg_mssr_pub - data shared with device-specific clk registration code
+ *
+ * @base0: CPG/MSSR register block base0 address
+ * @notifiers: Notifier chain to save/restore clock state for system resume
+ * @rmw_lock: protects RMW register accesses
+ * @clks: pointer to clocks
+ */
+struct cpg_mssr_pub {
+ void __iomem *base0;
+ struct raw_notifier_head notifiers;
+ spinlock_t rmw_lock;
+ struct clk **clks;
+};
+
enum clk_types {
/* Generic */
CLK_TYPE_IN, /* External Clock Input */
@@ -153,8 +170,7 @@ struct cpg_mssr_info {
struct clk *(*cpg_clk_register)(struct device *dev,
const struct cpg_core_clk *core,
const struct cpg_mssr_info *info,
- struct clk **clks, void __iomem *base,
- struct raw_notifier_head *notifiers);
+ struct cpg_mssr_pub *pub);
};
extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (4 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 12:09 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 07/11] serial: sh-sci: Use private port ID Thierry Bultel
` (4 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
linux-kernel, linux-clk
RZ/T2H has 2 register blocks at different addresses.
The clock tree has configurable dividers and mux selectors.
Add these new clock types, new register layout type, and
registration code for mux and div in registration callback.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- Makefile: keep ordered list
- r9a09g077-cpg-mssr.c: use high bit instead of sel_base,
same macro for DIV and MUX
- removed unused clocks
- CLK_LOCO is internal with a DEF_RATE definition
- added CLK_PLL4D1 & CLK_SCI0ASYNC
- added per-CA55 clocks
- added missing error check in r9a09g077_cpg_mux_clk_register
- fixed num_hw_mod_clks to 14
- added missing 2 holes in mstpcr_for_rzt2h
- renamed cpg_read_rzt2h_mstp_from_offset to cpg_read_rzt2h_mstp,
directly reads at calculated address
- added cpg_write_rzt2h_mstp and call in cpg_mstp_clock_endisable
- do not register reset controller in case of CLK_REG_LAYOUT_RZ_T2H
- moved CLK_DIV & CLK_MUX definitions to RZT2H specifics
Changes v6->v7: none
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4:
- Add missing #include <bitfield.h> (reported by bot)
- Add missing __iomem address space in cpg_rzt2h_addr_from_offset and
return type (reported by bot)
- fixed clocks: inverted 'mult' and 'div' parameters when using
the DEF_FIXED macro
---
drivers/clk/renesas/Kconfig | 5 +
drivers/clk/renesas/Makefile | 1 +
drivers/clk/renesas/r9a09g077-cpg-mssr.c | 252 +++++++++++++++++++++++
drivers/clk/renesas/renesas-cpg-mssr.c | 90 +++++++-
drivers/clk/renesas/renesas-cpg-mssr.h | 12 ++
5 files changed, 358 insertions(+), 2 deletions(-)
create mode 100644 drivers/clk/renesas/r9a09g077-cpg-mssr.c
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 5a4bc3f94d49..3f9c4deb4c25 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -42,6 +42,7 @@ config CLK_RENESAS
select CLK_R9A09G011 if ARCH_R9A09G011
select CLK_R9A09G047 if ARCH_R9A09G047
select CLK_R9A09G057 if ARCH_R9A09G057
+ select CLK_R9A09G077 if ARCH_R9A09G077
select CLK_SH73A0 if ARCH_SH73A0
if CLK_RENESAS
@@ -203,6 +204,10 @@ config CLK_R9A09G057
bool "RZ/V2H(P) clock support" if COMPILE_TEST
select CLK_RZV2H
+config CLK_R9A09G077
+ bool "RZ/T2H clock support" if COMPILE_TEST
+ select CLK_RENESAS_CPG_MSSR
+
config CLK_SH73A0
bool "SH-Mobile AG5 clock support" if COMPILE_TEST
select CLK_RENESAS_CPG_MSTP
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index 2d6e746939c4..e9d66dec2ca7 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_CLK_R9A08G045) += r9a08g045-cpg.o
obj-$(CONFIG_CLK_R9A09G011) += r9a09g011-cpg.o
obj-$(CONFIG_CLK_R9A09G047) += r9a09g047-cpg.o
obj-$(CONFIG_CLK_R9A09G057) += r9a09g057-cpg.o
+obj-$(CONFIG_CLK_R9A09G077) += r9a09g077-cpg-mssr.o
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
# Family
diff --git a/drivers/clk/renesas/r9a09g077-cpg-mssr.c b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
new file mode 100644
index 000000000000..029619a6cb19
--- /dev/null
+++ b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r9a09g077 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
+#include "renesas-cpg-mssr.h"
+
+#define RZT2H_REG_BLOCK_SHIFT 11
+#define RZT2H_REG_OFFSET_MASK GENMASK(10, 0)
+#define RZT2H_REG_CONF(block, offset) (((block) << RZT2H_REG_BLOCK_SHIFT) | \
+ ((offset) & RZT2H_REG_OFFSET_MASK))
+
+#define RZT2H_REG_BLOCK(x) ((x) >> RZT2H_REG_BLOCK_SHIFT)
+#define RZT2H_REG_OFFSET(x) ((x) & RZT2H_REG_OFFSET_MASK)
+
+#define SCKCR RZT2H_REG_CONF(0, 0x00)
+#define SCKCR2 RZT2H_REG_CONF(1, 0x04)
+#define SCKCR3 RZT2H_REG_CONF(0, 0x08)
+
+#define OFFSET_MASK GENMASK(31, 20)
+#define SHIFT_MASK GENMASK(19, 12)
+#define WIDTH_MASK GENMASK(11, 8)
+
+#define CONF_PACK(offset, shift, width) \
+ (FIELD_PREP_CONST(OFFSET_MASK, (offset)) | \
+ FIELD_PREP_CONST(SHIFT_MASK, (shift)) | \
+ FIELD_PREP_CONST(WIDTH_MASK, (width)))
+
+#define GET_SHIFT(val) FIELD_GET(SHIFT_MASK, val)
+#define GET_WIDTH(val) FIELD_GET(WIDTH_MASK, val)
+#define GET_REG_OFFSET(val) FIELD_GET(OFFSET_MASK, val)
+
+#define DIVCA55C0 CONF_PACK(SCKCR2, 8, 1)
+#define DIVCA55C1 CONF_PACK(SCKCR2, 9, 1)
+#define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1)
+#define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1)
+#define DIVCA55S CONF_PACK(SCKCR2, 12, 1)
+
+#define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 1)
+
+#define SEL_PLL CONF_PACK(SCKCR, 22, 1)
+
+
+enum rzt2h_clk_types {
+ CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */
+ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */
+};
+
+#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
+ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_DIV, .conf = _conf, \
+ .parent = _parent, .dtable = _dtable, .flag = _flag)
+#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \
+ _mux_flags) \
+ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_MUX, .conf = _conf, \
+ .parent_names = _parent_names, .num_parents = _num_parents, \
+ .flag = _flag, .mux_flags = _mux_flags)
+
+enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R9A09G077_CLK_PCLKM,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+
+ /* Internal Core Clocks */
+ CLK_LOCO,
+ CLK_MAIN,
+ CLK_PLL0,
+ CLK_PLL1,
+ CLK_PLL4,
+ CLK_SEL_PLL0,
+ CLK_SEL_CLK_PLL0,
+ CLK_SEL_PLL1,
+ CLK_SEL_CLK_PLL1,
+ CLK_SEL_PLL4,
+ CLK_SEL_CLK_PLL4,
+ CLK_PLL4D1,
+ CLK_SCI0ASYNC,
+
+ /* Module Clocks */
+ MOD_CLK_BASE,
+};
+
+static const struct clk_div_table dtable_1_2[] = {
+ {0, 2},
+ {1, 1},
+ {0, 0},
+};
+
+static const struct clk_div_table dtable_24_25_30_32[] = {
+ {0, 24},
+ {0, 25},
+ {0, 30},
+ {0, 32},
+ {0, 0},
+};
+
+/* Mux clock tables */
+
+static const char * const sel_clk_pll0[] = { "loco", ".sel_pll0" };
+static const char * const sel_clk_pll1[] = { "loco", ".sel_pll1" };
+static const char * const sel_clk_pll4[] = { "loco", ".sel_pll4" };
+
+static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+
+ /* Internal Core Clocks */
+ DEF_RATE("loco", CLK_LOCO, 1000 * 1000),
+ DEF_FIXED(".pll0", CLK_PLL0, CLK_EXTAL, 1, 48),
+ DEF_FIXED(".pll1", CLK_PLL1, CLK_EXTAL, 1, 40),
+ DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 1, 96),
+ /* unimplemented CLMA0 selector */
+ DEF_FIXED(".sel_pll0", CLK_SEL_PLL0, CLK_PLL0, 1, 1),
+ DEF_MUX(".sel_clk_pll0", CLK_SEL_CLK_PLL0, SEL_PLL,
+ sel_clk_pll0, ARRAY_SIZE(sel_clk_pll0), 0, CLK_MUX_READ_ONLY),
+ /* unimplemented CLMA1 selector */
+ DEF_FIXED(".sel_pll1", CLK_SEL_PLL1, CLK_PLL1, 1, 1),
+ DEF_MUX(".sel_clk_pll1", CLK_SEL_CLK_PLL1, SEL_PLL,
+ sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), 0, CLK_MUX_READ_ONLY),
+ /* unimplemented CLMA4 selector */
+ DEF_FIXED(".sel_pll4", CLK_SEL_PLL4, CLK_PLL4, 1, 1),
+ DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL,
+ sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), 0, CLK_MUX_READ_ONLY),
+
+ DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1),
+ DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC,
+ dtable_24_25_30_32, CLK_DIVIDER_HIWORD_MASK),
+
+ /* Core output clk */
+ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0,
+ dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("CA55C1", R9A09G077_CLK_CA55C1, CLK_SEL_CLK_PLL0, DIVCA55C1,
+ dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("CA55C2", R9A09G077_CLK_CA55C2, CLK_SEL_CLK_PLL0, DIVCA55C2,
+ dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("CA55C3", R9A09G077_CLK_CA55C3, CLK_SEL_CLK_PLL0, DIVCA55C3,
+ dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
+ DEF_DIV("CA55S", R9A09G077_CLK_CA55S, CLK_SEL_CLK_PLL0, DIVCA55S,
+ dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
+ DEF_FIXED("PCLKGPTL", R9A09G077_CLK_PCLKGPTL, CLK_SEL_CLK_PLL1, 2, 1),
+ DEF_FIXED("PCLKM", R9A09G077_CLK_PCLKM, CLK_SEL_CLK_PLL1, 8, 1),
+};
+
+static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
+ DEF_MOD("sci0fck", R9A09G077_PCLK_SCI0, CLK_SCI0ASYNC),
+};
+
+static struct clk * __init
+r9a09g077_cpg_div_clk_register(struct device *dev,
+ const struct cpg_core_clk *core,
+ void __iomem *addr, struct cpg_mssr_pub *pub)
+{
+ const struct clk *parent;
+ const char *parent_name;
+ struct clk_hw *clk_hw;
+
+ parent = pub->clks[core->parent];
+
+ if (IS_ERR(parent))
+ return ERR_CAST(parent);
+
+ parent_name = __clk_get_name(parent);
+
+ if (core->dtable)
+ clk_hw = clk_hw_register_divider_table(dev, core->name,
+ parent_name, 0,
+ addr,
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->flag,
+ core->dtable,
+ &pub->rmw_lock);
+ else
+ clk_hw = clk_hw_register_divider(dev, core->name,
+ parent_name, 0,
+ addr,
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->flag, &pub->rmw_lock);
+
+ if (IS_ERR(clk_hw))
+ return ERR_CAST(clk_hw);
+
+ return clk_hw->clk;
+
+}
+
+static struct clk * __init
+r9a09g077_cpg_mux_clk_register(struct device *dev,
+ const struct cpg_core_clk *core,
+ void __iomem *addr, struct cpg_mssr_pub *pub)
+{
+ struct clk_hw *clk_hw;
+
+ clk_hw = devm_clk_hw_register_mux(dev, core->name,
+ core->parent_names, core->num_parents,
+ core->flag,
+ addr,
+ GET_SHIFT(core->conf),
+ GET_WIDTH(core->conf),
+ core->mux_flags, &pub->rmw_lock);
+ if (IS_ERR(clk_hw))
+ return ERR_CAST(clk_hw);
+
+ return clk_hw->clk;
+}
+
+static struct clk * __init
+r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core,
+ const struct cpg_mssr_info *info,
+ struct cpg_mssr_pub *pub)
+{
+ u32 offset = GET_REG_OFFSET(core->conf);
+ void __iomem *base = RZT2H_REG_BLOCK(offset) ? pub->base1 : pub->base0;
+ void __iomem *addr = base + offset;
+
+ switch (core->type) {
+ case CLK_TYPE_RZT2H_DIV:
+ return r9a09g077_cpg_div_clk_register(dev, core, addr, pub);
+ case CLK_TYPE_RZT2H_MUX:
+ return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub);
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+}
+
+const struct cpg_mssr_info r9a09g077_cpg_mssr_info = {
+ /* Core Clocks */
+ .core_clks = r9a09g077_core_clks,
+ .num_core_clks = ARRAY_SIZE(r9a09g077_core_clks),
+ .last_dt_core_clk = LAST_DT_CORE_CLK,
+ .num_total_core_clks = MOD_CLK_BASE,
+
+ /* Module Clocks */
+ .mod_clks = r9a09g077_mod_clks,
+ .num_mod_clks = ARRAY_SIZE(r9a09g077_mod_clks),
+ .num_hw_mod_clks = 14 * 32,
+
+ .reg_layout = CLK_REG_LAYOUT_RZ_T2H,
+ .cpg_clk_register = r9a09g077_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index d2080e326945..d10d33a1bb76 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -79,6 +79,37 @@ static const u16 mstpcr_for_gen4[] = {
0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74,
};
+/*
+ * Module Stop Control Register (RZ/T2H)
+ * RZ/T2H has 2 registers blocks,
+ * Bit 12 is used to differentiate them
+ */
+
+#define RZT2H_MSTPCR_BLOCK_SHIFT 12
+#define RZT2H_MSTPCR_OFFSET_MASK GENMASK(11, 0)
+#define RZT2H_MSTPCR(block, offset) (((block) << RZT2H_MSTPCR_BLOCK_SHIFT) | \
+ ((offset) & RZT2H_MSTPCR_OFFSET_MASK))
+
+#define RZT2H_MSTPCR_BLOCK(x) ((x) >> RZT2H_MSTPCR_BLOCK_SHIFT)
+#define RZT2H_MSTPCR_OFFSET(x) ((x) & RZT2H_MSTPCR_OFFSET_MASK)
+
+static const u16 mstpcr_for_rzt2h[] = {
+ RZT2H_MSTPCR(0, 0x300), /* MSTPCRA */
+ RZT2H_MSTPCR(0, 0x304), /* MSTPCRB */
+ RZT2H_MSTPCR(0, 0x308), /* MSTPCRC */
+ RZT2H_MSTPCR(0, 0x30c), /* MSTPCRD */
+ RZT2H_MSTPCR(0, 0x310), /* MSTPCRE */
+ 0,
+ RZT2H_MSTPCR(1, 0x318), /* MSTPCRG */
+ 0,
+ RZT2H_MSTPCR(1, 0x320), /* MSTPCRI */
+ RZT2H_MSTPCR(0, 0x324), /* MSTPCRJ */
+ RZT2H_MSTPCR(0, 0x328), /* MSTPCRK */
+ RZT2H_MSTPCR(0, 0x32c), /* MSTPCRL */
+ RZT2H_MSTPCR(0, 0x330), /* MSTPCRM */
+ RZT2H_MSTPCR(1, 0x334), /* MSTPCRN */
+};
+
/*
* Standby Control Register offsets (RZ/A)
* Base address is FRQCR register
@@ -187,6 +218,26 @@ struct mstp_clock {
#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+static u32 cpg_read_rzt2h_mstp(struct clk_hw *hw, u16 offset)
+{
+ struct mstp_clock *clock = to_mstp_clock(hw);
+ struct cpg_mssr_priv *priv = clock->priv;
+ void __iomem *base =
+ RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0;
+
+ return readl(base + RZT2H_MSTPCR_OFFSET(offset));
+}
+
+static void cpg_write_rzt2h_mstp(struct clk_hw *hw, u16 offset, u32 value)
+{
+ struct mstp_clock *clock = to_mstp_clock(hw);
+ struct cpg_mssr_priv *priv = clock->priv;
+ void __iomem *base =
+ RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0;
+
+ writel(value, base + RZT2H_MSTPCR_OFFSET(offset));
+}
+
static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
{
struct mstp_clock *clock = to_mstp_clock(hw);
@@ -215,6 +266,19 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
readb(priv->pub.base0 + priv->control_regs[reg]);
barrier_data(priv->pub.base0 + priv->control_regs[reg]);
+ } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+ pr_info("RZTH2 case");
+ value = cpg_read_rzt2h_mstp(hw,
+ priv->control_regs[reg]);
+
+ if (enable)
+ value &= ~bitmask;
+ else
+ value |= bitmask;
+
+ cpg_write_rzt2h_mstp(hw,
+ priv->control_regs[reg],
+ value);
} else {
value = readl(priv->pub.base0 + priv->control_regs[reg]);
if (enable)
@@ -226,7 +290,8 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
- if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
+ if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
+ priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
return 0;
error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
@@ -257,6 +322,9 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
value = readb(priv->pub.base0 + priv->control_regs[reg]);
+ else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
+ value = cpg_read_rzt2h_mstp(hw,
+ priv->control_regs[reg]);
else
value = readl(priv->pub.base0 + priv->status_regs[reg]);
@@ -867,6 +935,12 @@ static const struct of_device_id cpg_mssr_match[] = {
.compatible = "renesas,r8a779h0-cpg-mssr",
.data = &r8a779h0_cpg_mssr_info,
},
+#endif
+#ifdef CONFIG_CLK_R9A09G077
+ {
+ .compatible = "renesas,r9a09g077-cpg-mssr",
+ .data = &r9a09g077_cpg_mssr_info,
+ },
#endif
{ /* sentinel */ }
};
@@ -1064,6 +1138,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
error = -ENOMEM;
goto out_err;
}
+ if (info->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+ priv->pub.base1 = of_iomap(np, 1);
+ if (!priv->pub.base1) {
+ error = -ENOMEM;
+ goto out_err;
+ }
+ }
priv->num_core_clks = info->num_total_core_clks;
priv->num_mod_clks = info->num_hw_mod_clks;
@@ -1077,6 +1158,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
priv->reset_clear_regs = srstclr;
} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
priv->control_regs = stbcr;
+ } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
+ priv->control_regs = mstpcr_for_rzt2h;
} else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
priv->status_regs = mstpsr_for_gen4;
priv->control_regs = mstpcr_for_gen4;
@@ -1107,6 +1190,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
out_err:
if (priv->pub.base0)
iounmap(priv->pub.base0);
+ if (priv->pub.base1)
+ iounmap(priv->pub.base1);
kfree(priv);
return error;
@@ -1171,7 +1256,8 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
goto reserve_exit;
/* Reset Controller not supported for Standby Control SoCs */
- if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
+ if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
+ priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
goto reserve_exit;
error = cpg_mssr_reset_controller_register(priv);
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index 7ce3cc9a64c1..2801d6bf2f6d 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -22,6 +22,10 @@
struct cpg_core_clk {
/* Common */
const char *name;
+ union {
+ const char * const *parent_names;
+ const struct clk_div_table *dtable;
+ };
unsigned int id;
unsigned int type;
/* Depending on type */
@@ -29,18 +33,24 @@ struct cpg_core_clk {
unsigned int div;
unsigned int mult;
unsigned int offset;
+ u32 conf;
+ u16 flag;
+ u8 mux_flags;
+ u8 num_parents;
};
/**
* struct cpg_mssr_pub - data shared with device-specific clk registration code
*
* @base0: CPG/MSSR register block base0 address
+ * @base1: CPG/MSSR register block base1 address
* @notifiers: Notifier chain to save/restore clock state for system resume
* @rmw_lock: protects RMW register accesses
* @clks: pointer to clocks
*/
struct cpg_mssr_pub {
void __iomem *base0;
+ void __iomem *base1;
struct raw_notifier_head notifiers;
spinlock_t rmw_lock;
struct clk **clks;
@@ -106,6 +116,7 @@ enum clk_reg_layout {
CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
CLK_REG_LAYOUT_RZ_A,
CLK_REG_LAYOUT_RCAR_GEN4,
+ CLK_REG_LAYOUT_RZ_T2H,
};
/**
@@ -197,6 +208,7 @@ extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779g0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779h0_cpg_mssr_info;
+extern const struct cpg_mssr_info r9a09g077_cpg_mssr_info;
void __init cpg_mssr_early_init(struct device_node *np,
const struct cpg_mssr_info *info);
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 07/11] serial: sh-sci: Use private port ID
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (5 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 12:59 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
` (3 subsequent siblings)
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
linux-kernel, linux-serial
From: Thierry Bultel <thierry.bultel@linatsea.fr>
New port types cannot be added in serial_core.h, which is shared with
userspace.
In order to support new port types, the coming new ones will have
BIT(15) set in the id value, and in this case, uartport->type is
set to PORT_GENERIC.
This commit therefore changes all the places where the port type is
read, by not relying on uartport->type but on the private
value stored in struct sci_port.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
drivers/tty/serial/sh-sci-common.h | 3 +
drivers/tty/serial/sh-sci.c | 157 ++++++++++++++++-------------
2 files changed, 90 insertions(+), 70 deletions(-)
diff --git a/drivers/tty/serial/sh-sci-common.h b/drivers/tty/serial/sh-sci-common.h
index bd9d9cfac1c8..de9796595cfd 100644
--- a/drivers/tty/serial/sh-sci-common.h
+++ b/drivers/tty/serial/sh-sci-common.h
@@ -142,6 +142,9 @@ struct sci_port {
int rx_fifo_timeout;
u16 hscif_tot;
+ unsigned int type;
+ unsigned int regtype;
+
const struct sci_port_ops *ops;
bool has_rtscts;
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ff1986dc6af3..2abf80230a77 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -75,6 +75,8 @@
#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
+#define SCI_PUBLIC_PORT_ID(port) (!((port) & BIT(15)) ? (port) : PORT_GENERIC)
+
static struct sci_port sci_ports[SCI_NPORTS];
static unsigned long sci_ports_in_use;
static struct uart_driver sci_uart_driver;
@@ -580,7 +582,7 @@ static void sci_start_tx(struct uart_port *port)
unsigned short ctrl;
#ifdef CONFIG_SERIAL_SH_SCI_DMA
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
u16 new, scr = sci_serial_in(port, SCSCR);
if (s->chan_tx)
new = scr | SCSCR_TDRQE;
@@ -592,7 +594,7 @@ static void sci_start_tx(struct uart_port *port)
if (s->chan_tx && !kfifo_is_empty(&port->state->port.xmit_fifo) &&
dma_submit_error(s->cookie_tx)) {
- if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+ if (s->regtype == SCIx_RZ_SCIFA_REGTYPE)
/* Switch irq from SCIF to DMA */
disable_irq_nosync(s->irqs[SCIx_TXI_IRQ]);
@@ -601,8 +603,8 @@ static void sci_start_tx(struct uart_port *port)
}
#endif
- if (!s->chan_tx || s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE ||
- port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (!s->chan_tx || s->regtype == SCIx_RZ_SCIFA_REGTYPE ||
+ s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_serial_in(port, SCSCR);
@@ -611,7 +613,7 @@ static void sci_start_tx(struct uart_port *port)
* (transmit interrupt enable) or in the same instruction to start
* the transmit process.
*/
- if (port->type == PORT_SCI)
+ if (s->type == PORT_SCI)
ctrl |= SCSCR_TE;
sci_serial_out(port, SCSCR, ctrl | SCSCR_TIE);
@@ -620,12 +622,13 @@ static void sci_start_tx(struct uart_port *port)
static void sci_stop_tx(struct uart_port *port)
{
+ struct sci_port *s = to_sci_port(port);
unsigned short ctrl;
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_serial_in(port, SCSCR);
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB)
ctrl &= ~SCSCR_TDRQE;
ctrl &= ~SCSCR_TIE;
@@ -633,21 +636,22 @@ static void sci_stop_tx(struct uart_port *port)
sci_serial_out(port, SCSCR, ctrl);
#ifdef CONFIG_SERIAL_SH_SCI_DMA
- if (to_sci_port(port)->chan_tx &&
- !dma_submit_error(to_sci_port(port)->cookie_tx)) {
- dmaengine_terminate_async(to_sci_port(port)->chan_tx);
- to_sci_port(port)->cookie_tx = -EINVAL;
+ if (s->chan_tx &&
+ !dma_submit_error(s->cookie_tx)) {
+ dmaengine_terminate_async(s->chan_tx);
+ s->cookie_tx = -EINVAL;
}
#endif
}
static void sci_start_rx(struct uart_port *port)
{
+ struct sci_port *s = to_sci_port(port);
unsigned short ctrl;
ctrl = sci_serial_in(port, SCSCR) | port_rx_irq_mask(port);
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB)
ctrl &= ~SCSCR_RDRQE;
sci_serial_out(port, SCSCR, ctrl);
@@ -655,11 +659,12 @@ static void sci_start_rx(struct uart_port *port)
static void sci_stop_rx(struct uart_port *port)
{
+ struct sci_port *s = to_sci_port(port);
unsigned short ctrl;
ctrl = sci_serial_in(port, SCSCR);
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB)
ctrl &= ~SCSCR_RDRQE;
ctrl &= ~port_rx_irq_mask(port);
@@ -669,10 +674,12 @@ static void sci_stop_rx(struct uart_port *port)
static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask)
{
- if (port->type == PORT_SCI) {
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->type == PORT_SCI) {
/* Just store the mask */
sci_serial_out(port, SCxSR, mask);
- } else if (to_sci_port(port)->params->overrun_mask == SCIFA_ORER) {
+ } else if (s->params->overrun_mask == SCIFA_ORER) {
/* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */
/* Only clear the status bits we want to clear */
sci_serial_out(port, SCxSR, sci_serial_in(port, SCxSR) & mask);
@@ -742,13 +749,13 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
return;
}
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
u16 data = sci_serial_in(port, SCPDR);
u16 ctrl = sci_serial_in(port, SCPCR);
/* Enable RXD and TXD pin functions */
ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC);
- if (to_sci_port(port)->has_rtscts) {
+ if (s->has_rtscts) {
/* RTS# is output, active low, unless autorts */
if (!(port->mctrl & TIOCM_RTS)) {
ctrl |= SCPCR_RTSC;
@@ -765,7 +772,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
}
sci_serial_out(port, SCPDR, data);
sci_serial_out(port, SCPCR, ctrl);
- } else if (sci_getreg(port, SCSPTR)->size && s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE) {
+ } else if (sci_getreg(port, SCSPTR)->size && s->regtype != SCIx_RZV2H_SCIF_REGTYPE) {
u16 status = sci_serial_in(port, SCSPTR);
/* RTS# is always output; and active low, unless autorts */
@@ -852,7 +859,7 @@ static void sci_transmit_chars(struct uart_port *port)
c = port->x_char;
port->x_char = 0;
} else if (stopped || !kfifo_get(&tport->xmit_fifo, &c)) {
- if (port->type == PORT_SCI &&
+ if (s->type == PORT_SCI &&
kfifo_is_empty(&tport->xmit_fifo)) {
ctrl = sci_serial_in(port, SCSCR);
ctrl &= ~SCSCR_TE;
@@ -873,7 +880,7 @@ static void sci_transmit_chars(struct uart_port *port)
if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (kfifo_is_empty(&tport->xmit_fifo)) {
- if (port->type == PORT_SCI) {
+ if (s->type == PORT_SCI) {
ctrl = sci_serial_in(port, SCSCR);
ctrl &= ~SCSCR_TIE;
ctrl |= SCSCR_TEIE;
@@ -904,7 +911,7 @@ static void sci_receive_chars(struct uart_port *port)
if (count == 0)
break;
- if (port->type == PORT_SCI) {
+ if (s->type == PORT_SCI) {
char c = sci_serial_in(port, SCxRDR);
if (uart_handle_sysrq_char(port, c))
count = 0;
@@ -914,8 +921,8 @@ static void sci_receive_chars(struct uart_port *port)
for (i = 0; i < count; i++) {
char c;
- if (port->type == PORT_SCIF ||
- port->type == PORT_HSCIF) {
+ if (s->type == PORT_SCIF ||
+ s->type == PORT_HSCIF) {
status = sci_serial_in(port, SCxSR);
c = sci_serial_in(port, SCxRDR);
} else {
@@ -1052,6 +1059,7 @@ static int sci_handle_breaks(struct uart_port *port)
static int scif_set_rtrg(struct uart_port *port, int rx_trig)
{
+ struct sci_port *s = to_sci_port(port);
unsigned int bits;
if (rx_trig >= port->fifosize)
@@ -1065,7 +1073,7 @@ static int scif_set_rtrg(struct uart_port *port, int rx_trig)
return rx_trig;
}
- switch (port->type) {
+ switch (s->type) {
case PORT_SCIF:
if (rx_trig < 4) {
bits = 0;
@@ -1150,7 +1158,7 @@ static ssize_t rx_fifo_trigger_store(struct device *dev,
return ret;
sci->rx_trigger = sci->ops->set_rtrg(port, r);
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+ if (sci->type == PORT_SCIFA || sci->type == PORT_SCIFB)
sci->ops->set_rtrg(port, 1);
return count;
@@ -1166,7 +1174,7 @@ static ssize_t rx_fifo_timeout_show(struct device *dev,
struct sci_port *sci = to_sci_port(port);
int v;
- if (port->type == PORT_HSCIF)
+ if (sci->type == PORT_HSCIF)
v = sci->hscif_tot >> HSSCR_TOT_SHIFT;
else
v = sci->rx_fifo_timeout;
@@ -1188,7 +1196,7 @@ static ssize_t rx_fifo_timeout_store(struct device *dev,
if (ret)
return ret;
- if (port->type == PORT_HSCIF) {
+ if (sci->type == PORT_HSCIF) {
if (r < 0 || r > 3)
return -EINVAL;
sci->hscif_tot = r << HSSCR_TOT_SHIFT;
@@ -1229,11 +1237,11 @@ static void sci_dma_tx_complete(void *arg)
schedule_work(&s->work_tx);
} else {
s->cookie_tx = -EINVAL;
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
- s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB ||
+ s->regtype == SCIx_RZ_SCIFA_REGTYPE) {
u16 ctrl = sci_serial_in(port, SCSCR);
sci_serial_out(port, SCSCR, ctrl & ~SCSCR_TIE);
- if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ if (s->regtype == SCIx_RZ_SCIFA_REGTYPE) {
/* Switch irq from DMA to SCIF */
dmaengine_pause(s->chan_tx_saved);
enable_irq(s->irqs[SCIx_TXI_IRQ]);
@@ -1315,10 +1323,10 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
/* Direct new serial port interrupts back to CPU */
scr = sci_serial_in(port, SCSCR);
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
- s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB ||
+ s->regtype == SCIx_RZ_SCIFA_REGTYPE) {
enable_irq(s->irqs[SCIx_RXI_IRQ]);
- if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+ if (s->regtype == SCIx_RZ_SCIFA_REGTYPE)
s->ops->set_rtrg(port, s->rx_trigger);
else
scr &= ~SCSCR_RDRQE;
@@ -1558,8 +1566,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
tty_flip_buffer_push(&port->state->port);
}
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
- s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB ||
+ s->regtype == SCIx_RZ_SCIFA_REGTYPE)
sci_dma_rx_submit(s, true);
sci_dma_rx_reenable_irq(s);
@@ -1682,8 +1690,8 @@ static void sci_request_dma(struct uart_port *port)
s->chan_rx_saved = s->chan_rx = chan;
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
- s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB ||
+ s->regtype == SCIx_RZ_SCIFA_REGTYPE)
sci_dma_rx_submit(s, false);
}
}
@@ -1753,10 +1761,10 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
u16 ssr = sci_serial_in(port, SCxSR);
/* Disable future Rx interrupts */
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
- s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB ||
+ s->regtype == SCIx_RZ_SCIFA_REGTYPE) {
disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
- if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ if (s->regtype == SCIx_RZ_SCIFA_REGTYPE) {
s->ops->set_rtrg(port, 1);
scr |= SCSCR_RIE;
} else {
@@ -1820,7 +1828,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
unsigned long flags;
u32 ctrl;
- if (port->type != PORT_SCI)
+ if (s->type != PORT_SCI)
return sci_tx_interrupt(irq, ptr);
uart_port_lock_irqsave(port, &flags);
@@ -1867,7 +1875,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
}
/* Handle errors */
- if (port->type == PORT_SCI) {
+ if (s->type == PORT_SCI) {
if (sci_handle_errors(port)) {
/* discard character in rx buffer */
sci_serial_in(port, SCxSR);
@@ -2091,7 +2099,9 @@ static unsigned int sci_tx_empty(struct uart_port *port)
static void sci_set_rts(struct uart_port *port, bool state)
{
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
u16 data = sci_serial_in(port, SCPDR);
/* Active low */
@@ -2118,7 +2128,9 @@ static void sci_set_rts(struct uart_port *port, bool state)
static bool sci_get_cts(struct uart_port *port)
{
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
/* Active low */
return !(sci_serial_in(port, SCPDR) & SCPDR_CTSD);
} else if (sci_getreg(port, SCSPTR)->size) {
@@ -2164,21 +2176,21 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
if (!(mctrl & TIOCM_RTS)) {
/* Disable Auto RTS */
- if (s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE)
+ if (s->regtype != SCIx_RZV2H_SCIF_REGTYPE)
sci_serial_out(port, SCFCR,
sci_serial_in(port, SCFCR) & ~SCFCR_MCE);
/* Clear RTS */
sci_set_rts(port, 0);
} else if (s->autorts) {
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB) {
/* Enable RTS# pin function */
sci_serial_out(port, SCPCR,
sci_serial_in(port, SCPCR) & ~SCPCR_RTSC);
}
/* Enable Auto RTS */
- if (s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE)
+ if (s->regtype != SCIx_RZV2H_SCIF_REGTYPE)
sci_serial_out(port, SCFCR,
sci_serial_in(port, SCFCR) | SCFCR_MCE);
} else {
@@ -2315,7 +2327,7 @@ static int sci_sck_calc(struct sci_port *s, unsigned int bps,
int err, min_err = INT_MAX;
unsigned int sr;
- if (s->port.type != PORT_HSCIF)
+ if (s->type != PORT_HSCIF)
freq *= 2;
for_each_sr(sr, s) {
@@ -2342,7 +2354,7 @@ static int sci_brg_calc(struct sci_port *s, unsigned int bps,
int err, min_err = INT_MAX;
unsigned int sr, dl;
- if (s->port.type != PORT_HSCIF)
+ if (s->type != PORT_HSCIF)
freq *= 2;
for_each_sr(sr, s) {
@@ -2375,7 +2387,7 @@ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
unsigned int sr, br, prediv, scrate, c;
int err, min_err = INT_MAX;
- if (s->port.type != PORT_HSCIF)
+ if (s->type != PORT_HSCIF)
freq *= 2;
/*
@@ -2460,8 +2472,8 @@ static void sci_reset(struct uart_port *port)
s->ops->set_rtrg(port, 1);
timer_setup(&s->rx_fifo_timer, rx_fifo_timer_fn, 0);
} else {
- if (port->type == PORT_SCIFA ||
- port->type == PORT_SCIFB)
+ if (s->type == PORT_SCIFA ||
+ s->type == PORT_SCIFB)
s->ops->set_rtrg(port, 1);
else
s->ops->set_rtrg(port, s->rx_trigger);
@@ -2521,8 +2533,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
*/
/* Optional Undivided External Clock */
- if (s->clk_rates[SCI_SCK] && port->type != PORT_SCIFA &&
- port->type != PORT_SCIFB) {
+ if (s->clk_rates[SCI_SCK] && s->type != PORT_SCIFA &&
+ s->type != PORT_SCIFB) {
err = sci_sck_calc(s, baud, &srr1);
if (abs(err) < abs(min_err)) {
best_clk = SCI_SCK;
@@ -2607,7 +2619,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
sci_serial_out(port, SEMR, 0);
if (best_clk >= 0) {
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+ if (s->type == PORT_SCIFA || s->type == PORT_SCIFB)
switch (srr + 1) {
case 5: smr_val |= SCSMR_SRC_5; break;
case 7: smr_val |= SCSMR_SRC_7; break;
@@ -2692,12 +2704,12 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
* (transmit interrupt enable) or in the same instruction to
* start the transmitting process. So skip setting TE here for SCI.
*/
- if (port->type != PORT_SCI)
+ if (s->type != PORT_SCI)
scr_val |= SCSCR_TE;
scr_val |= SCSCR_RE | (s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0));
sci_serial_out(port, SCSCR, scr_val | s->hscif_tot);
if ((srr + 1 == 5) &&
- (port->type == PORT_SCIFA || port->type == PORT_SCIFB)) {
+ (s->type == PORT_SCIFA || s->type == PORT_SCIFB)) {
/*
* In asynchronous mode, when the sampling rate is 1/5, first
* received data may become invalid on some SCIFA and SCIFB.
@@ -2741,7 +2753,9 @@ void sci_pm(struct uart_port *port, unsigned int state,
static const char *sci_type(struct uart_port *port)
{
- switch (port->type) {
+ struct sci_port *s = to_sci_port(port);
+
+ switch (s->type) {
case PORT_IRDA:
return "irda";
case PORT_SCI:
@@ -2825,8 +2839,7 @@ void sci_config_port(struct uart_port *port, int flags)
{
if (flags & UART_CONFIG_TYPE) {
struct sci_port *sport = to_sci_port(port);
-
- port->type = sport->cfg->type;
+ port->type = SCI_PUBLIC_PORT_ID(sport->type);
sci_request_port(port);
}
}
@@ -2964,7 +2977,7 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
struct clk *clk;
unsigned int i;
- if (sci_port->cfg->type == PORT_HSCIF)
+ if (sci_port->type == PORT_HSCIF)
clk_names[SCI_SCK] = "hsck";
for (i = 0; i < SCI_NUM_CLKS; i++) {
@@ -3050,6 +3063,9 @@ static int sci_init_single(struct platform_device *dev,
sci_port->cfg = p;
+ sci_port->type = p->type;
+ sci_port->regtype = p->regtype;
+
port->iotype = UPIO_MEM;
port->line = index;
port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SH_SCI_CONSOLE);
@@ -3128,11 +3144,11 @@ static int sci_init_single(struct platform_device *dev,
return ret;
}
- port->type = p->type;
+ port->type = SCI_PUBLIC_PORT_ID(p->type);
port->flags = UPF_FIXED_PORT | UPF_BOOT_AUTOCONF | p->flags;
port->fifosize = sci_port->params->fifosize;
- if (port->type == PORT_SCI && !dev->dev.of_node) {
+ if (p->type == PORT_SCI && !dev->dev.of_node) {
if (sci_port->reg_size >= 0x20)
port->regshift = 2;
else
@@ -3322,13 +3338,13 @@ static struct uart_driver sci_uart_driver = {
static void sci_remove(struct platform_device *dev)
{
- struct sci_port *port = platform_get_drvdata(dev);
- unsigned int type = port->port.type; /* uart_remove_... clears it */
+ struct sci_port *s = platform_get_drvdata(dev);
+ unsigned int type = s->type; /* uart_remove_... clears it */
- sci_ports_in_use &= ~BIT(port->port.line);
- uart_remove_one_port(&sci_uart_driver, &port->port);
+ sci_ports_in_use &= ~BIT(s->port.line);
+ uart_remove_one_port(&sci_uart_driver, &s->port);
- if (port->port.fifosize > 1)
+ if (s->port.fifosize > 1)
device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger);
if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF)
device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout);
@@ -3682,8 +3698,8 @@ static int sci_probe(struct platform_device *dev)
if (ret)
return ret;
}
- if (sp->port.type == PORT_SCIFA || sp->port.type == PORT_SCIFB ||
- sp->port.type == PORT_HSCIF) {
+ if (sp->type == PORT_SCIFA || sp->type == PORT_SCIFB ||
+ sp->type == PORT_HSCIF) {
ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_timeout);
if (ret) {
if (sp->port.fifosize > 1) {
@@ -3799,7 +3815,8 @@ int __init scix_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
- device->port.type = data->type;
+ device->port.type = SCI_PUBLIC_PORT_ID(data->type);
+
sci_ports[0].port = device->port;
port_cfg.type = data->type;
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (6 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 07/11] serial: sh-sci: Use private port ID Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-02 1:15 ` kernel test robot
2025-05-13 13:29 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
` (2 subsequent siblings)
10 siblings, 2 replies; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Wolfram Sang, linux-kernel, linux-serial
Define a new RSCI port type, and the RSCI 32 bits registers set.
The RZ/T2H SCI has a a fifo, and a quite different set of registers
from the orginal SH SCI ones.
DMA is not supported yet.
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- s/rzsci/rsci/g
- declared SCI_PORT_RSCI as private port ID
- look for secondary clock
- report error when rsci clocks are not found
Changes v6->v7:
- Renamed compatible string to r9a09g077-rsci
Changes v5->v6:
- Rename SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI
- Rename rz-sci-t2.{c,h} to rsci.{c,h}
- Rename port type to PORT_RSCI
- Rename sci_r9a09g077_data to of_sci_r9a09g077_data for consistency
Changes v4->v5:
- Rename SERIAL_RZ_SCI to SERIAL_RZ_SCI_T2
- Rename rzsci.{c,h} to rz-sci-t2.{c,h}
- Rename port type to PORT_RZ_SCI_T2
- Set sci_shutdown ops pointer (needed by systemd for having a console)
Changes v3->v4:
- Added missing #include <bitfield.h>
- Fix christmas tree code style in rzsci_transmit_chars.
---
drivers/tty/serial/Kconfig | 7 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/rsci.c | 466 +++++++++++++++++++++++++++++
drivers/tty/serial/rsci.h | 12 +
drivers/tty/serial/sh-sci-common.h | 5 +
drivers/tty/serial/sh-sci.c | 43 ++-
6 files changed, 524 insertions(+), 10 deletions(-)
create mode 100644 drivers/tty/serial/rsci.c
create mode 100644 drivers/tty/serial/rsci.h
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 79a8186d3361..44427415a80d 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -675,6 +675,13 @@ config SERIAL_SH_SCI_DMA
depends on SERIAL_SH_SCI && DMA_ENGINE
default ARCH_RENESAS
+config SERIAL_RSCI
+ tristate "Support for Renesas RZ/T2H SCI variant"
+ depends on SERIAL_SH_SCI
+ help
+ Support for the RZ/T2H SCI variant with fifo.
+ Say Y if you want to be able to use the RZ/T2H SCI serial port.
+
config SERIAL_HS_LPC32XX
tristate "LPC32XX high speed serial port support"
depends on ARCH_LPC32XX || COMPILE_TEST
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index d58d9f719889..a2ccbc508ec5 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_SERIAL_QCOM_GENI) += qcom_geni_serial.o
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
obj-$(CONFIG_SERIAL_RDA) += rda-uart.o
obj-$(CONFIG_SERIAL_RP2) += rp2.o
+obj-$(CONFIG_SERIAL_RSCI) += rsci.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o
obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
new file mode 100644
index 000000000000..6a71bcffcc98
--- /dev/null
+++ b/drivers/tty/serial/rsci.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/serial_core.h>
+#include <linux/serial_sci.h>
+#include <linux/tty_flip.h>
+#include "rsci.h"
+
+/* RSCI registers */
+#define RDR 0x00
+#define TDR 0x04
+#define CCR0 0x08
+#define CCR1 0x0C
+#define CCR2 0x10
+#define CCR3 0x14
+#define CCR4 0x18
+#define FCR 0x24
+#define DCR 0x30
+#define CSR 0x48
+#define FRSR 0x50
+#define FTSR 0x54
+#define CFCLR 0x68
+#define FFCLR 0x70
+
+/* RDR (Receive Data Register) */
+#define RDR_FFER BIT(12) /* FIFO Framing Error */
+#define RDR_FPER BIT(11) /* FIFO Parity Error */
+#define RDR_RDAT_MSK GENMASK(8, 0)
+
+/* TDR (Transmit Data Register) */
+#define TDR_MPBT BIT(9) /* Multiprocessor Transfer */
+#define TDR_TDAT_9BIT_LSHIFT 0
+#define TDR_TDAT_9BIT_VAL 0x1FF
+#define TDR_TDAT_9BIT_MSK (TDR_TDAT_9BIT_VAL << TDR_TDAT_9BIT_LSHIFT)
+
+/* CCR0 (Common Control Register 0) */
+#define CCR0_SSE BIT(24) /* SSn# Pin Function Enable */
+#define CCR0_TEIE BIT(21) /* Transmit End Interrupt Enable */
+#define CCR0_TIE BIT(20) /* Transmit Interrupt Enable */
+#define CCR0_RIE BIT(16) /* Receive Interrupt Enable */
+#define CCR0_IDSEL BIT(10) /* ID Frame Select */
+#define CCR0_DCME BIT(9) /* Data Compare Match Enable */
+#define CCR0_MPIE BIT(8) /* Multiprocessor Interrupt Enable */
+#define CCR0_TE BIT(4) /* Transmit Enable */
+#define CCR0_RE BIT(0) /* Receive Enable */
+
+/* CCR1 (Common Control Register 1) */
+#define CCR1_NFEN BIT(28) /* Digital Noise Filter Function */
+#define CCR1_SHARPS BIT(20) /* Half -duplex Communication Select */
+#define CCR1_SPLP BIT(16) /* Loopback Control */
+#define CCR1_RINV BIT(13) /* RxD invert */
+#define CCR1_TINV BIT(12) /* TxD invert */
+#define CCR1_PM BIT(9) /* Parity Mode */
+#define CCR1_PE BIT(8) /* Parity Enable */
+#define CCR1_SPB2IO BIT(5) /* Serial Port Break I/O */
+#define CCR1_SPB2DT BIT(4) /* Serial Port Break Data Select */
+#define CCR1_CTSPEN BIT(1) /* CTS External Pin Enable */
+#define CCR1_CTSE BIT(0) /* CTS Enable */
+
+/* FCR (FIFO Control Register) */
+#define FCR_RFRST BIT(23) /* Receive FIFO Data Register Reset */
+#define FCR_TFRST BIT(15) /* Transmit FIFO Data Register Reset */
+#define FCR_DRES BIT(0) /* Incoming Data Ready Error Select */
+#define FCR_RTRG4_0 GENMASK(20, 16)
+#define FCR_TTRG GENMASK(12, 8)
+
+/* CSR (Common Status Register) */
+#define CSR_RDRF BIT(31) /* Receive Data Full */
+#define CSR_TEND BIT(30) /* Transmit End Flag */
+#define CSR_TDRE BIT(29) /* Transmit Data Empty */
+#define CSR_FER BIT(28) /* Framing Error */
+#define CSR_PER BIT(27) /* Parity Error */
+#define CSR_MFF BIT(26) /* Mode Fault Error */
+#define CSR_ORER BIT(24) /* Overrun Error */
+#define CSR_DFER BIT(18) /* Data Compare Match Framing Error */
+#define CSR_DPER BIT(17) /* Data Compare Match Parity Error */
+#define CSR_DCMF BIT(16) /* Data Compare Match */
+#define CSR_RXDMON BIT(15) /* Serial Input Data Monitor */
+#define CSR_ERS BIT(4) /* Error Signal Status */
+
+#define SCxSR_ERRORS(port) (to_sci_port(port)->params->error_mask)
+#define SCxSR_ERROR_CLEAR(port) (to_sci_port(port)->params->error_clear)
+
+#define RSCI_DEFAULT_ERROR_MASK (CSR_PER | CSR_FER)
+
+#define RSCI_RDxF_CLEAR (CFCLR_RDRFC)
+#define RSCI_ERROR_CLEAR (CFCLR_PERC | CFCLR_FERC)
+#define RSCI_TDxE_CLEAR (CFCLR_TDREC)
+#define RSCI_BREAK_CLEAR (CFCLR_PERC | CFCLR_FERC | CFCLR_ORERC)
+
+/* FRSR (FIFO Receive Status Register) */
+#define FRSR_R5_0 GENMASK(13, 8) /* Receive FIFO Data Count */
+#define FRSR_DR BIT(0) /* Receive Data Ready */
+
+/* CFCLR (Common Flag CLear Register) */
+#define CFCLR_RDRFC BIT(31) /* RDRF Clear */
+#define CFCLR_TDREC BIT(29) /* TDRE Clear */
+#define CFCLR_FERC BIT(28) /* FER Clear */
+#define CFCLR_PERC BIT(27) /* PER Clear */
+#define CFCLR_MFFC BIT(26) /* MFF Clear */
+#define CFCLR_ORERC BIT(24) /* ORER Clear */
+#define CFCLR_DFERC BIT(18) /* DFER Clear */
+#define CFCLR_DPERC BIT(17) /* DPER Clear */
+#define CFCLR_DCMFC BIT(16) /* DCMF Clear */
+#define CFCLR_ERSC BIT(4) /* ERS Clear */
+#define CFCLR_CLRFLAG (CFCLR_RDRFC | CFCLR_FERC | CFCLR_PERC | \
+ CFCLR_MFFC | CFCLR_ORERC | CFCLR_DFERC | \
+ CFCLR_DPERC | CFCLR_DCMFC | CFCLR_ERSC)
+
+/* FFCLR (FIFO Flag CLear Register) */
+#define FFCLR_DRC BIT(0) /* DR Clear */
+
+#define DCR_DEPOL BIT(0)
+
+static u32 rsci_serial_in(struct uart_port *p, int offset)
+{
+ return readl(p->membase + offset);
+}
+
+static void rsci_serial_out(struct uart_port *p, int offset, int value)
+{
+ writel(value, p->membase + offset);
+}
+
+static void rsci_clear_DRxC(struct uart_port *port)
+{
+ rsci_serial_out(port, CFCLR, CFCLR_RDRFC);
+ rsci_serial_out(port, FFCLR, FFCLR_DRC);
+}
+
+static void rsci_clear_SCxSR(struct uart_port *port, unsigned int mask)
+{
+ rsci_serial_out(port, CFCLR, mask);
+}
+
+static void rsci_start_rx(struct uart_port *port)
+{
+ unsigned int ctrl;
+
+ ctrl = rsci_serial_in(port, CCR0);
+ ctrl |= CCR0_RIE;
+ rsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
+ const struct ktermios *old)
+{
+ struct sci_port *s = to_sci_port(port);
+ unsigned long flags;
+
+ sci_port_enable(s);
+ uart_port_lock_irqsave(port, &flags);
+
+ /* For now, only RX enabling is supported */
+ if (termios->c_cflag & CREAD)
+ rsci_start_rx(port);
+
+ uart_port_unlock_irqrestore(port, flags);
+ sci_port_disable(s);
+}
+
+static int rsci_txfill(struct uart_port *port)
+{
+ return rsci_serial_in(port, FTSR);
+}
+
+static int rsci_rxfill(struct uart_port *port)
+{
+ u32 val = rsci_serial_in(port, FRSR);
+
+ return FIELD_GET(FRSR_R5_0, val);
+}
+
+static unsigned int rsci_tx_empty(struct uart_port *port)
+{
+ unsigned int status = rsci_serial_in(port, CSR);
+ unsigned int in_tx_fifo = rsci_txfill(port);
+
+ return (status & CSR_TEND) && !in_tx_fifo ? TIOCSER_TEMT : 0;
+}
+
+static void rsci_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* Not supported yet */
+}
+
+static unsigned int rsci_get_mctrl(struct uart_port *port)
+{
+ /* Not supported yet */
+ return 0;
+}
+
+static void rsci_clear_CFC(struct uart_port *port, unsigned int mask)
+{
+ rsci_serial_out(port, CFCLR, mask);
+}
+
+static void rsci_start_tx(struct uart_port *port)
+{
+ struct sci_port *sp = to_sci_port(port);
+ u32 ctrl;
+
+ if (sp->chan_tx)
+ return;
+
+ /*
+ * TE (Transmit Enable) must be set after setting TIE
+ * (Transmit Interrupt Enable) or in the same instruction
+ * to start the transmit process.
+ */
+ ctrl = rsci_serial_in(port, CCR0);
+ ctrl |= CCR0_TIE | CCR0_TE;
+ rsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rsci_stop_tx(struct uart_port *port)
+{
+ u32 ctrl;
+
+ ctrl = rsci_serial_in(port, CCR0);
+ ctrl &= ~CCR0_TIE;
+ rsci_serial_out(port, CCR0, ctrl);
+}
+
+static void rsci_stop_rx(struct uart_port *port)
+{
+ u32 ctrl;
+
+ ctrl = rsci_serial_in(port, CCR0);
+ ctrl &= ~CCR0_RIE;
+ rsci_serial_out(port, CCR0, ctrl);
+}
+
+static int rsci_txroom(struct uart_port *port)
+{
+ return port->fifosize - rsci_txfill(port);
+}
+
+static void rsci_transmit_chars(struct uart_port *port)
+{
+ unsigned int stopped = uart_tx_stopped(port);
+ struct tty_port *tport = &port->state->port;
+ u32 status, ctrl;
+ int count;
+
+ status = rsci_serial_in(port, CSR);
+ if (!(status & CSR_TDRE)) {
+ ctrl = rsci_serial_in(port, CCR0);
+ if (kfifo_is_empty(&tport->xmit_fifo))
+ ctrl &= ~CCR0_TIE;
+ else
+ ctrl |= CCR0_TIE;
+ rsci_serial_out(port, CCR0, ctrl);
+ return;
+ }
+
+ count = rsci_txroom(port);
+
+ do {
+ unsigned char c;
+
+ if (port->x_char) {
+ c = port->x_char;
+ port->x_char = 0;
+ } else if (stopped || !kfifo_get(&tport->xmit_fifo, &c)) {
+ break;
+ }
+
+ rsci_clear_CFC(port, CFCLR_TDREC);
+ rsci_serial_out(port, TDR, c);
+
+ port->icount.tx++;
+ } while (--count > 0);
+
+ if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (kfifo_is_empty(&tport->xmit_fifo)) {
+ ctrl = rsci_serial_in(port, CCR0);
+ ctrl &= ~CCR0_TIE;
+ ctrl |= CCR0_TEIE;
+ rsci_serial_out(port, CCR0, ctrl);
+ }
+}
+
+static void rsci_receive_chars(struct uart_port *port)
+{
+ struct tty_port *tport = &port->state->port;
+ u32 rdat, status, frsr_status = 0;
+ int i, count, copied = 0;
+ unsigned char flag;
+
+ status = rsci_serial_in(port, CSR);
+ frsr_status = rsci_serial_in(port, FRSR);
+
+ if (!(status & CSR_RDRF) && !(frsr_status & FRSR_DR))
+ return;
+
+ while (1) {
+ /* Don't copy more bytes than there is room for in the buffer */
+ count = tty_buffer_request_room(tport, rsci_rxfill(port));
+
+ /* If for any reason we can't copy more data, we're done! */
+ if (count == 0)
+ break;
+
+ for (i = 0; i < count; i++) {
+ char c;
+
+ rdat = rsci_serial_in(port, RDR);
+ /* 9-bits data is not supported yet */
+ c = rdat & RDR_RDAT_MSK;
+
+ if (uart_handle_sysrq_char(port, c)) {
+ count--;
+ i--;
+ continue;
+ }
+
+ /* Store data and status.
+ * Non FIFO mode is not supported
+ */
+ if (rdat & RDR_FFER) {
+ flag = TTY_FRAME;
+ port->icount.frame++;
+ } else if (rdat & RDR_FPER) {
+ flag = TTY_PARITY;
+ port->icount.parity++;
+ } else {
+ flag = TTY_NORMAL;
+ }
+
+ tty_insert_flip_char(tport, c, flag);
+ }
+
+ rsci_serial_in(port, CSR); /* dummy read */
+ rsci_clear_DRxC(port);
+
+ copied += count;
+ port->icount.rx += count;
+ }
+
+ if (copied) {
+ /* Tell the rest of the system the news. New characters! */
+ tty_flip_buffer_push(tport);
+ } else {
+ /* TTY buffers full; read from RX reg to prevent lockup */
+ rsci_serial_in(port, RDR);
+ rsci_serial_in(port, CSR); /* dummy read */
+ rsci_clear_DRxC(port);
+ }
+}
+
+static void rsci_poll_put_char(struct uart_port *port, unsigned char c)
+{
+ u32 status;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + CSR, status,
+ (status & CSR_TDRE), 100,
+ USEC_PER_SEC);
+ if (ret != 0) {
+ dev_err(port->dev,
+ "Error while sending data in UART TX : %d\n", ret);
+ goto done;
+ }
+ rsci_serial_out(port, TDR, c);
+done:
+ rsci_clear_SCxSR(port, CFCLR_TDREC);
+}
+
+static void rsci_prepare_console_write(struct uart_port *port, u32 ctrl)
+{
+ struct sci_port *s = to_sci_port(port);
+ u32 ctrl_temp =
+ s->params->param_bits->rxtx_enable |
+ CCR0_TIE |
+ s->hscif_tot;
+ rsci_serial_out(port, CCR0, ctrl_temp);
+}
+
+static const char *rsci_type(struct uart_port *port)
+{
+ return "rsci";
+}
+
+static size_t rsci_suspend_regs_size(void)
+{
+ return 0;
+}
+
+static const struct sci_common_regs rsci_common_regs = {
+ .status = CSR,
+ .control = CCR0,
+};
+
+static const struct sci_port_params_bits rsci_port_param_bits = {
+ .rxtx_enable = CCR0_RE | CCR0_TE,
+ .te_clear = CCR0_TE | CCR0_TEIE,
+ .poll_sent_bits = CSR_TDRE | CSR_TEND,
+};
+
+static const struct sci_port_params rsci_port_params = {
+ .fifosize = 16,
+ .overrun_reg = CSR,
+ .overrun_mask = CSR_ORER,
+ .sampling_rate_mask = SCI_SR(32),
+ .error_mask = RSCI_DEFAULT_ERROR_MASK,
+ .error_clear = RSCI_ERROR_CLEAR,
+ .param_bits = &rsci_port_param_bits,
+ .common_regs = &rsci_common_regs,
+};
+
+static const struct uart_ops rzt2_sci_uart_ops = {
+ .tx_empty = rsci_tx_empty,
+ .set_mctrl = rsci_set_mctrl,
+ .get_mctrl = rsci_get_mctrl,
+ .start_tx = rsci_start_tx,
+ .stop_tx = rsci_stop_tx,
+ .stop_rx = rsci_stop_rx,
+ .startup = sci_startup,
+ .shutdown = sci_shutdown,
+ .set_termios = rsci_set_termios,
+ .pm = sci_pm,
+ .type = rsci_type,
+ .release_port = sci_release_port,
+ .request_port = sci_request_port,
+ .config_port = sci_config_port,
+ .verify_port = sci_verify_port,
+};
+
+static const struct sci_port_ops rsci_port_ops = {
+ .read_reg = rsci_serial_in,
+ .write_reg = rsci_serial_out,
+ .clear_SCxSR = rsci_clear_SCxSR,
+ .transmit_chars = rsci_transmit_chars,
+ .receive_chars = rsci_receive_chars,
+ .poll_put_char = rsci_poll_put_char,
+ .prepare_console_write = rsci_prepare_console_write,
+ .suspend_regs_size = rsci_suspend_regs_size,
+};
+
+struct sci_of_data of_sci_r9a09g077_data = {
+ .type = SCI_PORT_RSCI,
+ .ops = &rsci_port_ops,
+ .uart_ops = &rzt2_sci_uart_ops,
+ .params = &rsci_port_params,
+};
+
+#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
+
+static int __init rzt2hsci_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ return scix_early_console_setup(device, &of_sci_r9a09g077_data);
+}
+
+OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rzt2hsci_early_console_setup);
+
+#endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */
diff --git a/drivers/tty/serial/rsci.h b/drivers/tty/serial/rsci.h
new file mode 100644
index 000000000000..0a037af26267
--- /dev/null
+++ b/drivers/tty/serial/rsci.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __RSCI_H__
+#define __RSCI_H__
+
+#include "sh-sci-common.h"
+
+#ifdef CONFIG_SERIAL_RSCI
+extern struct sci_of_data of_sci_r9a09g077_data;
+#endif
+
+#endif /* __RSCI_H__ */
diff --git a/drivers/tty/serial/sh-sci-common.h b/drivers/tty/serial/sh-sci-common.h
index de9796595cfd..f172715621ae 100644
--- a/drivers/tty/serial/sh-sci-common.h
+++ b/drivers/tty/serial/sh-sci-common.h
@@ -5,6 +5,11 @@
#include <linux/serial_core.h>
+/* Private port IDs */
+enum SCI_PORT_TYPE {
+ SCI_PORT_RSCI = BIT(15)|0,
+};
+
enum SCI_CLKS {
SCI_FCK, /* Functional Clock */
SCI_SCK, /* Optional External Clock */
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 2abf80230a77..44066cd53e5e 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -54,6 +54,7 @@
#include <asm/platform_early.h>
#endif
+#include "rsci.h"
#include "serial_mctrl_gpio.h"
#include "sh-sci.h"
#include "sh-sci-common.h"
@@ -1828,7 +1829,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
unsigned long flags;
u32 ctrl;
- if (s->type != PORT_SCI)
+ if (s->type != PORT_SCI && s->type != SCI_PORT_RSCI)
return sci_tx_interrupt(irq, ptr);
uart_port_lock_irqsave(port, &flags);
@@ -2977,14 +2978,26 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
struct clk *clk;
unsigned int i;
- if (sci_port->type == PORT_HSCIF)
+ if (sci_port->type == PORT_HSCIF) {
clk_names[SCI_SCK] = "hsck";
+ } else if (sci_port->type == SCI_PORT_RSCI) {
+ clk_names[SCI_FCK] = "async";
+ clk_names[SCI_SCK] = "bus";
+ }
for (i = 0; i < SCI_NUM_CLKS; i++) {
- clk = devm_clk_get_optional(dev, clk_names[i]);
+ const char *name = clk_names[i];
+
+ clk = devm_clk_get_optional(dev, name);
if (IS_ERR(clk))
return PTR_ERR(clk);
+ if (!clk && i <= SCI_SCK && sci_port->type == SCI_PORT_RSCI) {
+ return dev_err_probe(dev, -ENODEV,
+ "failed to get %s\n",
+ name);
+ }
+
if (!clk && i == SCI_FCK) {
/*
* Not all SH platforms declare a clock lookup entry
@@ -2995,13 +3008,13 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
if (IS_ERR(clk))
return dev_err_probe(dev, PTR_ERR(clk),
"failed to get %s\n",
- clk_names[i]);
+ name);
}
if (!clk)
- dev_dbg(dev, "failed to get %s\n", clk_names[i]);
+ dev_dbg(dev, "failed to get %s\n", name);
else
- dev_dbg(dev, "clk %s is %pC rate %lu\n", clk_names[i],
+ dev_dbg(dev, "clk %s is %pC rate %lu\n", name,
clk, clk_get_rate(clk));
sci_port->clks[i] = clk;
}
@@ -3085,10 +3098,10 @@ static int sci_init_single(struct platform_device *dev,
}
/*
- * The fourth interrupt on SCI port is transmit end interrupt, so
+ * The fourth interrupt on SCI and RSCI port is transmit end interrupt, so
* shuffle the interrupts.
*/
- if (p->type == PORT_SCI)
+ if (p->type == PORT_SCI || p->type == SCI_PORT_RSCI)
swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]);
/* The SCI generates several interrupts. They can be muxed together or
@@ -3122,6 +3135,9 @@ static int sci_init_single(struct platform_device *dev,
else
sci_port->rx_trigger = 8;
break;
+ case SCI_PORT_RSCI:
+ sci_port->rx_trigger = 15;
+ break;
default:
sci_port->rx_trigger = 1;
break;
@@ -3346,7 +3362,8 @@ static void sci_remove(struct platform_device *dev)
if (s->port.fifosize > 1)
device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger);
- if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF)
+ if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF ||
+ type == SCI_PORT_RSCI)
device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout);
}
@@ -3440,6 +3457,12 @@ static const struct of_device_id of_sci_match[] __maybe_unused = {
.compatible = "renesas,scif-r9a09g057",
.data = &of_sci_scif_rzv2h,
},
+#ifdef CONFIG_SERIAL_RSCI
+ {
+ .compatible = "renesas,r9a09g077-rsci",
+ .data = &of_sci_r9a09g077_data,
+ },
+#endif /* CONFIG_SERIAL_RSCI */
/* Family-specific types */
{
.compatible = "renesas,rcar-gen1-scif",
@@ -3699,7 +3722,7 @@ static int sci_probe(struct platform_device *dev)
return ret;
}
if (sp->type == PORT_SCIFA || sp->type == PORT_SCIFB ||
- sp->type == PORT_HSCIF) {
+ sp->type == PORT_HSCIF || sp->type == SCI_PORT_RSCI) {
ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_timeout);
if (ret) {
if (sp->port.fifosize > 1) {
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (7 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 13:34 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
2025-04-29 8:19 ` [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
devicetree, linux-kernel
Add the initial dtsi for the RZ/T2H Soc:
- gic
- armv8-timer
- cpg clock
- sci0 uart
also add arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi, that keeps
all 4 CPUs enabled, for consistency with later support of -m24
and -m04 SoC revisions, that only have 2 and 1 Cortex-A55, respectively,
and that will use /delete-node/ to disable the missing CPUs.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- removed loco clock
- added sci0 secondary clock
Changes v6->v7:
- Renamed compatible string to r9a09g077-rsci
Changes v5->v6: none
Changes v4->v5: none
Changes v3->v4: none
---
arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 122 ++++++++++++++++++
arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi | 13 ++
2 files changed, 135 insertions(+)
create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077.dtsi
create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
new file mode 100644
index 000000000000..78f7e9d2b7e1
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/T2H SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "renesas,r9a09g077";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ l3_ca55: cache-controller-0 {
+ compatible = "cache";
+ cache-unified;
+ cache-size = <0x100000>;
+ cache-level = <3>;
+ };
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a55";
+ reg = <0>;
+ device_type = "cpu";
+ next-level-cache = <&l3_ca55>;
+ enable-method = "psci";
+ };
+
+ cpu1: cpu@100 {
+ compatible = "arm,cortex-a55";
+ reg = <0x100>;
+ device_type = "cpu";
+ next-level-cache = <&l3_ca55>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@200 {
+ compatible = "arm,cortex-a55";
+ reg = <0x200>;
+ device_type = "cpu";
+ next-level-cache = <&l3_ca55>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@300 {
+ compatible = "arm,cortex-a55";
+ reg = <0x300>;
+ device_type = "cpu";
+ next-level-cache = <&l3_ca55>;
+ enable-method = "psci";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ sci0: serial@80005000 {
+ compatible = "renesas,r9a09g077-rsci";
+ reg = <0 0x80005000 0 0x400>;
+ interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 591 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "eri", "rxi", "txi", "tei";
+ clocks = <&cpg CPG_MOD R9A09G077_PCLK_SCI0>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
+ clock-names = "async", "bus";
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
+
+ cpg: clock-controller@80280000 {
+ compatible = "renesas,r9a09g077-cpg-mssr";
+ reg = <0 0x80280000 0 0x1000>,
+ <0 0x81280000 0 0x9000>;
+ clocks = <&extal_clk>;
+ clock-names = "extal";
+ #clock-cells = <2>;
+ #reset-cells = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ gic: interrupt-controller@83000000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x83000000 0 0x40000>,
+ <0x0 0x83040000 0 0x160000>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
new file mode 100644
index 000000000000..6f4a11b39d12
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/T2H 4-core SoC
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r9a09g077.dtsi"
+
+/ {
+ compatible = "renesas,r9a09g077m44", "renesas,r9a09g077";
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (8 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 13:38 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
devicetree, linux-kernel
Add the initial device tree for the RZ/T2H evaluation board.
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8:
- removed loco clock
- fixed checkpatch warning
Changes v6->v7:
- lands in arm64 directory instead of arm
Changes v5->v6: rebased on next-20250331
Changes v4->v5: none
Changes v3->v4: none
---
arch/arm64/boot/dts/renesas/Makefile | 1 +
.../dts/renesas/r9a09g077m44-rzt2h-evk.dts | 31 +++++++++++++++++++
2 files changed, 32 insertions(+)
create mode 100644 arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index d25e665ee4bf..14e2b41b6e13 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -152,6 +152,7 @@ dtb-$(CONFIG_ARCH_R9A09G011) += r9a09g011-v2mevk2.dtb
dtb-$(CONFIG_ARCH_R9A09G047) += r9a09g047e57-smarc.dtb
+dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-rzt2h-evk.dtb
dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h44-rzv2h-evk.dtb
dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h48-kakip.dtb
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
new file mode 100644
index 000000000000..bbacdca1959e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the RZ/T2H Development EVK board
+ *
+ * Copyright (C) 2025 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+
+#include "r9a09g077m44.dtsi"
+
+/ {
+ model = "Renesas Development EVK based on r9a09g077m44";
+ compatible = "renesas,rzt2h-evk", "renesas,r9a09g077m44", "renesas,r9a09g077";
+
+ aliases {
+ serial0 = &sci0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&extal_clk {
+ clock-frequency = <25000000>;
+};
+
+&sci0 {
+ status = "okay";
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
` (9 preceding siblings ...)
2025-04-29 8:19 ` [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
@ 2025-04-29 8:19 ` Thierry Bultel
2025-05-13 13:39 ` Geert Uytterhoeven
10 siblings, 1 reply; 27+ messages in thread
From: Thierry Bultel @ 2025-04-29 8:19 UTC (permalink / raw)
To: thierry.bultel
Cc: linux-renesas-soc, geert, paul.barker.ct, Thierry Bultel,
Wolfram Sang, linux-arm-kernel, linux-kernel
Selects RZ/T2H (aka r9a09g077) SCI (serial) specific code.
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
---
Changes v7->v8: none
Changes v6->v7: none
Changes v5->v6:
- Renamed CONFIG_SERIAL_RZ_SCI_T2 to CONFIG_SERIAL_RSCI
Changes v4->v5:
- Renamed CONFIG_SERIAL_RZ_SCI to CONFIG_SERIAL_RZ_SCI_T2
Changes v3->v4:
- Remove CONFIG_ARCH_R9A09G077=y
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 5bb8f09422a2..fcfc7b2e5819 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -494,6 +494,7 @@ CONFIG_SERIAL_TEGRA_TCU=y
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_RSCI=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_QCOM_GENI=y
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
@ 2025-04-29 14:48 ` Hugo Villeneuve
2025-05-09 18:58 ` Rob Herring
2025-05-13 9:38 ` Geert Uytterhoeven
2 siblings, 0 replies; 27+ messages in thread
From: Hugo Villeneuve @ 2025-04-29 14:48 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, geert, paul.barker.ct,
Geert Uytterhoeven, linux-kernel, linux-serial, devicetree
Hi Thierry,
On Tue, 29 Apr 2025 10:19:43 +0200
Thierry Bultel <thierry.bultel.yh@bp.renesas.com> wrote:
> At boot, the default clock is the PCLKM core lock (synchronous
lock -> clock?
> clock, which is enabled by the bootloader).
> For different baudrates, the asynchronous clock input must be used.
> Clock selection is made by an internal register of RCSI.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> .../bindings/serial/renesas,rsci.yaml | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> index ea879db5f485..aa2428837a2f 100644
> --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> @@ -35,10 +35,14 @@ properties:
> - const: tei
>
> clocks:
> - maxItems: 1
> + items:
> + - description: serial functional clock
> + - description: default core clock
>
> clock-names:
> - const: fck # UART functional clock
> + items:
> + - const: async
> + - const: bus
>
> power-domains:
> maxItems: 1
> @@ -58,11 +62,7 @@ unevaluatedProperties: false
> examples:
> - |
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> - #include <dt-bindings/clock/renesas-cpg-mssr.h>
> -
> - aliases {
> - serial0 = &sci0;
> - };
> + #include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
>
> sci0: serial@80005000 {
> compatible = "renesas,r9a09g077-rsci";
> @@ -72,7 +72,7 @@ examples:
> <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
> interrupt-names = "eri", "rxi", "txi", "tei";
> - clocks = <&cpg CPG_MOD 108>;
> - clock-names = "fck";
> + clocks = <&cpg CPG_MOD 108>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
> + clock-names = "async", "bus";
> power-domains = <&cpg>;
> };
> --
> 2.43.0
>
>
--
Hugo Villeneuve
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
2025-04-29 8:19 ` [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
@ 2025-04-29 15:01 ` Rob Herring (Arm)
2025-05-13 10:00 ` Geert Uytterhoeven
1 sibling, 0 replies; 27+ messages in thread
From: Rob Herring (Arm) @ 2025-04-29 15:01 UTC (permalink / raw)
To: Thierry Bultel
Cc: Geert Uytterhoeven, geert, paul.barker.ct, linux-kernel,
linux-clk, devicetree, linux-renesas-soc, thierry.bultel
On Tue, 29 Apr 2025 10:19:45 +0200, Thierry Bultel wrote:
> Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - extra parenthesis
> - added loco
> - renesas-cpg-mssr.h: removed unused clocks, added a macro for mstp
> Changes v6->v7:
> - Add description for reg property
> Changes v5->v6:
> - Set clock minItem constraint
> - Moved additionalProperties after 'allOf' section
> Changes v4->v5:
> - Set reg minItems and maxItems defaults at top level
> Changes v3->v4:
> - Handle maxItems and clocks names properly in schema.
> ---
> .../bindings/clock/renesas,cpg-mssr.yaml | 58 ++++++++++++++-----
> .../clock/renesas,r9a09g077-cpg-mssr.h | 48 +++++++++++++++
> 2 files changed, 90 insertions(+), 16 deletions(-)
> create mode 100644 include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI
2025-04-29 8:19 ` [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
@ 2025-05-02 1:15 ` kernel test robot
2025-05-13 13:29 ` Geert Uytterhoeven
1 sibling, 0 replies; 27+ messages in thread
From: kernel test robot @ 2025-05-02 1:15 UTC (permalink / raw)
To: Thierry Bultel, thierry.bultel
Cc: llvm, oe-kbuild-all, linux-renesas-soc, geert, paul.barker.ct,
Thierry Bultel, Wolfram Sang, linux-kernel, linux-serial
Hi Thierry,
kernel test robot noticed the following build errors:
[auto build test ERROR on tty/tty-testing]
[also build test ERROR on tty/tty-next]
[cannot apply to geert-renesas-drivers/renesas-clk tty/tty-linus geert-renesas-devel/next linus/master v6.15-rc4 next-20250501]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Thierry-Bultel/dt-bindings-soc-Add-Renesas-RZ-T2H-R9A09G077-SoC/20250429-172052
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link: https://lore.kernel.org/r/20250429081956.3804621-9-thierry.bultel.yh%40bp.renesas.com
patch subject: [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20250502/202505020836.WBkjrl7J-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505020836.WBkjrl7J-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505020836.WBkjrl7J-lkp@intel.com/
All errors (new ones prefixed by >>, old ones prefixed by <<):
ERROR: modpost: missing MODULE_LICENSE() in drivers/tty/serial/rsci.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/tty/serial/rsci.o
>> ERROR: modpost: "sci_port_enable" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_port_disable" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_release_port" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_shutdown" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_startup" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_verify_port" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_request_port" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_config_port" [drivers/tty/serial/rsci.ko] undefined!
>> ERROR: modpost: "sci_pm" [drivers/tty/serial/rsci.ko] undefined!
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
2025-04-29 14:48 ` Hugo Villeneuve
@ 2025-05-09 18:58 ` Rob Herring
2025-05-13 9:40 ` Geert Uytterhoeven
2025-05-13 9:38 ` Geert Uytterhoeven
2 siblings, 1 reply; 27+ messages in thread
From: Rob Herring @ 2025-05-09 18:58 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, geert, paul.barker.ct,
Geert Uytterhoeven, linux-kernel, linux-serial, devicetree
On Tue, Apr 29, 2025 at 10:19:43AM +0200, Thierry Bultel wrote:
> At boot, the default clock is the PCLKM core lock (synchronous
> clock, which is enabled by the bootloader).
> For different baudrates, the asynchronous clock input must be used.
> Clock selection is made by an internal register of RCSI.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> .../bindings/serial/renesas,rsci.yaml | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> index ea879db5f485..aa2428837a2f 100644
> --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> @@ -35,10 +35,14 @@ properties:
> - const: tei
>
> clocks:
> - maxItems: 1
> + items:
> + - description: serial functional clock
> + - description: default core clock
>
> clock-names:
> - const: fck # UART functional clock
> + items:
> + - const: async
> + - const: bus
This is an ABI change. You can't just drop 'fck' without good reasons.
Rob
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC
2025-04-29 8:19 ` [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
@ 2025-05-13 9:20 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 9:20 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Rob Herring,
Geert Uytterhoeven, devicetree, linux-kernel
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Add RZ/T2H (R9A09G077), its variants, and the rt2h-evk evaluation board in
> documentation.
>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Already applied as commit 6147c5f081708485 ("dt-bindings: soc: renesas:
Add Renesas RZ/T2H (R9A09G077) SoC") in next-20250423 and later.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
2025-04-29 14:48 ` Hugo Villeneuve
2025-05-09 18:58 ` Rob Herring
@ 2025-05-13 9:38 ` Geert Uytterhoeven
2025-05-13 13:17 ` Geert Uytterhoeven
2 siblings, 1 reply; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 9:38 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-kernel,
linux-serial, devicetree
Hi Thierry,
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> At boot, the default clock is the PCLKM core lock (synchronous
> clock, which is enabled by the bootloader).
> For different baudrates, the asynchronous clock input must be used.
> Clock selection is made by an internal register of RCSI.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
Thanks for your patch!
You forgot to CC the serial and DT maintainers.
> --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> @@ -35,10 +35,14 @@ properties:
> - const: tei
>
> clocks:
> - maxItems: 1
> + items:
> + - description: serial functional clock
The Hardware Manual calls this "operation clock".
> + - description: default core clock
The Hardware Manual calls this "bus clock".
>
> clock-names:
> - const: fck # UART functional clock
> + items:
> + - const: async
"async" is the name on the producer side, not the consumer side.
"operation"?
> + - const: bus
>
> power-domains:
> maxItems: 1
> @@ -58,11 +62,7 @@ unevaluatedProperties: false
> examples:
> - |
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> - #include <dt-bindings/clock/renesas-cpg-mssr.h>
> -
> - aliases {
> - serial0 = &sci0;
> - };
While this change is good, it is not mentioned in the commit
description.
> + #include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
This has a hard dependency on "[PATCH v8 03/11] dt-bindings: clock:
Add cpg for the Renesas RZ/T2H SoC". To relax that dependency, you can
s/R9A09G077_CLK_PCLKM/13/ below..
>
> sci0: serial@80005000 {
> compatible = "renesas,r9a09g077-rsci";
> @@ -72,7 +72,7 @@ examples:
> <GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
> interrupt-names = "eri", "rxi", "txi", "tei";
> - clocks = <&cpg CPG_MOD 108>;
> - clock-names = "fck";
> + clocks = <&cpg CPG_MOD 108>, <&cpg CPG_CORE R9A09G077_CLK_PCLKM>;
s/108/8/?
> + clock-names = "async", "bus";
> power-domains = <&cpg>;
> };
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
2025-05-09 18:58 ` Rob Herring
@ 2025-05-13 9:40 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 9:40 UTC (permalink / raw)
To: Rob Herring
Cc: Thierry Bultel, thierry.bultel, linux-renesas-soc, paul.barker.ct,
linux-kernel, linux-serial, devicetree
Hi Rob,
On Fri, 9 May 2025 at 20:59, Rob Herring <robh@kernel.org> wrote:
> On Tue, Apr 29, 2025 at 10:19:43AM +0200, Thierry Bultel wrote:
> > At boot, the default clock is the PCLKM core lock (synchronous
> > clock, which is enabled by the bootloader).
> > For different baudrates, the asynchronous clock input must be used.
> > Clock selection is made by an internal register of RCSI.
> >
> > Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> > ---
> > .../bindings/serial/renesas,rsci.yaml | 18 +++++++++---------
> > 1 file changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> > index ea879db5f485..aa2428837a2f 100644
> > --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> > +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> > @@ -35,10 +35,14 @@ properties:
> > - const: tei
> >
> > clocks:
> > - maxItems: 1
> > + items:
> > + - description: serial functional clock
> > + - description: default core clock
> >
> > clock-names:
> > - const: fck # UART functional clock
> > + items:
> > + - const: async
> > + - const: bus
>
> This is an ABI change. You can't just drop 'fck' without good reasons.
This is fine, as there are no users yet.
The initial DT bindings were written based on a limited understanding of
the device. Let's hope our current understanding is less limited ;-)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC
2025-04-29 8:19 ` [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
2025-04-29 15:01 ` Rob Herring (Arm)
@ 2025-05-13 10:00 ` Geert Uytterhoeven
1 sibling, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 10:00 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-clk,
devicetree, linux-kernel
Hi Thierry,
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Document RZ/T2H (a.k.a r9a09g077) cpg-mssr (Clock Pulse Generator) binding.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - extra parenthesis
> - added loco
> - renesas-cpg-mssr.h: removed unused clocks, added a macro for mstp
Thanks for the update!
> --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
> +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
> @@ -52,9 +52,15 @@ properties:
> - renesas,r8a779f0-cpg-mssr # R-Car S4-8
> - renesas,r8a779g0-cpg-mssr # R-Car V4H
> - renesas,r8a779h0-cpg-mssr # R-Car V4M
> + - renesas,r9a09g077-cpg-mssr # RZ/T2H
>
> reg:
> - maxItems: 1
> + minItems: 1
> + items:
> + - description: base address of register block 0
> + - description: base address of register block 1
> + description: base addresses of clock controller. Some controllers
> + (like r9a09g077) use two blocks instead of a single one.
>
> clocks:
> minItems: 1
> @@ -63,11 +69,6 @@ properties:
> clock-names:
> minItems: 1
> maxItems: 2
> - items:
> - enum:
> - - extal # All
> - - extalr # Most R-Car Gen3 and RZ/G2
> - - usb_extal # Most R-Car Gen2 and RZ/G1
Please keep this list here, as the single RZ/T2H input clock is
just a subset.
>
> '#clock-cells':
> description: |
> @@ -92,16 +93,6 @@ properties:
> the datasheet.
> const: 1
>
> -if:
> - not:
> - properties:
> - compatible:
> - items:
> - enum:
> - - renesas,r7s9210-cpg-mssr
> -then:
> - required:
> - - '#reset-cells'
>
> required:
> - compatible
> @@ -111,6 +102,41 @@ required:
> - '#clock-cells'
> - '#power-domain-cells'
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: renesas,r9a09g077-cpg-mssr
> + then:
> + properties:
> + reg:
> + minItems: 2
> + clock-names:
> + items:
> + - const: extal
> + else:
> + properties:
> + reg:
> + maxItems: 1
> + clock-names:
> + items:
> + enum:
> + - extal # All
> + - extalr # Most R-Car Gen3 and RZ/G2
> + - usb_extal # Most R-Car Gen2 and RZ/G1
> +
> + - if:
> + not:
> + properties:
> + compatible:
> + items:
> + enum:
> + - renesas,r7s9210-cpg-mssr
> + then:
> + required:
> + - '#reset-cells'
> +
> additionalProperties: false
>
> examples:
> diff --git a/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
> new file mode 100644
> index 000000000000..d5b16d08e75d
> --- /dev/null
> +++ b/include/dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> + *
> + * Copyright (C) 2025 Renesas Electronics Corp.
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> +#define __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__
> +
> +#include <dt-bindings/clock/renesas-cpg-mssr.h>
> +
> +/* R9A09G077 CPG Core Clocks */
> +#define R9A09G077_CLK_CA55C0 0
> +#define R9A09G077_CLK_CA55C1 1
> +#define R9A09G077_CLK_CA55C2 2
> +#define R9A09G077_CLK_CA55C3 3
> +#define R9A09G077_CLK_CA55S 4
> +#define R9A09G077_CLK_CR52_CPU0 5
> +#define R9A09G077_CLK_CR52_CPU1 6
> +#define R9A09G077_CLK_BSC 7
> +#define R9A09G077_CLK_CKIO R9A09G077_CLK_BSC
I would drop R9A09G077_CLK_BSC and only keep R9A09G077_CLK_CKIO,
as the documentation only lists consumers for the latter.
> +#define R9A09G077_CLK_PCLKAH 8
> +#define R9A09G077_CLK_PCLKAM 9
> +#define R9A09G077_CLK_PCLKAL 10
> +#define R9A09G077_CLK_PCLKGPTL 11
> +#define R9A09G077_CLK_PCLKH 12
> +#define R9A09G077_CLK_PCLKM 13
> +
> +
> +#define R9A09G077_MSTPCRA 0
> +#define R9A09G077_MSTPCRB 1
> +#define R9A09G077_MSTPCRC 2
> +#define R9A09G077_MSTPCRD 3
> +#define R9A09G077_MSTPCRE 4
> +#define R9A09G077_MSTPCRG 7
6...
> +#define R9A09G077_MSTPCRI 8
> +#define R9A09G077_MSTPCRJ 9
> +#define R9A09G077_MSTPCRK 10
> +#define R9A09G077_MSTPCRL 11
> +#define R9A09G077_MSTPCRM 12
> +#define R9A09G077_MSTPCRN 13
> +
> +#define R9A09G077_MSTP(mstp, idx) (100*(mstp)+(idx))
> +
> +/* R9A09G077 CPG Module Clocks */
> +#define R9A09G077_PCLK_SCI0 R9A09G077_MSTP(R9A09G077_MSTPCRA, 8)
... but please drop all the R9A09G077_MSTP* definitions and module
clocks. There is a very simple formula to convert from register and
bit numbers in the documentation to MSTP numbers, so the DTS can
just use these numbers.
> +
> +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */
> +
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
2025-04-29 8:19 ` [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
@ 2025-05-13 10:10 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 10:10 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-clk,
linux-kernel
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> In a subsequent patch, the registration callback will need more parameters
> from cpg_mssr_priv (like another base address with clock controllers
> with double register block, and also, notifiers and rmw_lock).
> Instead of adding more parameters, move the needed parameters to a public
> sub-struct.
> Instead moving clks to this structure, which would have implied to add
> an allocation (and cleanup) for it, keep the way the allocation is done
> and just have a copy of the pointer in the public structure.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - moved struct cpg_mssr_pub pub to the beginning of struct cpg_mssr_priv
> - make *core & *info fit on the same line
> - order of doc tags
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC
2025-04-29 8:19 ` [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
@ 2025-05-13 12:09 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 12:09 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-kernel,
linux-clk
Hi Thierry,
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> RZ/T2H has 2 register blocks at different addresses.
>
> The clock tree has configurable dividers and mux selectors.
> Add these new clock types, new register layout type, and
> registration code for mux and div in registration callback.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - Makefile: keep ordered list
> - r9a09g077-cpg-mssr.c: use high bit instead of sel_base,
> same macro for DIV and MUX
> - removed unused clocks
> - CLK_LOCO is internal with a DEF_RATE definition
> - added CLK_PLL4D1 & CLK_SCI0ASYNC
> - added per-CA55 clocks
> - added missing error check in r9a09g077_cpg_mux_clk_register
> - fixed num_hw_mod_clks to 14
> - added missing 2 holes in mstpcr_for_rzt2h
> - renamed cpg_read_rzt2h_mstp_from_offset to cpg_read_rzt2h_mstp,
> directly reads at calculated address
> - added cpg_write_rzt2h_mstp and call in cpg_mstp_clock_endisable
> - do not register reset controller in case of CLK_REG_LAYOUT_RZ_T2H
> - moved CLK_DIV & CLK_MUX definitions to RZT2H specifics
Thanks for the update!
> index 000000000000..029619a6cb19
> --- /dev/null
> +++ b/drivers/clk/renesas/r9a09g077-cpg-mssr.c
r9a09g077-cpg.c
> @@ -0,0 +1,252 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * r9a09g077 Clock Pulse Generator / Module Standby and Software Reset
> + *
> + * Copyright (C) 2025 Renesas Electronics Corp.
> + *
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +
> +#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
> +#include "renesas-cpg-mssr.h"
> +
> +#define RZT2H_REG_BLOCK_SHIFT 11
> +#define RZT2H_REG_OFFSET_MASK GENMASK(10, 0)
> +#define RZT2H_REG_CONF(block, offset) (((block) << RZT2H_REG_BLOCK_SHIFT) | \
> + ((offset) & RZT2H_REG_OFFSET_MASK))
> +
> +#define RZT2H_REG_BLOCK(x) ((x) >> RZT2H_REG_BLOCK_SHIFT)
> +#define RZT2H_REG_OFFSET(x) ((x) & RZT2H_REG_OFFSET_MASK)
> +
> +#define SCKCR RZT2H_REG_CONF(0, 0x00)
> +#define SCKCR2 RZT2H_REG_CONF(1, 0x04)
> +#define SCKCR3 RZT2H_REG_CONF(0, 0x08)
> +
> +#define OFFSET_MASK GENMASK(31, 20)
> +#define SHIFT_MASK GENMASK(19, 12)
> +#define WIDTH_MASK GENMASK(11, 8)
> +
> +#define CONF_PACK(offset, shift, width) \
> + (FIELD_PREP_CONST(OFFSET_MASK, (offset)) | \
> + FIELD_PREP_CONST(SHIFT_MASK, (shift)) | \
> + FIELD_PREP_CONST(WIDTH_MASK, (width)))
> +
> +#define GET_SHIFT(val) FIELD_GET(SHIFT_MASK, val)
> +#define GET_WIDTH(val) FIELD_GET(WIDTH_MASK, val)
> +#define GET_REG_OFFSET(val) FIELD_GET(OFFSET_MASK, val)
> +
> +#define DIVCA55C0 CONF_PACK(SCKCR2, 8, 1)
> +#define DIVCA55C1 CONF_PACK(SCKCR2, 9, 1)
> +#define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1)
> +#define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1)
> +#define DIVCA55S CONF_PACK(SCKCR2, 12, 1)
> +
> +#define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 1)
This field holds two bits, not one.
> +
> +#define SEL_PLL CONF_PACK(SCKCR, 22, 1)
> +
> +
> +enum rzt2h_clk_types {
> + CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */
> + CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */
> +};
> +
> +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
> + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_DIV, .conf = _conf, \
> + .parent = _parent, .dtable = _dtable, .flag = _flag)
The _flag parameter is always zero?
> +#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \
> + _mux_flags) \
> + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_MUX, .conf = _conf, \
> + .parent_names = _parent_names, .num_parents = _num_parents, \
> + .flag = _flag, .mux_flags = _mux_flags)
The _flag parameter is always zero (see below)?
> +
> +enum clk_ids {
> + /* Core Clock Outputs exported to DT */
> + LAST_DT_CORE_CLK = R9A09G077_CLK_PCLKM,
> +
> + /* External Input Clocks */
> + CLK_EXTAL,
> +
> + /* Internal Core Clocks */
> + CLK_LOCO,
> + CLK_MAIN,
Unused
> + CLK_PLL0,
> + CLK_PLL1,
> + CLK_PLL4,
> + CLK_SEL_PLL0,
> + CLK_SEL_CLK_PLL0,
> + CLK_SEL_PLL1,
> + CLK_SEL_CLK_PLL1,
> + CLK_SEL_PLL4,
> + CLK_SEL_CLK_PLL4,
> + CLK_PLL4D1,
> + CLK_SCI0ASYNC,
> +
> + /* Module Clocks */
> + MOD_CLK_BASE,
> +};
> +
> +static const struct clk_div_table dtable_1_2[] = {
> + {0, 2},
> + {1, 1},
> + {0, 0},
> +};
> +
> +static const struct clk_div_table dtable_24_25_30_32[] = {
> + {0, 24},
> + {0, 25},
> + {0, 30},
> + {0, 32},
The first value of each tuple must contain the register bit field value,
and usually the tables are sorted by value (although the code doesn't
seem to rely on that):
{0, 32},
{1, 30},
{2, 25},
{3, 24},
> + {0, 0},
> +};
> +
> +/* Mux clock tables */
> +
> +static const char * const sel_clk_pll0[] = { "loco", ".sel_pll0" };
> +static const char * const sel_clk_pll1[] = { "loco", ".sel_pll1" };
> +static const char * const sel_clk_pll4[] = { "loco", ".sel_pll4" };
".loco", as this is an internal clock.
> +
> +static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
> + /* External Clock Inputs */
> + DEF_INPUT("extal", CLK_EXTAL),
> +
> + /* Internal Core Clocks */
> + DEF_RATE("loco", CLK_LOCO, 1000 * 1000),
".loco", as this is an internal clock.
> + DEF_FIXED(".pll0", CLK_PLL0, CLK_EXTAL, 1, 48),
> + DEF_FIXED(".pll1", CLK_PLL1, CLK_EXTAL, 1, 40),
> + DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 1, 96),
> + /* unimplemented CLMA0 selector */
> + DEF_FIXED(".sel_pll0", CLK_SEL_PLL0, CLK_PLL0, 1, 1),
Will there ever be a need to implement these CLMAx selectors?
If not, you can just drop all SEL_PLLx clocks with 1/1 mul/div.
IIUIC, the CPG will switch automatically to clocks derived from the
LOCO if an anomaly is detected, yielding the same clock frequencies
as during normal operation (albeit with less precision)?
> + DEF_MUX(".sel_clk_pll0", CLK_SEL_CLK_PLL0, SEL_PLL,
> + sel_clk_pll0, ARRAY_SIZE(sel_clk_pll0), 0, CLK_MUX_READ_ONLY),
> + /* unimplemented CLMA1 selector */
> + DEF_FIXED(".sel_pll1", CLK_SEL_PLL1, CLK_PLL1, 1, 1),
> + DEF_MUX(".sel_clk_pll1", CLK_SEL_CLK_PLL1, SEL_PLL,
> + sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), 0, CLK_MUX_READ_ONLY),
> + /* unimplemented CLMA4 selector */
> + DEF_FIXED(".sel_pll4", CLK_SEL_PLL4, CLK_PLL4, 1, 1),
> + DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL,
> + sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), 0, CLK_MUX_READ_ONLY),
> +
> + DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1),
> + DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC,
> + dtable_24_25_30_32, CLK_DIVIDER_HIWORD_MASK),
CLK_DIVIDER_HIWORD_MASK is wrong, as there is no mask in
the higher 16-bit of the SCKCR3 register...
> +
> + /* Core output clk */
> + DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0,
> + dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
... nor in the SCKCR2 register.
> + DEF_DIV("CA55C1", R9A09G077_CLK_CA55C1, CLK_SEL_CLK_PLL0, DIVCA55C1,
> + dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
> + DEF_DIV("CA55C2", R9A09G077_CLK_CA55C2, CLK_SEL_CLK_PLL0, DIVCA55C2,
> + dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
> + DEF_DIV("CA55C3", R9A09G077_CLK_CA55C3, CLK_SEL_CLK_PLL0, DIVCA55C3,
> + dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
> + DEF_DIV("CA55S", R9A09G077_CLK_CA55S, CLK_SEL_CLK_PLL0, DIVCA55S,
> + dtable_1_2, CLK_DIVIDER_HIWORD_MASK),
> + DEF_FIXED("PCLKGPTL", R9A09G077_CLK_PCLKGPTL, CLK_SEL_CLK_PLL1, 2, 1),
> + DEF_FIXED("PCLKM", R9A09G077_CLK_PCLKM, CLK_SEL_CLK_PLL1, 8, 1),
> +};
> +
> +static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
> + DEF_MOD("sci0fck", R9A09G077_PCLK_SCI0, CLK_SCI0ASYNC),
> +};
> +
> +static struct clk * __init
> +r9a09g077_cpg_div_clk_register(struct device *dev,
> + const struct cpg_core_clk *core,
> + void __iomem *addr, struct cpg_mssr_pub *pub)
> +{
> + const struct clk *parent;
> + const char *parent_name;
> + struct clk_hw *clk_hw;
> +
> + parent = pub->clks[core->parent];
> +
Please drop this blank line.
> + if (IS_ERR(parent))
> + return ERR_CAST(parent);
> +static struct clk * __init
> +r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core,
> + const struct cpg_mssr_info *info,
> + struct cpg_mssr_pub *pub)
> +{
> + u32 offset = GET_REG_OFFSET(core->conf);
> + void __iomem *base = RZT2H_REG_BLOCK(offset) ? pub->base1 : pub->base0;
> + void __iomem *addr = base + offset;
... + RZT2H_REG_OFFSET(offset);
> +
> + switch (core->type) {
> + case CLK_TYPE_RZT2H_DIV:
> + return r9a09g077_cpg_div_clk_register(dev, core, addr, pub);
> + case CLK_TYPE_RZT2H_MUX:
> + return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub);
> + default:
> + return ERR_PTR(-EINVAL);
> + }
> +}
> --- a/drivers/clk/renesas/renesas-cpg-mssr.c
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.c
> @@ -79,6 +79,37 @@ static const u16 mstpcr_for_gen4[] = {
> 0x2D60, 0x2D64, 0x2D68, 0x2D6C, 0x2D70, 0x2D74,
> };
>
> +/*
> + * Module Stop Control Register (RZ/T2H)
> + * RZ/T2H has 2 registers blocks,
> + * Bit 12 is used to differentiate them
> + */
> +
> +#define RZT2H_MSTPCR_BLOCK_SHIFT 12
> +#define RZT2H_MSTPCR_OFFSET_MASK GENMASK(11, 0)
> +#define RZT2H_MSTPCR(block, offset) (((block) << RZT2H_MSTPCR_BLOCK_SHIFT) | \
> + ((offset) & RZT2H_MSTPCR_OFFSET_MASK))
> +
> +#define RZT2H_MSTPCR_BLOCK(x) ((x) >> RZT2H_MSTPCR_BLOCK_SHIFT)
> +#define RZT2H_MSTPCR_OFFSET(x) ((x) & RZT2H_MSTPCR_OFFSET_MASK)
> @@ -187,6 +218,26 @@ struct mstp_clock {
>
> #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
>
> +static u32 cpg_read_rzt2h_mstp(struct clk_hw *hw, u16 offset)
rzt2h_mstpcr_read(), to match the naming of the helper macros above?
> +{
> + struct mstp_clock *clock = to_mstp_clock(hw);
> + struct cpg_mssr_priv *priv = clock->priv;
> + void __iomem *base =
> + RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0;
> +
> + return readl(base + RZT2H_MSTPCR_OFFSET(offset));
> +}
> +
> +static void cpg_write_rzt2h_mstp(struct clk_hw *hw, u16 offset, u32 value)
rzt2h_mstpcr_write()?
> +{
> + struct mstp_clock *clock = to_mstp_clock(hw);
> + struct cpg_mssr_priv *priv = clock->priv;
> + void __iomem *base =
> + RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0;
> +
> + writel(value, base + RZT2H_MSTPCR_OFFSET(offset));
> +}
> +
> static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> {
> struct mstp_clock *clock = to_mstp_clock(hw);
> @@ -215,6 +266,19 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> readb(priv->pub.base0 + priv->control_regs[reg]);
> barrier_data(priv->pub.base0 + priv->control_regs[reg]);
>
> + } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
> + pr_info("RZTH2 case");
Please drop this pr_info() call.
> + value = cpg_read_rzt2h_mstp(hw,
> + priv->control_regs[reg]);
> +
> + if (enable)
> + value &= ~bitmask;
> + else
> + value |= bitmask;
> +
> + cpg_write_rzt2h_mstp(hw,
> + priv->control_regs[reg],
> + value);
> } else {
> value = readl(priv->pub.base0 + priv->control_regs[reg]);
> if (enable)
> @@ -1064,6 +1138,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
> error = -ENOMEM;
> goto out_err;
> }
> + if (info->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
> + priv->pub.base1 = of_iomap(np, 1);
> + if (!priv->pub.base1) {
> + error = -ENOMEM;
> + goto out_err;
> + }
> + }
>
> priv->num_core_clks = info->num_total_core_clks;
> priv->num_mod_clks = info->num_hw_mod_clks;
> @@ -1077,6 +1158,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
> priv->reset_clear_regs = srstclr;
> } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
> priv->control_regs = stbcr;
> + } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
> + priv->control_regs = mstpcr_for_rzt2h;
> } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
> priv->status_regs = mstpsr_for_gen4;
> priv->control_regs = mstpcr_for_gen4;
> @@ -1107,6 +1190,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
> out_err:
> if (priv->pub.base0)
> iounmap(priv->pub.base0);
> + if (priv->pub.base1)
> + iounmap(priv->pub.base1);
> kfree(priv);
>
> return error;
> @@ -1171,7 +1256,8 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
> goto reserve_exit;
>
> /* Reset Controller not supported for Standby Control SoCs */
> - if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
> + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
> + priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
> goto reserve_exit;
>
> error = cpg_mssr_reset_controller_register(priv);
> diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
> index 7ce3cc9a64c1..2801d6bf2f6d 100644
> --- a/drivers/clk/renesas/renesas-cpg-mssr.h
> +++ b/drivers/clk/renesas/renesas-cpg-mssr.h
> @@ -22,6 +22,10 @@
> struct cpg_core_clk {
> /* Common */
> const char *name;
> + union {
> + const char * const *parent_names;
> + const struct clk_div_table *dtable;
> + };
Please move them below, as they are type-specific.
> unsigned int id;
> unsigned int type;
> /* Depending on type */
> @@ -29,18 +33,24 @@ struct cpg_core_clk {
> unsigned int div;
> unsigned int mult;
> unsigned int offset;
> + u32 conf;
> + u16 flag;
> + u8 mux_flags;
> + u8 num_parents;
> };
>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 07/11] serial: sh-sci: Use private port ID
2025-04-29 8:19 ` [PATCH v8 07/11] serial: sh-sci: Use private port ID Thierry Bultel
@ 2025-05-13 12:59 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 12:59 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-kernel,
linux-serial
Hi Thierry,
Thanks for your patch!
You forgot to CC the serial maintainers.
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> From: Thierry Bultel <thierry.bultel@linatsea.fr>
>
> New port types cannot be added in serial_core.h, which is shared with
> userspace.
> In order to support new port types, the coming new ones will have
> BIT(15) set in the id value, and in this case, uartport->type is
> set to PORT_GENERIC.
> This commit therefore changes all the places where the port type is
> read, by not relying on uartport->type but on the private
> value stored in struct sci_port.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
scripts/checkpatch.pl:
WARNING: From:/Signed-off-by: email address mismatch: 'From: Thierry
Bultel <thierry.bultel@linatsea.fr>' != 'Signed-off-by: Thierry Bultel
<thierry.bultel.yh@bp.renesas.com>'
> --- a/drivers/tty/serial/sh-sci-common.h
> +++ b/drivers/tty/serial/sh-sci-common.h
> @@ -142,6 +142,9 @@ struct sci_port {
> int rx_fifo_timeout;
> u16 hscif_tot;
>
> + unsigned int type;
u16 should be sufficient, as you store the new info in bit 15.
Even u8 is sufficient (but then you have to move the new bit to bit
7), and has the advantage of not increasing the size of the structure,
as there was still a 2-byte hole.
> + unsigned int regtype;
u8?
> +
> const struct sci_port_ops *ops;
>
> bool has_rtscts;
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index ff1986dc6af3..2abf80230a77 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -75,6 +75,8 @@
>
> #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
>
> +#define SCI_PUBLIC_PORT_ID(port) (!((port) & BIT(15)) ? (port) : PORT_GENERIC)
Please simplify by inverting the check:
((port) & BIT(15)) ? PORT_GENERIC : port
> +
> static struct sci_port sci_ports[SCI_NPORTS];
> static unsigned long sci_ports_in_use;
> static struct uart_driver sci_uart_driver;
> @@ -3050,6 +3063,9 @@ static int sci_init_single(struct platform_device *dev,
>
> sci_port->cfg = p;
>
> + sci_port->type = p->type;
> + sci_port->regtype = p->regtype;
> +
> port->iotype = UPIO_MEM;
> port->line = index;
> port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SH_SCI_CONSOLE);
> @@ -3799,7 +3815,8 @@ int __init scix_early_console_setup(struct earlycon_device *device,
> if (!device->port.membase)
> return -ENODEV;
>
> - device->port.type = data->type;
> + device->port.type = SCI_PUBLIC_PORT_ID(data->type);
> +
> sci_ports[0].port = device->port;
Here you have to fill in sci_ports[0].type and sci_ports[0].regtype,
like in sci_init_single(), else they are always zero when using
earlycon.
>
> port_cfg.type = data->type;
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI
2025-05-13 9:38 ` Geert Uytterhoeven
@ 2025-05-13 13:17 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 13:17 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, linux-kernel,
linux-serial, devicetree
Hi Thierry,
On Tue, 13 May 2025 at 11:38, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
> <thierry.bultel.yh@bp.renesas.com> wrote:
> > At boot, the default clock is the PCLKM core lock (synchronous
> > clock, which is enabled by the bootloader).
> > For different baudrates, the asynchronous clock input must be used.
> > Clock selection is made by an internal register of RCSI.
> >
> > Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> > --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> > +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
> > @@ -35,10 +35,14 @@ properties:
> > - const: tei
> >
> > clocks:
> > - maxItems: 1
> > + items:
> > + - description: serial functional clock
>
> The Hardware Manual calls this "operation clock".
>
> > + - description: default core clock
>
> The Hardware Manual calls this "bus clock".
>
> >
> > clock-names:
> > - const: fck # UART functional clock
> > + items:
> > + - const: async
>
> "async" is the name on the producer side, not the consumer side.
> "operation"?
>
> > + - const: bus
Actually there can be a third optional clock, just like on all other
variants except for SCIFA/SCIFB: the external SCK pin.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI
2025-04-29 8:19 ` [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
2025-05-02 1:15 ` kernel test robot
@ 2025-05-13 13:29 ` Geert Uytterhoeven
1 sibling, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 13:29 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Wolfram Sang,
linux-kernel, linux-serial
Hi Thierry,
Thanks for the update!
You forgot to CC the serial maintainers.
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
>
> Define a new RSCI port type, and the RSCI 32 bits registers set.
> The RZ/T2H SCI has a a fifo, and a quite different set of registers
> from the orginal SH SCI ones.
original
> DMA is not supported yet.
>
> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - s/rzsci/rsci/g
> - declared SCI_PORT_RSCI as private port ID
> - look for secondary clock
> - report error when rsci clocks are not found
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -675,6 +675,13 @@ config SERIAL_SH_SCI_DMA
> depends on SERIAL_SH_SCI && DMA_ENGINE
> default ARCH_RENESAS
>
> +config SERIAL_RSCI
> + tristate "Support for Renesas RZ/T2H SCI variant"
> + depends on SERIAL_SH_SCI
As this subdriver can be a module, the relevant symbols in the sh-sci
driver need to be exported, as reported by the kernel robot.
> + help
> + Support for the RZ/T2H SCI variant with fifo.
> + Say Y if you want to be able to use the RZ/T2H SCI serial port.
> +
> config SERIAL_HS_LPC32XX
> tristate "LPC32XX high speed serial port support"
> depends on ARCH_LPC32XX || COMPILE_TEST
> --- /dev/null
> +++ b/drivers/tty/serial/rsci.c
> +static void rsci_prepare_console_write(struct uart_port *port, u32 ctrl)
> +{
> + struct sci_port *s = to_sci_port(port);
> + u32 ctrl_temp =
> + s->params->param_bits->rxtx_enable |
> + CCR0_TIE |
> + s->hscif_tot;
This fits on two lines:
u32 ctrl_temp = s->params->param_bits->rxtx_enable | CCR0_TIE |
s->hscif_tot;
> + rsci_serial_out(port, CCR0, ctrl_temp);
> +}
> +static const struct uart_ops rzt2_sci_uart_ops = {
rsci_uart_ops
> + .tx_empty = rsci_tx_empty,
> + .set_mctrl = rsci_set_mctrl,
> + .get_mctrl = rsci_get_mctrl,
> + .start_tx = rsci_start_tx,
> + .stop_tx = rsci_stop_tx,
> + .stop_rx = rsci_stop_rx,
> + .startup = sci_startup,
> + .shutdown = sci_shutdown,
> + .set_termios = rsci_set_termios,
> + .pm = sci_pm,
> + .type = rsci_type,
> + .release_port = sci_release_port,
> + .request_port = sci_request_port,
> + .config_port = sci_config_port,
> + .verify_port = sci_verify_port,
> +};
> +struct sci_of_data of_sci_r9a09g077_data = {
of_sci_rsci_data
> + .type = SCI_PORT_RSCI,
> + .ops = &rsci_port_ops,
> + .uart_ops = &rzt2_sci_uart_ops,
> + .params = &rsci_port_params,
> +};
> +
> +#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
> +
> +static int __init rzt2hsci_early_console_setup(struct earlycon_device *device,
rsci_early_console_setup
> + const char *opt)
> +{
> + return scix_early_console_setup(device, &of_sci_r9a09g077_data);
> +}
> +
> +OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rzt2hsci_early_console_setup);
> +
> +#endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */
> --- a/drivers/tty/serial/sh-sci-common.h
> +++ b/drivers/tty/serial/sh-sci-common.h
> @@ -5,6 +5,11 @@
>
> #include <linux/serial_core.h>
>
> +/* Private port IDs */
> +enum SCI_PORT_TYPE {
> + SCI_PORT_RSCI = BIT(15)|0,
Please add spaces around "|".
> +};
> +
> enum SCI_CLKS {
> SCI_FCK, /* Functional Clock */
> SCI_SCK, /* Optional External Clock */
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 2abf80230a77..44066cd53e5e 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -2977,14 +2978,26 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
> struct clk *clk;
> unsigned int i;
>
> - if (sci_port->type == PORT_HSCIF)
> + if (sci_port->type == PORT_HSCIF) {
> clk_names[SCI_SCK] = "hsck";
> + } else if (sci_port->type == SCI_PORT_RSCI) {
> + clk_names[SCI_FCK] = "async";
As per my comment on the bindings, I think you should use a different
name. But the actual behavior (overriding [SCI_SCK]) is fine.
> + clk_names[SCI_SCK] = "bus";
This is not OK, as on RSCI the SCK pin can serve as a clock input.
I see two options here:
- Add a fifth entry for the RSCI bus clock,
- Override the [SCI_BRG_INT] entry (which is the closest to a
bus clock); RSCI will have its own set_termios implementation anyway.
> + }
> @@ -3085,10 +3098,10 @@ static int sci_init_single(struct platform_device *dev,
> }
>
> /*
> - * The fourth interrupt on SCI port is transmit end interrupt, so
> + * The fourth interrupt on SCI and RSCI port is transmit end interrupt, so
(R)SCI?
> * shuffle the interrupts.
> */
> - if (p->type == PORT_SCI)
> + if (p->type == PORT_SCI || p->type == SCI_PORT_RSCI)
> swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]);
>
> /* The SCI generates several interrupts. They can be muxed together or
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC
2025-04-29 8:19 ` [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
@ 2025-05-13 13:34 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 13:34 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, devicetree,
linux-kernel
Hi Thierry,
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Add the initial dtsi for the RZ/T2H Soc:
>
> - gic
> - armv8-timer
> - cpg clock
> - sci0 uart
>
> also add arch/arm64/boot/dts/renesas/r9a09g077m44.dtsi, that keeps
> all 4 CPUs enabled, for consistency with later support of -m24
> and -m04 SoC revisions, that only have 2 and 1 Cortex-A55, respectively,
> and that will use /delete-node/ to disable the missing CPUs.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - removed loco clock
> - added sci0 secondary clock
Thanks for your patch!
LGTM (modulo the comments on the RSCI and CPG bindings), so
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board
2025-04-29 8:19 ` [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
@ 2025-05-13 13:38 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 13:38 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, devicetree,
linux-kernel
Hi Thierry,
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Add the initial device tree for the RZ/T2H evaluation board.
>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
> ---
> Changes v7->v8:
> - removed loco clock
> - fixed checkpatch warning
Thanks for the update!
> --- a/arch/arm64/boot/dts/renesas/Makefile
> +++ b/arch/arm64/boot/dts/renesas/Makefile
> @@ -152,6 +152,7 @@ dtb-$(CONFIG_ARCH_R9A09G011) += r9a09g011-v2mevk2.dtb
>
> dtb-$(CONFIG_ARCH_R9A09G047) += r9a09g047e57-smarc.dtb
>
> +dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-rzt2h-evk.dtb
Please preserve alphabetical sort order.
> dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h44-rzv2h-evk.dtb
> dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h48-kakip.dtb
The rest LGTM, so with the above fixed:
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI
2025-04-29 8:19 ` [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
@ 2025-05-13 13:39 ` Geert Uytterhoeven
0 siblings, 0 replies; 27+ messages in thread
From: Geert Uytterhoeven @ 2025-05-13 13:39 UTC (permalink / raw)
To: Thierry Bultel
Cc: thierry.bultel, linux-renesas-soc, paul.barker.ct, Wolfram Sang,
linux-arm-kernel, linux-kernel
On Tue, 29 Apr 2025 at 10:20, Thierry Bultel
<thierry.bultel.yh@bp.renesas.com> wrote:
> Selects RZ/T2H (aka r9a09g077) SCI (serial) specific code.
>
> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2025-05-13 13:39 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20250429081956.3804621-1-thierry.bultel.yh@bp.renesas.com>
2025-04-29 8:19 ` [PATCH v8 01/11] dt-bindings: serial: Added secondary clock for RZ/T2H RSCI Thierry Bultel
2025-04-29 14:48 ` Hugo Villeneuve
2025-05-09 18:58 ` Rob Herring
2025-05-13 9:40 ` Geert Uytterhoeven
2025-05-13 9:38 ` Geert Uytterhoeven
2025-05-13 13:17 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 02/11] dt-bindings: soc: Add Renesas RZ/T2H (R9A09G077) SoC Thierry Bultel
2025-05-13 9:20 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 03/11] dt-bindings: clock: Add cpg for the Renesas RZ/T2H SoC Thierry Bultel
2025-04-29 15:01 ` Rob Herring (Arm)
2025-05-13 10:00 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 04/11] soc: renesas: Add RZ/T2H (R9A09G077) config option Thierry Bultel
2025-04-29 8:19 ` [PATCH v8 05/11] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register Thierry Bultel
2025-05-13 10:10 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 06/11] clk: renesas: Add support for R9A09G077 SoC Thierry Bultel
2025-05-13 12:09 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 07/11] serial: sh-sci: Use private port ID Thierry Bultel
2025-05-13 12:59 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 08/11] serial: sh-sci: Add support for RZ/T2H SCI Thierry Bultel
2025-05-02 1:15 ` kernel test robot
2025-05-13 13:29 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 09/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H SoC Thierry Bultel
2025-05-13 13:34 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 10/11] arm64: dts: renesas: Add initial support for renesas RZ/T2H eval board Thierry Bultel
2025-05-13 13:38 ` Geert Uytterhoeven
2025-04-29 8:19 ` [PATCH v8 11/11] arm64: defconfig: Enable Renesas RZ/T2H serial SCI Thierry Bultel
2025-05-13 13:39 ` Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox