* [PATCH v2 1/8] dt-bindings: clock: rk3588: add PCLK_DDR_MON_CH clocks
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-10-05 17:10 ` Rob Herring (Arm)
2026-09-21 20:32 ` [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588 Sebastian Reichel
` (6 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
On RK3588, each memory channel has its own DDR bandwidth monitor
silicon, and each instance of that has its own clock gate that drives
the monitor logic.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
include/dt-bindings/clock/rockchip,rk3588-cru.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/dt-bindings/clock/rockchip,rk3588-cru.h b/include/dt-bindings/clock/rockchip,rk3588-cru.h
index 7528034cff56..6ea25019ebb4 100644
--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
+++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
@@ -738,6 +738,10 @@
#define I2S1_8CH_MCLKOUT_TO_IO 723
#define I2S2_2CH_MCLKOUT_TO_IO 724
#define I2S3_2CH_MCLKOUT_TO_IO 725
+#define PCLK_DDR_MON_CH0 726
+#define PCLK_DDR_MON_CH1 727
+#define PCLK_DDR_MON_CH2 728
+#define PCLK_DDR_MON_CH3 729
/* scmi-clocks indices */
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v2 1/8] dt-bindings: clock: rk3588: add PCLK_DDR_MON_CH clocks
2026-09-21 20:32 ` [PATCH v2 1/8] dt-bindings: clock: rk3588: add PCLK_DDR_MON_CH clocks Sebastian Reichel
@ 2026-10-05 17:10 ` Rob Herring (Arm)
0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring (Arm) @ 2026-10-05 17:10 UTC (permalink / raw)
To: Sebastian Reichel
Cc: kernel, Brian Masney, Chanwoo Choi, devicetree, linux-kernel,
Nicolas Frattaroli, linux-arm-kernel, Jerome Brunet,
Heiko Stuebner, MyungJoo Ham, Kyungmin Park, linux-rockchip,
Sascha Hauer, Stephen Boyd, Conor Dooley, linux-pm,
Krzysztof Kozlowski, linux-clk
On Mon, 21 Sep 2026 22:32:44 +0200, Sebastian Reichel wrote:
> From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
>
> On RK3588, each memory channel has its own DDR bandwidth monitor
> silicon, and each instance of that has its own clock gate that drives
> the monitor logic.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> include/dt-bindings/clock/rockchip,rk3588-cru.h | 4 ++++
> 1 file changed, 4 insertions(+)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 1/8] dt-bindings: clock: rk3588: add PCLK_DDR_MON_CH clocks Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:41 ` sashiko-bot
2026-10-05 17:10 ` Rob Herring (Arm)
2026-09-21 20:32 ` [PATCH v2 3/8] PM / devfreq: rockchip-dfi: move to per-variant const structs Sebastian Reichel
` (5 subsequent siblings)
7 siblings, 2 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
RK3588's DFI has pclks for each channel. They just weren't noticed as
missing until now because nothing ever gates them, and they're ungated
by default on power-on.
The RK3399 clock situation needs no changes, as there the hardware
really just has one monitoring unit for both channels.
Add these clocks to the binding, so that drivers for this device can
properly know about their existence.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
.../bindings/devfreq/event/rockchip,dfi.yaml | 70 ++++++++++++++++++----
1 file changed, 58 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml b/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
index 50d3fabe958d..3450e28b4020 100644
--- a/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
+++ b/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
@@ -17,11 +17,18 @@ properties:
- rockchip,rk3588-dfi
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 4
clock-names:
+ minItems: 1
items:
- - const: pclk_ddr_mon
+ - enum:
+ - pclk_ddr_mon
+ - pclk_ddr_mon_ch0
+ - const: pclk_ddr_mon_ch1
+ - const: pclk_ddr_mon_ch2
+ - const: pclk_ddr_mon_ch3
interrupts:
minItems: 1
@@ -40,17 +47,37 @@ required:
- interrupts
- reg
-if:
- properties:
- compatible:
- contains:
- enum:
- - rockchip,rk3399-dfi
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - rockchip,rk3399-dfi
+ then:
+ properties:
+ clocks:
+ maxItems: 1
+ clock-names:
+ maxItems: 1
+ required:
+ - clocks
+ - clock-names
-then:
- required:
- - clocks
- - clock-names
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - rockchip,rk3588-dfi
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ maxItems: 4
+ clock-names:
+ minItems: 4
+ maxItems: 4
additionalProperties: false
@@ -72,3 +99,22 @@ examples:
clock-names = "pclk_ddr_mon";
};
};
+
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ dfi_rk3588: dfi@fe060000 {
+ compatible = "rockchip,rk3588-dfi";
+ reg = <0x00 0xfe060000 0x00 0x10000>;
+ clocks = <&cru 0x53>, <&cru 0x48>, <&cru 0x49>, <&cru 0x54>;
+ clock-names = "pclk_ddr_mon_ch0", "pclk_ddr_mon_ch1",
+ "pclk_ddr_mon_ch2", "pclk_ddr_mon_ch3";
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+ rockchip,pmu = <&pmugrf>;
+ };
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588
2026-09-21 20:32 ` [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588 Sebastian Reichel
@ 2026-09-21 20:41 ` sashiko-bot
2026-10-05 17:10 ` Rob Herring (Arm)
1 sibling, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-09-21 20:41 UTC (permalink / raw)
To: Sebastian Reichel; +Cc: robh, linux-clk, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] dt-bindings: missing clock constraints for rk3568-dfi
- [Medium] dt-bindings: variant conditionals fail to restrict clock-names exact strings
--
commit 88c291fbc8ab68b7cfb2fa8d4a230dd27bd0f853
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588
This commit updates the Rockchip DFI binding to add clock definitions for
the rk3588 SoC. It modifies the global clock limits and introduces
conditional blocks to handle the differences between rk3399 and rk3588.
> diff --git a/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml b/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
> index 50d3fabe958d5..3450e28b40208 100644
> --- a/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
> +++ b/Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml
> @@ -17,11 +17,18 @@ properties:
> - rockchip,rk3588-dfi
>
> clocks:
> - maxItems: 1
> + minItems: 1
> + maxItems: 4
>
> clock-names:
> + minItems: 1
> items:
> - - const: pclk_ddr_mon
> + - enum:
> + - pclk_ddr_mon
> + - pclk_ddr_mon_ch0
> + - const: pclk_ddr_mon_ch1
> + - const: pclk_ddr_mon_ch2
> + - const: pclk_ddr_mon_ch3
[ ... ]
> -if:
> - properties:
> - compatible:
> - contains:
> - enum:
> - - rockchip,rk3399-dfi
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - rockchip,rk3399-dfi
[Severity: Medium]
Will this omission cause schema validation to be incomplete for rk3568-dfi?
The global clocks constraint was relaxed to maxItems: 4 to support rk3588,
but rk3568-dfi is omitted from these conditional blocks. Doesn't this mean
device trees for rk3568-dfi specifying up to 4 clocks will inadvertently pass
dtbs_check validation instead of being restricted to the historic maxItems: 1
limit?
> + then:
> + properties:
> + clocks:
> + maxItems: 1
> + clock-names:
> + maxItems: 1
> + required:
> + - clocks
> + - clock-names
[Severity: Medium]
Does this setup allow incorrectly named clocks to pass validation for specific
variants?
Since the global clock-names definition uses an enum for the first item,
and this conditional block only restricts maxItems: 1, a device tree using
clock-names = "pclk_ddr_mon_ch0" will erroneously pass validation for
rk3399-dfi. The same applies for rk3588-dfi passing with "pclk_ddr_mon".
Should the variant-specific conditional blocks override the items array
to enforce the correct fixed string (const) for that specific variant?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921-rockchip-dfi-cleanup-v2-0-43ff34ac8599@collabora.com?part=2
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588
2026-09-21 20:32 ` [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588 Sebastian Reichel
2026-09-21 20:41 ` sashiko-bot
@ 2026-10-05 17:10 ` Rob Herring (Arm)
1 sibling, 0 replies; 14+ messages in thread
From: Rob Herring (Arm) @ 2026-10-05 17:10 UTC (permalink / raw)
To: Sebastian Reichel
Cc: kernel, Chanwoo Choi, linux-pm, Brian Masney, devicetree,
Krzysztof Kozlowski, Stephen Boyd, linux-arm-kernel, linux-clk,
linux-rockchip, MyungJoo Ham, linux-kernel, Conor Dooley,
Kyungmin Park, Nicolas Frattaroli, Sascha Hauer, Jerome Brunet,
Heiko Stuebner
On Mon, 21 Sep 2026 22:32:45 +0200, Sebastian Reichel wrote:
> From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
>
> RK3588's DFI has pclks for each channel. They just weren't noticed as
> missing until now because nothing ever gates them, and they're ungated
> by default on power-on.
>
> The RK3399 clock situation needs no changes, as there the hardware
> really just has one monitoring unit for both channels.
>
> Add these clocks to the binding, so that drivers for this device can
> properly know about their existence.
>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> .../bindings/devfreq/event/rockchip,dfi.yaml | 70 ++++++++++++++++++----
> 1 file changed, 58 insertions(+), 12 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 3/8] PM / devfreq: rockchip-dfi: move to per-variant const structs
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 1/8] dt-bindings: clock: rk3588: add PCLK_DDR_MON_CH clocks Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 2/8] dt-bindings: devfreq: event: rockchip,dfi: add clocks to rk3588 Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 4/8] PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability Sebastian Reichel
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
The rockchip-dfi driver supports several variants of the DDR monitoring
hardware. The differences in these variants are handled with one init
function for each variant.
However, some of the members that these init functions set are actually
constants, specific to that variant, with no runtime involvement from
reading registers or anything.
Refactor the code to move those values (and the soc_init function
pointer) into a new struct. Declare some const instances of this variant
struct, and use it wherever needed.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/devfreq/event/rockchip-dfi.c | 94 +++++++++++++++++++++---------------
1 file changed, 54 insertions(+), 40 deletions(-)
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 255aee1bdd91..5339616f7ca6 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -103,7 +103,6 @@ struct rockchip_dfi {
struct mutex mutex;
u32 ddr_type;
unsigned int channel_mask;
- unsigned int max_channels;
enum cpuhp_state cpuhp_state;
struct hlist_node node;
struct pmu pmu;
@@ -112,11 +111,17 @@ struct rockchip_dfi {
int active_events;
int burst_len;
int buswidth[DMC_MAX_CHANNELS];
- int ddrmon_stride;
- bool ddrmon_ctrl_single;
u32 lp5_bank_mode;
bool lp5_ckr; /* true if in 4:1 command-to-data clock ratio mode */
unsigned int count_multiplier; /* number of data clocks per count */
+ const struct rockchip_dfi_variant *variant;
+};
+
+struct rockchip_dfi_variant {
+ int (*init)(struct rockchip_dfi *dfi);
+ int stride;
+ bool ctrl_single;
+ unsigned int max_channels;
};
static int rockchip_dfi_ddrtype_to_ctrl(struct rockchip_dfi *dfi, u32 *ctrl)
@@ -188,7 +193,7 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
if (ret)
goto out;
- for (i = 0; i < dfi->max_channels; i++) {
+ for (i = 0; i < dfi->variant->max_channels; i++) {
if (!(dfi->channel_mask & BIT(i)))
continue;
@@ -197,16 +202,16 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_TIMER_CNT_EN, 0) |
FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0) |
FIELD_PREP_WM16(DDRMON_CTRL_HARDWARE_EN, 0),
- dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+ dfi_regs + i * dfi->variant->stride + DDRMON_CTRL);
- writel_relaxed(ctrl, dfi_regs + i * dfi->ddrmon_stride +
+ writel_relaxed(ctrl, dfi_regs + i * dfi->variant->stride +
DDRMON_CTRL);
/* enable count, use software mode */
writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 1),
- dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+ dfi_regs + i * dfi->variant->stride + DDRMON_CTRL);
- if (dfi->ddrmon_ctrl_single)
+ if (dfi->variant->ctrl_single)
break;
}
out:
@@ -229,14 +234,14 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
if (dfi->usecount > 0)
goto out;
- for (i = 0; i < dfi->max_channels; i++) {
+ for (i = 0; i < dfi->variant->max_channels; i++) {
if (!(dfi->channel_mask & BIT(i)))
continue;
writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0),
- dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+ dfi_regs + i * dfi->variant->stride + DDRMON_CTRL);
- if (dfi->ddrmon_ctrl_single)
+ if (dfi->variant->ctrl_single)
break;
}
@@ -250,17 +255,17 @@ static void rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct dmc_coun
u32 i;
void __iomem *dfi_regs = dfi->regs;
- for (i = 0; i < dfi->max_channels; i++) {
+ for (i = 0; i < dfi->variant->max_channels; i++) {
if (!(dfi->channel_mask & BIT(i)))
continue;
res->c[i].read_access = readl_relaxed(dfi_regs +
- DDRMON_CH0_RD_NUM + i * dfi->ddrmon_stride);
+ DDRMON_CH0_RD_NUM + i * dfi->variant->stride);
res->c[i].write_access = readl_relaxed(dfi_regs +
- DDRMON_CH0_WR_NUM + i * dfi->ddrmon_stride);
+ DDRMON_CH0_WR_NUM + i * dfi->variant->stride);
res->c[i].access = readl_relaxed(dfi_regs +
- DDRMON_CH0_DFI_ACCESS_NUM + i * dfi->ddrmon_stride);
+ DDRMON_CH0_DFI_ACCESS_NUM + i * dfi->variant->stride);
res->c[i].clock_cycles = readl_relaxed(dfi_regs +
- DDRMON_CH0_COUNT_NUM + i * dfi->ddrmon_stride);
+ DDRMON_CH0_COUNT_NUM + i * dfi->variant->stride);
}
}
@@ -297,7 +302,7 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
rockchip_dfi_read_counters(dfi, &count);
/* We can only report one channel, so find the busiest one */
- for (i = 0; i < dfi->max_channels; i++) {
+ for (i = 0; i < dfi->variant->max_channels; i++) {
u32 a, c;
if (!(dfi->channel_mask & BIT(i)))
@@ -336,7 +341,7 @@ static void rockchip_ddr_perf_counters_add(struct rockchip_dfi *dfi,
const struct dmc_count *last = &dfi->last_perf_count;
int i;
- for (i = 0; i < dfi->max_channels; i++) {
+ for (i = 0; i < dfi->variant->max_channels; i++) {
res->c[i].read_access = dfi->total_count.c[i].read_access +
(u32)(now->c[i].read_access - last->c[i].read_access);
res->c[i].write_access = dfi->total_count.c[i].write_access +
@@ -477,11 +482,11 @@ static u64 rockchip_ddr_perf_event_get_count(struct perf_event *event)
count = total.c[0].clock_cycles * dfi->count_multiplier;
break;
case PERF_EVENT_READ_BYTES:
- for (i = 0; i < dfi->max_channels; i++)
+ for (i = 0; i < dfi->variant->max_channels; i++)
count += total.c[i].read_access * blen * dfi->buswidth[i];
break;
case PERF_EVENT_WRITE_BYTES:
- for (i = 0; i < dfi->max_channels; i++)
+ for (i = 0; i < dfi->variant->max_channels; i++)
count += total.c[i].write_access * blen * dfi->buswidth[i];
break;
case PERF_EVENT_READ_BYTES0:
@@ -509,7 +514,7 @@ static u64 rockchip_ddr_perf_event_get_count(struct perf_event *event)
count = total.c[3].write_access * blen * dfi->buswidth[3];
break;
case PERF_EVENT_BYTES:
- for (i = 0; i < dfi->max_channels; i++)
+ for (i = 0; i < dfi->variant->max_channels; i++)
count += total.c[i].access * blen * dfi->buswidth[i];
break;
}
@@ -726,14 +731,10 @@ static int rk3399_dfi_init(struct rockchip_dfi *dfi)
dfi->ddr_type = FIELD_GET(RK3399_PMUGRF_OS_REG2_DDRTYPE, val);
dfi->channel_mask = GENMASK(1, 0);
- dfi->max_channels = 2;
dfi->buswidth[0] = FIELD_GET(RK3399_PMUGRF_OS_REG2_BW_CH0, val) == 0 ? 4 : 2;
dfi->buswidth[1] = FIELD_GET(RK3399_PMUGRF_OS_REG2_BW_CH1, val) == 0 ? 4 : 2;
- dfi->ddrmon_stride = 0x14;
- dfi->ddrmon_ctrl_single = true;
-
return 0;
};
@@ -756,13 +757,9 @@ static int rk3568_dfi_init(struct rockchip_dfi *dfi)
dfi->ddr_type |= FIELD_GET(RK3568_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3, reg3) << 3;
dfi->channel_mask = BIT(0);
- dfi->max_channels = 1;
dfi->buswidth[0] = FIELD_GET(RK3568_PMUGRF_OS_REG2_BW_CH0, reg2) == 0 ? 4 : 2;
- dfi->ddrmon_stride = 0x0; /* not relevant, we only have a single channel on this SoC */
- dfi->ddrmon_ctrl_single = true;
-
return 0;
};
@@ -791,9 +788,7 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi)
dfi->buswidth[3] = FIELD_GET(RK3588_PMUGRF_OS_REG2_BW_CH1, reg4) == 0 ? 4 : 2;
dfi->channel_mask = FIELD_GET(RK3588_PMUGRF_OS_REG2_CH_INFO, reg2) |
FIELD_GET(RK3588_PMUGRF_OS_REG2_CH_INFO, reg4) << 2;
- dfi->max_channels = 4;
- dfi->ddrmon_stride = 0x4000;
dfi->count_multiplier = 2;
if (dfi->ddr_type == ROCKCHIP_DDRTYPE_LPDDR5) {
@@ -807,10 +802,30 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi)
return 0;
};
+static const struct rockchip_dfi_variant rk3399_variant = {
+ .init = rk3399_dfi_init,
+ .stride = 0x14,
+ .ctrl_single = true,
+ .max_channels = 2,
+};
+
+static const struct rockchip_dfi_variant rk3568_variant = {
+ .init = rk3568_dfi_init,
+ .stride = 0x0,
+ .ctrl_single = true,
+ .max_channels = 1,
+};
+
+static const struct rockchip_dfi_variant rk3588_variant = {
+ .init = rk3588_dfi_init,
+ .stride = 0x4000,
+ .max_channels = 4,
+};
+
static const struct of_device_id rockchip_dfi_id_match[] = {
- { .compatible = "rockchip,rk3399-dfi", .data = rk3399_dfi_init },
- { .compatible = "rockchip,rk3568-dfi", .data = rk3568_dfi_init },
- { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init },
+ { .compatible = "rockchip,rk3399-dfi", .data = &rk3399_variant },
+ { .compatible = "rockchip,rk3568-dfi", .data = &rk3568_variant },
+ { .compatible = "rockchip,rk3588-dfi", .data = &rk3588_variant },
{ },
};
@@ -822,17 +837,16 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
struct rockchip_dfi *dfi;
struct devfreq_event_desc *desc;
struct device_node *np = pdev->dev.of_node, *node;
- int (*soc_init)(struct rockchip_dfi *dfi);
int ret;
- soc_init = of_device_get_match_data(&pdev->dev);
- if (!soc_init)
- return -EINVAL;
-
dfi = devm_kzalloc(dev, sizeof(*dfi), GFP_KERNEL);
if (!dfi)
return -ENOMEM;
+ dfi->variant = of_device_get_match_data(dev);
+ if (!dfi->variant)
+ return -EINVAL;
+
dfi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dfi->regs))
return PTR_ERR(dfi->regs);
@@ -854,7 +868,7 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
desc->driver_data = dfi;
desc->name = np->name;
- ret = soc_init(dfi);
+ ret = dfi->variant->init(dfi);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v2 4/8] PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
` (2 preceding siblings ...)
2026-09-21 20:32 ` [PATCH v2 3/8] PM / devfreq: rockchip-dfi: move to per-variant const structs Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:39 ` sashiko-bot
2026-09-21 20:32 ` [PATCH v2 5/8] PM / devfreq: rockchip-dfi: use bulk clock APIs Sebastian Reichel
` (3 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
The perf subsystem's PERF_PMU_CAP_NO_INTERRUPT is a bit of a
misnomer.[1] Instead of meaning that the PMU has no interrupt, it
actually means that the PMU does support sampling. On CPU PMUs, this is
equivalent to not having an interrupt, but for uncore PMUs like the
rockchip-dfi PMU is, no meaningful sample data could ever be generated
regardless of whether or not there is an interrupt, as it is not a CPU.
Since rockchip-dfi doesn't seem to make use of the interrupt the DT
provides it with anyway, this was probably never a confusion that
existed in this case; the capability flag was likely just forgotten.
Add PERF_PMU_CAP_NO_INTERRUPT to the set flags for the pmu struct's
capabilities member, so that the perf core knows about this limitation.
Fixes: 4d586b5724d3 ("PM / devfreq: rockchip-dfi: Add perf support")
Link: https://lore.kernel.org/all/20250619140442.GH1613376@noisy.programming.kicks-ass.net/ [1]
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/devfreq/event/rockchip-dfi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 5339616f7ca6..dd9edfd6a674 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -646,7 +646,7 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi)
seqlock_init(&dfi->count_seqlock);
pmu->module = THIS_MODULE;
- pmu->capabilities = PERF_PMU_CAP_NO_EXCLUDE;
+ pmu->capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT;
pmu->task_ctx_nr = perf_invalid_context;
pmu->attr_groups = attr_groups;
pmu->event_init = rockchip_ddr_perf_event_init;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v2 4/8] PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability
2026-09-21 20:32 ` [PATCH v2 4/8] PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability Sebastian Reichel
@ 2026-09-21 20:39 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-09-21 20:39 UTC (permalink / raw)
To: Sebastian Reichel; +Cc: robh, devicetree, linux-clk, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] perf: logic inversion in commit message regarding sampling support
--
commit 568c8dc55a298020ff3044a68b97809f490ba7e0
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability
This commit adds the PERF_PMU_CAP_NO_INTERRUPT capability flag to the
rockchip-dfi PMU. This informs the perf core that the PMU does not support
sampling.
Link: https://lore.kernel.org/all/20250619140442.GH1613376@noisy.programming.kicks-ass.net/ [1]
> The perf subsystem's PERF_PMU_CAP_NO_INTERRUPT is a bit of a
> misnomer.[1] Instead of meaning that the PMU has no interrupt, it
> actually means that the PMU does support sampling. On CPU PMUs, this is
[Severity: Low]
Is there a missing "not" in this sentence?
In kernel/events/core.c, if a sampling event is requested for a PMU with this
flag, the allocation fails with -EOPNOTSUPP. Thus, the flag means the PMU does
not support sampling.
The code in drivers/devfreq/event/rockchip-dfi.c:rockchip_ddr_perf_init()
correctly applies the flag, so there is no functional issue, but the commit
message contains a logic inversion.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921-rockchip-dfi-cleanup-v2-0-43ff34ac8599@collabora.com?part=4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 5/8] PM / devfreq: rockchip-dfi: use bulk clock APIs
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
` (3 preceding siblings ...)
2026-09-21 20:32 ` [PATCH v2 4/8] PM / devfreq: rockchip-dfi: add NO_INTERRUPT perf capability Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 6/8] clk: rockchip: rk3588: add PCLK_DDR_MON_CH gate branches Sebastian Reichel
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Currently, the only clock rockchip-dfi will ever use is on the rk3399,
namely pclk_ddr_mon. However, this is mainly because every other SoC's
mainline clock tree and bindings are probably lying and not telling us
about some clock gate branches that do exist in hardware, but nothing
happens ever gate.
Get preparations out of the way to fix this by moving to the bulk clock
APIs, which will make handling the one-clock-per-channel cases easier to
deal with.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/devfreq/event/rockchip-dfi.c | 39 +++++++++++++++++++++++++++---------
1 file changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index dd9edfd6a674..b61ec500eaed 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -98,7 +98,7 @@ struct rockchip_dfi {
struct device *dev;
void __iomem *regs;
struct regmap *regmap_pmu;
- struct clk *clk;
+ struct clk_bulk_data *clocks;
int usecount;
struct mutex mutex;
u32 ddr_type;
@@ -122,6 +122,8 @@ struct rockchip_dfi_variant {
int stride;
bool ctrl_single;
unsigned int max_channels;
+ const char * const *clk_names;
+ unsigned int num_clks;
};
static int rockchip_dfi_ddrtype_to_ctrl(struct rockchip_dfi *dfi, u32 *ctrl)
@@ -183,9 +185,10 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
if (dfi->usecount > 1)
goto out;
- ret = clk_prepare_enable(dfi->clk);
+ ret = clk_bulk_prepare_enable(dfi->variant->num_clks, dfi->clocks);
if (ret) {
- dev_err(&dfi->edev->dev, "failed to enable dfi clk: %d\n", ret);
+ dev_err(&dfi->edev->dev, "failed to enable dfi clocks: %pe\n",
+ ERR_PTR(ret));
goto out;
}
@@ -245,7 +248,7 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
break;
}
- clk_disable_unprepare(dfi->clk);
+ clk_bulk_disable_unprepare(dfi->variant->num_clks, dfi->clocks);
out:
mutex_unlock(&dfi->mutex);
}
@@ -721,11 +724,6 @@ static int rk3399_dfi_init(struct rockchip_dfi *dfi)
struct regmap *regmap_pmu = dfi->regmap_pmu;
u32 val;
- dfi->clk = devm_clk_get(dfi->dev, "pclk_ddr_mon");
- if (IS_ERR(dfi->clk))
- return dev_err_probe(dfi->dev, PTR_ERR(dfi->clk),
- "Cannot get the clk pclk_ddr_mon\n");
-
/* get ddr type */
regmap_read(regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
dfi->ddr_type = FIELD_GET(RK3399_PMUGRF_OS_REG2_DDRTYPE, val);
@@ -802,11 +800,17 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi)
return 0;
};
+static const char * const rk3399_clk_names[] = {
+ "pclk_ddr_mon",
+};
+
static const struct rockchip_dfi_variant rk3399_variant = {
.init = rk3399_dfi_init,
.stride = 0x14,
.ctrl_single = true,
.max_channels = 2,
+ .clk_names = rk3399_clk_names,
+ .num_clks = ARRAY_SIZE(rk3399_clk_names),
};
static const struct rockchip_dfi_variant rk3568_variant = {
@@ -837,6 +841,7 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
struct rockchip_dfi *dfi;
struct devfreq_event_desc *desc;
struct device_node *np = pdev->dev.of_node, *node;
+ unsigned int i;
int ret;
dfi = devm_kzalloc(dev, sizeof(*dfi), GFP_KERNEL);
@@ -868,6 +873,22 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
desc->driver_data = dfi;
desc->name = np->name;
+ if (dfi->variant->num_clks) {
+ /* NB: CCF is fine with us leaving this NULL if num_clks = 0 */
+ dfi->clocks = devm_kcalloc(dev, dfi->variant->num_clks,
+ sizeof(*dfi->clocks), GFP_KERNEL);
+ if (!dfi->clocks)
+ return -ENOMEM;
+
+ for (i = 0; i < dfi->variant->num_clks; i++)
+ dfi->clocks[i].id = dfi->variant->clk_names[i];
+
+ ret = devm_clk_bulk_get(dev, dfi->variant->num_clks,
+ dfi->clocks);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get clocks\n");
+ }
+
ret = dfi->variant->init(dfi);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v2 6/8] clk: rockchip: rk3588: add PCLK_DDR_MON_CH gate branches
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
` (4 preceding siblings ...)
2026-09-21 20:32 ` [PATCH v2 5/8] PM / devfreq: rockchip-dfi: use bulk clock APIs Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 7/8] PM / devfreq: rockchip-dfi: make RK3588 use its clocks Sebastian Reichel
2026-09-21 20:32 ` [PATCH v2 8/8] arm64: dts: rockchip: add dfi clocks on RK3588 Sebastian Reichel
7 siblings, 0 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
On the Rockchip RK3588, each memory channel has some bandwidth
monitoring silicon (hence the "DDR_MON"), which is driven by a clock
gated by PCLK_DDR_MON_CH0/1/2/3.
These clock branches were left out of the mainline clock tree until now.
Add them, with the proper CRU reg bits, and the proper parent. They are
given the "CLK_IGNORE_UNUSED" flag, so that older device trees with
newer kernels don't turn off the clocks because they're seen as not in
use.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/clk/rockchip/clk-rk3588.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 24baa0ef9bf3..0485faf27163 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -1349,6 +1349,14 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
COMPOSITE(CLK_DDR_CM0_RTC, "clk_ddr_cm0_rtc", mux_24m_32k_p, CLK_IS_CRITICAL,
RK3588_CLKSEL_CON(166), 5, 1, MFLAGS, 0, 5, DFLAGS,
RK3588_CLKGATE_CON(70), 4, GFLAGS),
+ GATE(PCLK_DDR_MON_CH0, "pclk_ddr_mon_ch0", "pclk_center_root", CLK_IGNORE_UNUSED,
+ RK3588_CLKGATE_CON(20), 1, GFLAGS),
+ GATE(PCLK_DDR_MON_CH1, "pclk_ddr_mon_ch1", "pclk_center_root", CLK_IGNORE_UNUSED,
+ RK3588_CLKGATE_CON(20), 14, GFLAGS),
+ GATE(PCLK_DDR_MON_CH2, "pclk_ddr_mon_ch2", "pclk_center_root", CLK_IGNORE_UNUSED,
+ RK3588_CLKGATE_CON(23), 1, GFLAGS),
+ GATE(PCLK_DDR_MON_CH3, "pclk_ddr_mon_ch3", "pclk_center_root", CLK_IGNORE_UNUSED,
+ RK3588_CLKGATE_CON(23), 14, GFLAGS),
GATE(PCLK_WDT, "pclk_wdt", "pclk_center_root", 0,
RK3588_CLKGATE_CON(70), 7, GFLAGS),
GATE(PCLK_TIMER, "pclk_timer", "pclk_center_root", 0,
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v2 7/8] PM / devfreq: rockchip-dfi: make RK3588 use its clocks
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
` (5 preceding siblings ...)
2026-09-21 20:32 ` [PATCH v2 6/8] clk: rockchip: rk3588: add PCLK_DDR_MON_CH gate branches Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
2026-09-21 20:46 ` sashiko-bot
2026-09-21 20:32 ` [PATCH v2 8/8] arm64: dts: rockchip: add dfi clocks on RK3588 Sebastian Reichel
7 siblings, 1 reply; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
So far, RK3588 doesn't have the pclks for DDRMON used in the driver, as
they weren't modelled before.
However, they are now correctly modelled, so the driver should use them
when possible.
Instead of unconditionally getting them for this SoC, add a new variant
member that specifies whether the driver should let missing clocks
slide. This is needed because we want old device trees to keep
functioning, as otherwise we'd be introducing a breaking change for
literally no functional difference here.
Fill out a clock name list for this variant as well, and hand it to it.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/devfreq/event/rockchip-dfi.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index b61ec500eaed..380361a231a2 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -117,6 +117,18 @@ struct rockchip_dfi {
const struct rockchip_dfi_variant *variant;
};
+/**
+ * struct rockchip_dfi_variant
+ * @init: pointer to the variant-specific initialisation function
+ * @stride: address offset between the DDRMON per-channel instances
+ * @ctrl_single: whether only one DDRMON instance monitors multiple channels
+ * @max_channels: maximum number of memory channels for this SoC
+ * @clk_names: pointer to a constant array of constant clock name strings
+ * @num_clk: the number of elements in the @clk_names array
+ * @clocks_optional: whether not finding the clocks is non-fatal. Set if the
+ * DT binding for this variant didn't require clocks in the
+ * past, so that the driver remains compatible with old DTs.
+ */
struct rockchip_dfi_variant {
int (*init)(struct rockchip_dfi *dfi);
int stride;
@@ -124,6 +136,7 @@ struct rockchip_dfi_variant {
unsigned int max_channels;
const char * const *clk_names;
unsigned int num_clks;
+ bool clocks_optional;
};
static int rockchip_dfi_ddrtype_to_ctrl(struct rockchip_dfi *dfi, u32 *ctrl)
@@ -804,6 +817,11 @@ static const char * const rk3399_clk_names[] = {
"pclk_ddr_mon",
};
+static const char * const rk3588_clk_names[] = {
+ "pclk_ddr_mon_ch0", "pclk_ddr_mon_ch1", "pclk_ddr_mon_ch2",
+ "pclk_ddr_mon_ch3",
+};
+
static const struct rockchip_dfi_variant rk3399_variant = {
.init = rk3399_dfi_init,
.stride = 0x14,
@@ -824,6 +842,9 @@ static const struct rockchip_dfi_variant rk3588_variant = {
.init = rk3588_dfi_init,
.stride = 0x4000,
.max_channels = 4,
+ .clk_names = rk3588_clk_names,
+ .num_clks = ARRAY_SIZE(rk3588_clk_names),
+ .clocks_optional = true,
};
static const struct of_device_id rockchip_dfi_id_match[] = {
@@ -883,8 +904,12 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
for (i = 0; i < dfi->variant->num_clks; i++)
dfi->clocks[i].id = dfi->variant->clk_names[i];
- ret = devm_clk_bulk_get(dev, dfi->variant->num_clks,
- dfi->clocks);
+ if (dfi->variant->clocks_optional)
+ ret = devm_clk_bulk_get_optional(dev, dfi->variant->num_clks,
+ dfi->clocks);
+ else
+ ret = devm_clk_bulk_get(dev, dfi->variant->num_clks,
+ dfi->clocks);
if (ret)
return dev_err_probe(dev, ret, "failed to get clocks\n");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v2 7/8] PM / devfreq: rockchip-dfi: make RK3588 use its clocks
2026-09-21 20:32 ` [PATCH v2 7/8] PM / devfreq: rockchip-dfi: make RK3588 use its clocks Sebastian Reichel
@ 2026-09-21 20:46 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-09-21 20:46 UTC (permalink / raw)
To: Sebastian Reichel; +Cc: linux-clk, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] kerneldoc: mismatch for num_clks in struct rockchip_dfi_variant
--
commit 27e02ec68846e2b57e63f7073dbf4cd24e5115ea
Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
PM / devfreq: rockchip-dfi: make RK3588 use its clocks
This commit updates the RK3588 devfreq driver to utilize its recently modelled
DDRMON clocks. It adds a clocks_optional field to the dfi variant structure
so older device trees remain compatible without introducing a breaking change.
> diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
> index b61ec500eaed9..380361a231a20 100644
> --- a/drivers/devfreq/event/rockchip-dfi.c
> +++ b/drivers/devfreq/event/rockchip-dfi.c
> @@ -117,6 +117,18 @@ struct rockchip_dfi {
> const struct rockchip_dfi_variant *variant;
> };
>
> +/**
> + * struct rockchip_dfi_variant
> + * @init: pointer to the variant-specific initialisation function
> + * @stride: address offset between the DDRMON per-channel instances
> + * @ctrl_single: whether only one DDRMON instance monitors multiple channels
> + * @max_channels: maximum number of memory channels for this SoC
> + * @clk_names: pointer to a constant array of constant clock name strings
> + * @num_clk: the number of elements in the @clk_names array
[Severity: Low]
This isn't a bug, but does this kerneldoc parameter mismatch the struct
definition? The struct member is defined as num_clks, while this block
documents num_clk, which will trigger a kernel-doc script warning.
> + * @clocks_optional: whether not finding the clocks is non-fatal. Set if the
> + * DT binding for this variant didn't require clocks in the
> + * past, so that the driver remains compatible with old DTs.
> + */
> struct rockchip_dfi_variant {
> int (*init)(struct rockchip_dfi *dfi);
> int stride;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921-rockchip-dfi-cleanup-v2-0-43ff34ac8599@collabora.com?part=7
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 8/8] arm64: dts: rockchip: add dfi clocks on RK3588
2026-09-21 20:32 [PATCH v2 0/8] PM / devfreq: rockchip-dfi: cleanups Sebastian Reichel
` (6 preceding siblings ...)
2026-09-21 20:32 ` [PATCH v2 7/8] PM / devfreq: rockchip-dfi: make RK3588 use its clocks Sebastian Reichel
@ 2026-09-21 20:32 ` Sebastian Reichel
7 siblings, 0 replies; 14+ messages in thread
From: Sebastian Reichel @ 2026-09-21 20:32 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Chanwoo Choi,
MyungJoo Ham, Kyungmin Park, Sascha Hauer
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, linux-pm, kernel, Sebastian Reichel
From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
The DFI clocks weren't modelled before and the binding didn't know about
them either. That has changed though, and now we actually need to
specify these clocks.
Add all four clocks for all four channels of monitoring.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 376ad04e0786..ac9299e1197b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -2178,6 +2178,10 @@ qos_vop_m1: qos@fdf82200 {
dfi: dfi@fe060000 {
reg = <0x00 0xfe060000 0x00 0x10000>;
compatible = "rockchip,rk3588-dfi";
+ clocks = <&cru PCLK_DDR_MON_CH0>, <&cru PCLK_DDR_MON_CH1>,
+ <&cru PCLK_DDR_MON_CH2>, <&cru PCLK_DDR_MON_CH3>;
+ clock-names = "pclk_ddr_mon_ch0", "pclk_ddr_mon_ch1",
+ "pclk_ddr_mon_ch2", "pclk_ddr_mon_ch3";
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
<GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread