mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk
@ 2025-04-10 12:07 Alexander Shiyan
  2025-04-10 12:07 ` [PATCH 2/3] clk: rockchip: Add linked gate clock support Alexander Shiyan
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Alexander Shiyan @ 2025-04-10 12:07 UTC (permalink / raw)
  To: barebox; +Cc: Alexander Shiyan

Changing the DDR clock frequency requires special care, this patch
adds the DDR clock driver code from the Linux kernel repository.
While we're here, let's also update drivers/clk/rockchip/Makefile
to make it more readable.

Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
 drivers/clk/rockchip/Makefile       |  29 ++++--
 drivers/clk/rockchip/clk-ddr.c      | 131 ++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk-pll.c      |   6 +-
 drivers/clk/rockchip/clk.c          |   7 ++
 drivers/clk/rockchip/clk.h          |   1 +
 include/soc/rockchip/rockchip_sip.h |  23 +++++
 6 files changed, 188 insertions(+), 9 deletions(-)
 create mode 100644 drivers/clk/rockchip/clk-ddr.c
 create mode 100644 include/soc/rockchip/rockchip_sip.h

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f01014da0c..8d752d11b9 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -1,8 +1,21 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
-obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
-obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
-obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
-obj-$(CONFIG_ARCH_RK3399) += clk-rk3399.o
-obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
-obj-$(CONFIG_ARCH_RK3588) += clk-rk3588.o rst-rk3588.o
+# SPDX-License-Identifier: GPL-2.0
+#
+# Rockchip Clock specific Makefile
+#
+
+obj-y += clk-rockchip.o
+
+clk-rockchip-y += clk.o
+clk-rockchip-y += clk-pll.o
+clk-rockchip-y += clk-cpu.o
+clk-rockchip-y += clk-inverter.o
+clk-rockchip-y += clk-mmc-phase.o
+clk-rockchip-y += clk-muxgrf.o
+clk-rockchip-y += clk-ddr.o
+
+clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
+
+obj-$(CONFIG_ARCH_RK3188)	+= clk-rk3188.o
+obj-$(CONFIG_ARCH_RK3288)	+= clk-rk3288.o
+obj-$(CONFIG_ARCH_RK3568)	+= clk-rk3568.o
+obj-$(CONFIG_ARCH_RK3588)	+= clk-rk3588.o rst-rk3588.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 0000000000..7b10f1533b
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang <hl@rock-chips.com>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include <soc/rockchip/rockchip_sip.h>
+
+#include "clk.h"
+
+struct rockchip_ddrclk {
+	struct clk_hw	hw;
+	void __iomem	*reg_base;
+	int		mux_offset;
+	int		mux_shift;
+	int		mux_width;
+	int		div_shift;
+	int		div_width;
+	int		ddr_flag;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
+
+static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
+		      ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
+		      0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static unsigned long
+rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
+		      ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
+		      0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
+					   unsigned long rate,
+					   unsigned long *prate)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
+		      ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
+		      0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static int rockchip_ddrclk_get_parent(struct clk_hw *hw)
+{
+	struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+	u32 val;
+
+	val = readl(ddrclk->reg_base +
+			ddrclk->mux_offset) >> ddrclk->mux_shift;
+	val &= GENMASK(ddrclk->mux_width - 1, 0);
+
+	return val;
+}
+
+static const struct clk_ops rockchip_ddrclk_sip_ops = {
+	.recalc_rate = rockchip_ddrclk_sip_recalc_rate,
+	.set_rate = rockchip_ddrclk_sip_set_rate,
+	.round_rate = rockchip_ddrclk_sip_round_rate,
+	.get_parent = rockchip_ddrclk_get_parent,
+};
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+					 const char *const *parent_names,
+					 u8 num_parents, int mux_offset,
+					 int mux_shift, int mux_width,
+					 int div_shift, int div_width,
+					 int ddr_flag, void __iomem *reg_base,
+					 spinlock_t *lock)
+{
+	struct rockchip_ddrclk *ddrclk;
+	struct clk_init_data init;
+	struct clk *clk;
+
+	ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
+	if (!ddrclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.parent_names = parent_names;
+	init.num_parents = num_parents;
+
+	init.flags = flags;
+	init.flags |= CLK_SET_RATE_NO_REPARENT;
+
+	switch (ddr_flag) {
+	case ROCKCHIP_DDRCLK_SIP:
+		init.ops = &rockchip_ddrclk_sip_ops;
+		break;
+	default:
+		pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
+		kfree(ddrclk);
+		return ERR_PTR(-EINVAL);
+	}
+
+	ddrclk->reg_base = reg_base;
+	ddrclk->hw.init = &init;
+	ddrclk->mux_offset = mux_offset;
+	ddrclk->mux_shift = mux_shift;
+	ddrclk->mux_width = mux_width;
+	ddrclk->div_shift = div_shift;
+	ddrclk->div_width = div_width;
+	ddrclk->ddr_flag = ddr_flag;
+
+	clk = clk_register(NULL, &ddrclk->hw);
+	if (IS_ERR(clk))
+		kfree(ddrclk);
+
+	return clk;
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk);
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index b4152b03b1..2931c09ad5 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -913,7 +913,10 @@ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned
 	}
 	rate64 = rate64 >> cur.s;
 
-	return (unsigned long)rate64;
+	if (pll->type == pll_rk3588_ddr)
+		return (unsigned long)rate64 * 2;
+	else
+		return (unsigned long)rate64;
 }
 
 static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
@@ -1169,6 +1172,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
 		break;
 	case pll_rk3588:
 	case pll_rk3588_core:
+	case pll_rk3588_ddr:
 		if (!pll->rate_table)
 			init.ops = &rockchip_rk3588_pll_clk_norate_ops;
 		else
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index a154495efd..127b79e2c8 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -497,6 +497,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 				list->gate_flags, flags, &ctx->lock);
 			break;
 		case branch_ddrclk:
+			clk = rockchip_clk_register_ddrclk(
+				list->name, list->flags,
+				list->parent_names, list->num_parents,
+				list->muxdiv_offset, list->mux_shift,
+				list->mux_width, list->div_shift,
+				list->div_width, list->div_flags,
+				ctx->reg_base, &ctx->lock);
 			break;
 		}
 
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index a451229326..6665f8ac90 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -267,6 +267,7 @@ enum rockchip_pll_type {
 	pll_rk3399,
 	pll_rk3588,
 	pll_rk3588_core,
+	pll_rk3588_ddr,
 };
 
 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
new file mode 100644
index 0000000000..501ad1fedb
--- /dev/null
+++ b/include/soc/rockchip/rockchip_sip.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang <hl@rock-chips.com>
+ */
+#ifndef __SOC_ROCKCHIP_SIP_H
+#define __SOC_ROCKCHIP_SIP_H
+
+#define ROCKCHIP_SIP_SUSPEND_MODE		0x82000003
+#define ROCKCHIP_SLEEP_PD_CONFIG		0xff
+
+#define ROCKCHIP_SIP_DRAM_FREQ			0x82000008
+#define ROCKCHIP_SIP_CONFIG_DRAM_INIT		0x00
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE	0x01
+#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE	0x02
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR	0x03
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW		0x04
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE	0x05
+#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ	0x06
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM	0x07
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD	0x08
+
+#endif
-- 
2.39.1




^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/3] clk: rockchip: Add linked gate clock support
  2025-04-10 12:07 [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Alexander Shiyan
@ 2025-04-10 12:07 ` Alexander Shiyan
  2025-04-10 12:07 ` [PATCH 3/3] clk: rockchip: Update RK3188 driver Alexander Shiyan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Alexander Shiyan @ 2025-04-10 12:07 UTC (permalink / raw)
  To: barebox; +Cc: Alexander Shiyan

Recent Rockchip SoCs have a new hardware block called Native Interface
Unit (NIU), which gates clocks to devices behind them. These clock
gates will only have a running output clock when all of the following
conditions are met:

1. the parent clock is enabled
2. the enable bit is set correctly
3. the linked clock is enabled

To handle them this code registers them as a normal gate type clock,
which takes care of condition 1 + 2. Thus the complete handling
of these clocks has been moved into its own driver.

Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
 drivers/clk/rockchip/Makefile    |  1 +
 drivers/clk/rockchip/clk.c       | 67 ++++++++++++++++++++++++++------
 drivers/clk/rockchip/clk.h       | 25 +++++++++++-
 drivers/clk/rockchip/gate-link.c | 44 +++++++++++++++++++++
 4 files changed, 123 insertions(+), 14 deletions(-)
 create mode 100644 drivers/clk/rockchip/gate-link.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 8d752d11b9..b1ab402003 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -12,6 +12,7 @@ clk-rockchip-y += clk-inverter.o
 clk-rockchip-y += clk-mmc-phase.o
 clk-rockchip-y += clk-muxgrf.o
 clk-rockchip-y += clk-ddr.o
+clk-rockchip-y += gate-link.o
 
 clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
 
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 127b79e2c8..b162ca9798 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -240,7 +240,7 @@ static struct clk *rockchip_clk_register_frac_branch(
 			return mux_clk;
 		}
 
-		rockchip_clk_add_lookup(ctx, mux_clk, child->id);
+		rockchip_clk_set_lookup(ctx, mux_clk, child->id);
 
 		/* notifier on the fraction divider to catch rate changes */
 		if (frac->mux_frac_idx >= 0) {
@@ -350,14 +350,6 @@ void rockchip_clk_of_add_provider(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_of_add_provider);
 
-void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
-			     struct clk *clk, unsigned int id)
-{
-	if (ctx->clk_data.clks && id)
-		ctx->clk_data.clks[id] = clk;
-}
-EXPORT_SYMBOL_GPL(rockchip_clk_add_lookup);
-
 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 				struct rockchip_pll_clock *list,
 				unsigned int nr_pll, int grf_lock_offset)
@@ -378,7 +370,7 @@ void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 			continue;
 		}
 
-		rockchip_clk_add_lookup(ctx, clk, list->id);
+		rockchip_clk_set_lookup(ctx, clk, list->id);
 	}
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
@@ -400,6 +392,29 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id);
 
+static struct device *rockchip_clk_register_gate_link(
+		struct device *parent_dev,
+		struct rockchip_clk_provider *ctx,
+		struct rockchip_clk_branch *clkbr)
+{
+	struct rockchip_gate_link_platdata gate_link_pdata = {
+		.ctx = ctx,
+		.clkbr = clkbr,
+	};
+	struct device *dev;
+	int ret;
+
+	dev = device_alloc("rockchip-gate-link-clk", clkbr->id);
+	dev->parent = parent_dev;
+	dev->platform_data = &gate_link_pdata;
+
+	ret = platform_device_register(dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return dev;
+}
+
 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 				    struct rockchip_clk_branch *list,
 				    unsigned int nr_clk)
@@ -505,6 +520,9 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 				list->div_width, list->div_flags,
 				ctx->reg_base, &ctx->lock);
 			break;
+		case branch_linked_gate:
+			/* must be registered late, fall-through for error message */
+			break;
 		}
 
 		/* none of the cases above matched */
@@ -520,11 +538,36 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 			continue;
 		}
 
-		rockchip_clk_add_lookup(ctx, clk, list->id);
+		rockchip_clk_set_lookup(ctx, clk, list->id);
 	}
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_register_branches);
 
+void rockchip_clk_register_late_branches(struct device *dev,
+					 struct rockchip_clk_provider *ctx,
+					 struct rockchip_clk_branch *list,
+					 unsigned int nr_clk)
+{
+	unsigned int idx;
+
+	for (idx = 0; idx < nr_clk; idx++, list++) {
+		struct device *pdev = NULL;
+
+		switch (list->branch_type) {
+		case branch_linked_gate:
+			pdev = rockchip_clk_register_gate_link(dev, ctx, list);
+			break;
+		default:
+			dev_err(dev, "unknown clock type %d\n", list->branch_type);
+			break;
+		}
+
+		if (!pdev)
+			dev_err(dev, "failed to register device for clock %s\n", list->name);
+	}
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_register_late_branches);
+
 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 				  unsigned int lookup_id,
 				  const char *name, const char *const *parent_names,
@@ -544,7 +587,7 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 		return;
 	}
 
-	rockchip_clk_add_lookup(ctx, clk, lookup_id);
+	rockchip_clk_set_lookup(ctx, clk, lookup_id);
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
 
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 6665f8ac90..d201e753ef 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -500,6 +500,7 @@ enum rockchip_clk_branch_type {
 	branch_divider,
 	branch_fraction_divider,
 	branch_gate,
+	branch_linked_gate,
 	branch_mmc,
 	branch_inverter,
 	branch_factor,
@@ -883,17 +884,37 @@ struct rockchip_clk_branch {
 #define SGRF_GATE(_id, cname, pname)				\
 		FACTOR(_id, cname, pname, 0, 1, 1)
 
+static inline struct clk *rockchip_clk_get_lookup(struct rockchip_clk_provider *ctx,
+						  unsigned int id)
+{
+	return ctx->clk_data.clks[id];
+}
+
+static inline void rockchip_clk_set_lookup(struct rockchip_clk_provider *ctx,
+					   struct clk *clk, unsigned int id)
+{
+	ctx->clk_data.clks[id] = clk;
+}
+
+struct rockchip_gate_link_platdata {
+	struct rockchip_clk_provider *ctx;
+	struct rockchip_clk_branch *clkbr;
+};
+
 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
 			void __iomem *base, unsigned long nr_clks);
 void rockchip_clk_of_add_provider(struct device_node *np,
 				struct rockchip_clk_provider *ctx);
-void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
-			     struct clk *clk, unsigned int id);
 unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
 					   unsigned int nr_clk);
 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 				    struct rockchip_clk_branch *list,
 				    unsigned int nr_clk);
+void rockchip_clk_register_late_branches(struct device *dev,
+					 struct rockchip_clk_provider *ctx,
+					 struct rockchip_clk_branch *list,
+					 unsigned int nr_clk);
+
 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 				struct rockchip_pll_clock *pll_list,
 				unsigned int nr_pll, int grf_lock_offset);
diff --git a/drivers/clk/rockchip/gate-link.c b/drivers/clk/rockchip/gate-link.c
new file mode 100644
index 0000000000..710e77892a
--- /dev/null
+++ b/drivers/clk/rockchip/gate-link.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 Collabora Ltd.
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#include <common.h>
+
+#include "clk.h"
+
+static int rk_clk_gate_link_register(struct device *dev,
+				     struct rockchip_clk_provider *ctx,
+				     struct rockchip_clk_branch *clkbr)
+{
+	unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT;
+	struct clk *clk;
+
+	clk = clk_register_gate(dev, clkbr->name, clkbr->parent_names[0],
+				flags, ctx->reg_base + clkbr->gate_offset,
+				clkbr->gate_shift, clkbr->gate_flags,
+				&ctx->lock);
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	rockchip_clk_set_lookup(ctx, clk, clkbr->id);
+
+	return 0;
+}
+
+static int rk_clk_gate_link_probe(struct device *dev)
+{
+	struct rockchip_gate_link_platdata *pdata = dev->platform_data;
+	if (!pdata)
+		return dev_err_probe(dev, -ENODEV, "missing platform data");
+
+	return rk_clk_gate_link_register(dev, pdata->ctx, pdata->clkbr);
+}
+
+static struct driver rk_clk_gate_link_driver = {
+	.probe	= rk_clk_gate_link_probe,
+	.name	= "rockchip-gate-link-clk",
+};
+core_platform_driver(rk_clk_gate_link_driver);
-- 
2.39.1




^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/3] clk: rockchip: Update RK3188 driver
  2025-04-10 12:07 [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Alexander Shiyan
  2025-04-10 12:07 ` [PATCH 2/3] clk: rockchip: Add linked gate clock support Alexander Shiyan
@ 2025-04-10 12:07 ` Alexander Shiyan
  2025-04-14 11:32 ` [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Sascha Hauer
  2025-04-15  7:48 ` Sascha Hauer
  3 siblings, 0 replies; 6+ messages in thread
From: Alexander Shiyan @ 2025-04-10 12:07 UTC (permalink / raw)
  To: barebox; +Cc: Alexander Shiyan

This patch updates the RK3188-clk driver to reflect the latest
changes from the Linux kernel repository.

Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
 drivers/clk/rockchip/clk-rk3188.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 7e8c1f0d03..93a597ed4c 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -338,7 +338,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif0", "ext_cif0", 0,
 			RK2928_CLKGATE_CON(3), 3, GFLAGS),
-	INVERTER(0, "pclk_cif0", "pclkin_cif0",
+	INVERTER(PCLK_CIF0, "pclk_cif0", "pclkin_cif0",
 			RK2928_CLKSEL_CON(30), 8, IFLAGS),
 
 	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
@@ -596,7 +596,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 
 	GATE(0, "pclkin_cif1", "ext_cif1", 0,
 			RK2928_CLKGATE_CON(3), 4, GFLAGS),
-	INVERTER(0, "pclk_cif1", "pclkin_cif1",
+	INVERTER(PCLK_CIF1, "pclk_cif1", "pclkin_cif1",
 			RK2928_CLKSEL_CON(30), 12, IFLAGS),
 
 	COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
-- 
2.39.1




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk
  2025-04-10 12:07 [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Alexander Shiyan
  2025-04-10 12:07 ` [PATCH 2/3] clk: rockchip: Add linked gate clock support Alexander Shiyan
  2025-04-10 12:07 ` [PATCH 3/3] clk: rockchip: Update RK3188 driver Alexander Shiyan
@ 2025-04-14 11:32 ` Sascha Hauer
  2025-04-15  7:48 ` Sascha Hauer
  3 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2025-04-14 11:32 UTC (permalink / raw)
  To: barebox, Alexander Shiyan


On Thu, 10 Apr 2025 15:07:43 +0300, Alexander Shiyan wrote:
> Changing the DDR clock frequency requires special care, this patch
> adds the DDR clock driver code from the Linux kernel repository.
> While we're here, let's also update drivers/clk/rockchip/Makefile
> to make it more readable.
> 
> 

Applied, thanks!

[1/3] clk: rockchip: Add new clock-type for the ddrclk
      https://git.pengutronix.de/cgit/barebox/commit/?id=4e7465c80e36 (link may not be stable)
[2/3] clk: rockchip: Add linked gate clock support
      https://git.pengutronix.de/cgit/barebox/commit/?id=0336060c12ad (link may not be stable)
[3/3] clk: rockchip: Update RK3188 driver
      https://git.pengutronix.de/cgit/barebox/commit/?id=8ca5cf10b81e (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk
  2025-04-10 12:07 [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Alexander Shiyan
                   ` (2 preceding siblings ...)
  2025-04-14 11:32 ` [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Sascha Hauer
@ 2025-04-15  7:48 ` Sascha Hauer
  2025-04-15  7:56   ` Alexander Shiyan
  3 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2025-04-15  7:48 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: barebox

Hi Alexander,

On Thu, Apr 10, 2025 at 03:07:43PM +0300, Alexander Shiyan wrote:
> Changing the DDR clock frequency requires special care, this patch
> adds the DDR clock driver code from the Linux kernel repository.
> While we're here, let's also update drivers/clk/rockchip/Makefile
> to make it more readable.

This patch currently breaks build on ARMv7 Rockchip SoCs. It fails with
undefined reference to __arm_smccc_smc.

Looking at upstream Linux it seems that this driver is only used on
RK3399, the SoC we just removed support for.

Where do we go from here? I could fix this patch, but as it's unused I
could equally well drop it without loosing anything.

Sascha

> 
> Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
> ---
>  drivers/clk/rockchip/Makefile       |  29 ++++--
>  drivers/clk/rockchip/clk-ddr.c      | 131 ++++++++++++++++++++++++++++
>  drivers/clk/rockchip/clk-pll.c      |   6 +-
>  drivers/clk/rockchip/clk.c          |   7 ++
>  drivers/clk/rockchip/clk.h          |   1 +
>  include/soc/rockchip/rockchip_sip.h |  23 +++++
>  6 files changed, 188 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/clk/rockchip/clk-ddr.c
>  create mode 100644 include/soc/rockchip/rockchip_sip.h
> 
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index f01014da0c..8d752d11b9 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -1,8 +1,21 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
> -obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
> -obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
> -obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
> -obj-$(CONFIG_ARCH_RK3399) += clk-rk3399.o
> -obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
> -obj-$(CONFIG_ARCH_RK3588) += clk-rk3588.o rst-rk3588.o
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Rockchip Clock specific Makefile
> +#
> +
> +obj-y += clk-rockchip.o
> +
> +clk-rockchip-y += clk.o
> +clk-rockchip-y += clk-pll.o
> +clk-rockchip-y += clk-cpu.o
> +clk-rockchip-y += clk-inverter.o
> +clk-rockchip-y += clk-mmc-phase.o
> +clk-rockchip-y += clk-muxgrf.o
> +clk-rockchip-y += clk-ddr.o
> +
> +clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
> +
> +obj-$(CONFIG_ARCH_RK3188)	+= clk-rk3188.o
> +obj-$(CONFIG_ARCH_RK3288)	+= clk-rk3288.o
> +obj-$(CONFIG_ARCH_RK3568)	+= clk-rk3568.o
> +obj-$(CONFIG_ARCH_RK3588)	+= clk-rk3588.o rst-rk3588.o
> diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
> new file mode 100644
> index 0000000000..7b10f1533b
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-ddr.c
> @@ -0,0 +1,131 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> + * Author: Lin Huang <hl@rock-chips.com>
> + */
> +
> +#include <common.h>
> +#include <linux/arm-smccc.h>
> +#include <soc/rockchip/rockchip_sip.h>
> +
> +#include "clk.h"
> +
> +struct rockchip_ddrclk {
> +	struct clk_hw	hw;
> +	void __iomem	*reg_base;
> +	int		mux_offset;
> +	int		mux_shift;
> +	int		mux_width;
> +	int		div_shift;
> +	int		div_width;
> +	int		ddr_flag;
> +};
> +
> +#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
> +
> +static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
> +					unsigned long prate)
> +{
> +	struct arm_smccc_res res;
> +
> +	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
> +		      ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
> +		      0, 0, 0, 0, &res);
> +
> +	return res.a0;
> +}
> +
> +static unsigned long
> +rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
> +				unsigned long parent_rate)
> +{
> +	struct arm_smccc_res res;
> +
> +	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
> +		      ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
> +		      0, 0, 0, 0, &res);
> +
> +	return res.a0;
> +}
> +
> +static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
> +					   unsigned long rate,
> +					   unsigned long *prate)
> +{
> +	struct arm_smccc_res res;
> +
> +	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
> +		      ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
> +		      0, 0, 0, 0, &res);
> +
> +	return res.a0;
> +}
> +
> +static int rockchip_ddrclk_get_parent(struct clk_hw *hw)
> +{
> +	struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
> +	u32 val;
> +
> +	val = readl(ddrclk->reg_base +
> +			ddrclk->mux_offset) >> ddrclk->mux_shift;
> +	val &= GENMASK(ddrclk->mux_width - 1, 0);
> +
> +	return val;
> +}
> +
> +static const struct clk_ops rockchip_ddrclk_sip_ops = {
> +	.recalc_rate = rockchip_ddrclk_sip_recalc_rate,
> +	.set_rate = rockchip_ddrclk_sip_set_rate,
> +	.round_rate = rockchip_ddrclk_sip_round_rate,
> +	.get_parent = rockchip_ddrclk_get_parent,
> +};
> +
> +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
> +					 const char *const *parent_names,
> +					 u8 num_parents, int mux_offset,
> +					 int mux_shift, int mux_width,
> +					 int div_shift, int div_width,
> +					 int ddr_flag, void __iomem *reg_base,
> +					 spinlock_t *lock)
> +{
> +	struct rockchip_ddrclk *ddrclk;
> +	struct clk_init_data init;
> +	struct clk *clk;
> +
> +	ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
> +	if (!ddrclk)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = name;
> +	init.parent_names = parent_names;
> +	init.num_parents = num_parents;
> +
> +	init.flags = flags;
> +	init.flags |= CLK_SET_RATE_NO_REPARENT;
> +
> +	switch (ddr_flag) {
> +	case ROCKCHIP_DDRCLK_SIP:
> +		init.ops = &rockchip_ddrclk_sip_ops;
> +		break;
> +	default:
> +		pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
> +		kfree(ddrclk);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	ddrclk->reg_base = reg_base;
> +	ddrclk->hw.init = &init;
> +	ddrclk->mux_offset = mux_offset;
> +	ddrclk->mux_shift = mux_shift;
> +	ddrclk->mux_width = mux_width;
> +	ddrclk->div_shift = div_shift;
> +	ddrclk->div_width = div_width;
> +	ddrclk->ddr_flag = ddr_flag;
> +
> +	clk = clk_register(NULL, &ddrclk->hw);
> +	if (IS_ERR(clk))
> +		kfree(ddrclk);
> +
> +	return clk;
> +}
> +EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk);
> diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
> index b4152b03b1..2931c09ad5 100644
> --- a/drivers/clk/rockchip/clk-pll.c
> +++ b/drivers/clk/rockchip/clk-pll.c
> @@ -913,7 +913,10 @@ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned
>  	}
>  	rate64 = rate64 >> cur.s;
>  
> -	return (unsigned long)rate64;
> +	if (pll->type == pll_rk3588_ddr)
> +		return (unsigned long)rate64 * 2;
> +	else
> +		return (unsigned long)rate64;
>  }
>  
>  static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
> @@ -1169,6 +1172,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
>  		break;
>  	case pll_rk3588:
>  	case pll_rk3588_core:
> +	case pll_rk3588_ddr:
>  		if (!pll->rate_table)
>  			init.ops = &rockchip_rk3588_pll_clk_norate_ops;
>  		else
> diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
> index a154495efd..127b79e2c8 100644
> --- a/drivers/clk/rockchip/clk.c
> +++ b/drivers/clk/rockchip/clk.c
> @@ -497,6 +497,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
>  				list->gate_flags, flags, &ctx->lock);
>  			break;
>  		case branch_ddrclk:
> +			clk = rockchip_clk_register_ddrclk(
> +				list->name, list->flags,
> +				list->parent_names, list->num_parents,
> +				list->muxdiv_offset, list->mux_shift,
> +				list->mux_width, list->div_shift,
> +				list->div_width, list->div_flags,
> +				ctx->reg_base, &ctx->lock);
>  			break;
>  		}
>  
> diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> index a451229326..6665f8ac90 100644
> --- a/drivers/clk/rockchip/clk.h
> +++ b/drivers/clk/rockchip/clk.h
> @@ -267,6 +267,7 @@ enum rockchip_pll_type {
>  	pll_rk3399,
>  	pll_rk3588,
>  	pll_rk3588_core,
> +	pll_rk3588_ddr,
>  };
>  
>  #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
> diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
> new file mode 100644
> index 0000000000..501ad1fedb
> --- /dev/null
> +++ b/include/soc/rockchip/rockchip_sip.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
> + * Author: Lin Huang <hl@rock-chips.com>
> + */
> +#ifndef __SOC_ROCKCHIP_SIP_H
> +#define __SOC_ROCKCHIP_SIP_H
> +
> +#define ROCKCHIP_SIP_SUSPEND_MODE		0x82000003
> +#define ROCKCHIP_SLEEP_PD_CONFIG		0xff
> +
> +#define ROCKCHIP_SIP_DRAM_FREQ			0x82000008
> +#define ROCKCHIP_SIP_CONFIG_DRAM_INIT		0x00
> +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE	0x01
> +#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE	0x02
> +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR	0x03
> +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW		0x04
> +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE	0x05
> +#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ	0x06
> +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM	0x07
> +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD	0x08
> +
> +#endif
> -- 
> 2.39.1
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk
  2025-04-15  7:48 ` Sascha Hauer
@ 2025-04-15  7:56   ` Alexander Shiyan
  0 siblings, 0 replies; 6+ messages in thread
From: Alexander Shiyan @ 2025-04-15  7:56 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hello.

Good catch, I thought it was used even in RK3588 because
there are mentions of DDRPLL in the datasheet.
Perhaps the right solution in this case would be to remove this unit.

вт, 15 апр. 2025 г. в 10:48, Sascha Hauer <s.hauer@pengutronix.de>:
>
> Hi Alexander,
>
> On Thu, Apr 10, 2025 at 03:07:43PM +0300, Alexander Shiyan wrote:
> > Changing the DDR clock frequency requires special care, this patch
> > adds the DDR clock driver code from the Linux kernel repository.
> > While we're here, let's also update drivers/clk/rockchip/Makefile
> > to make it more readable.
>
> This patch currently breaks build on ARMv7 Rockchip SoCs. It fails with
> undefined reference to __arm_smccc_smc.
>
> Looking at upstream Linux it seems that this driver is only used on
> RK3399, the SoC we just removed support for.
>
> Where do we go from here? I could fix this patch, but as it's unused I
> could equally well drop it without loosing anything.
>
> Sascha
>
> >
> > Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
> > ---
> >  drivers/clk/rockchip/Makefile       |  29 ++++--
> >  drivers/clk/rockchip/clk-ddr.c      | 131 ++++++++++++++++++++++++++++
> >  drivers/clk/rockchip/clk-pll.c      |   6 +-
> >  drivers/clk/rockchip/clk.c          |   7 ++
> >  drivers/clk/rockchip/clk.h          |   1 +
> >  include/soc/rockchip/rockchip_sip.h |  23 +++++
> >  6 files changed, 188 insertions(+), 9 deletions(-)
> >  create mode 100644 drivers/clk/rockchip/clk-ddr.c
> >  create mode 100644 include/soc/rockchip/rockchip_sip.h
> >
> > diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> > index f01014da0c..8d752d11b9 100644
> > --- a/drivers/clk/rockchip/Makefile
> > +++ b/drivers/clk/rockchip/Makefile
> > @@ -1,8 +1,21 @@
> > -# SPDX-License-Identifier: GPL-2.0-only
> > -obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
> > -obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
> > -obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
> > -obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
> > -obj-$(CONFIG_ARCH_RK3399) += clk-rk3399.o
> > -obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
> > -obj-$(CONFIG_ARCH_RK3588) += clk-rk3588.o rst-rk3588.o
> > +# SPDX-License-Identifier: GPL-2.0
> > +#
> > +# Rockchip Clock specific Makefile
> > +#
> > +
> > +obj-y += clk-rockchip.o
> > +
> > +clk-rockchip-y += clk.o
> > +clk-rockchip-y += clk-pll.o
> > +clk-rockchip-y += clk-cpu.o
> > +clk-rockchip-y += clk-inverter.o
> > +clk-rockchip-y += clk-mmc-phase.o
> > +clk-rockchip-y += clk-muxgrf.o
> > +clk-rockchip-y += clk-ddr.o
> > +
> > +clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
> > +
> > +obj-$(CONFIG_ARCH_RK3188)    += clk-rk3188.o
> > +obj-$(CONFIG_ARCH_RK3288)    += clk-rk3288.o
> > +obj-$(CONFIG_ARCH_RK3568)    += clk-rk3568.o
> > +obj-$(CONFIG_ARCH_RK3588)    += clk-rk3588.o rst-rk3588.o
> > diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
> > new file mode 100644
> > index 0000000000..7b10f1533b
> > --- /dev/null
> > +++ b/drivers/clk/rockchip/clk-ddr.c
> > @@ -0,0 +1,131 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> > + * Author: Lin Huang <hl@rock-chips.com>
> > + */
> > +
> > +#include <common.h>
> > +#include <linux/arm-smccc.h>
> > +#include <soc/rockchip/rockchip_sip.h>
> > +
> > +#include "clk.h"
> > +
> > +struct rockchip_ddrclk {
> > +     struct clk_hw   hw;
> > +     void __iomem    *reg_base;
> > +     int             mux_offset;
> > +     int             mux_shift;
> > +     int             mux_width;
> > +     int             div_shift;
> > +     int             div_width;
> > +     int             ddr_flag;
> > +};
> > +
> > +#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
> > +
> > +static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
> > +                                     unsigned long prate)
> > +{
> > +     struct arm_smccc_res res;
> > +
> > +     arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
> > +                   ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
> > +                   0, 0, 0, 0, &res);
> > +
> > +     return res.a0;
> > +}
> > +
> > +static unsigned long
> > +rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
> > +                             unsigned long parent_rate)
> > +{
> > +     struct arm_smccc_res res;
> > +
> > +     arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
> > +                   ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
> > +                   0, 0, 0, 0, &res);
> > +
> > +     return res.a0;
> > +}
> > +
> > +static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
> > +                                        unsigned long rate,
> > +                                        unsigned long *prate)
> > +{
> > +     struct arm_smccc_res res;
> > +
> > +     arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
> > +                   ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
> > +                   0, 0, 0, 0, &res);
> > +
> > +     return res.a0;
> > +}
> > +
> > +static int rockchip_ddrclk_get_parent(struct clk_hw *hw)
> > +{
> > +     struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
> > +     u32 val;
> > +
> > +     val = readl(ddrclk->reg_base +
> > +                     ddrclk->mux_offset) >> ddrclk->mux_shift;
> > +     val &= GENMASK(ddrclk->mux_width - 1, 0);
> > +
> > +     return val;
> > +}
> > +
> > +static const struct clk_ops rockchip_ddrclk_sip_ops = {
> > +     .recalc_rate = rockchip_ddrclk_sip_recalc_rate,
> > +     .set_rate = rockchip_ddrclk_sip_set_rate,
> > +     .round_rate = rockchip_ddrclk_sip_round_rate,
> > +     .get_parent = rockchip_ddrclk_get_parent,
> > +};
> > +
> > +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
> > +                                      const char *const *parent_names,
> > +                                      u8 num_parents, int mux_offset,
> > +                                      int mux_shift, int mux_width,
> > +                                      int div_shift, int div_width,
> > +                                      int ddr_flag, void __iomem *reg_base,
> > +                                      spinlock_t *lock)
> > +{
> > +     struct rockchip_ddrclk *ddrclk;
> > +     struct clk_init_data init;
> > +     struct clk *clk;
> > +
> > +     ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
> > +     if (!ddrclk)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     init.name = name;
> > +     init.parent_names = parent_names;
> > +     init.num_parents = num_parents;
> > +
> > +     init.flags = flags;
> > +     init.flags |= CLK_SET_RATE_NO_REPARENT;
> > +
> > +     switch (ddr_flag) {
> > +     case ROCKCHIP_DDRCLK_SIP:
> > +             init.ops = &rockchip_ddrclk_sip_ops;
> > +             break;
> > +     default:
> > +             pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
> > +             kfree(ddrclk);
> > +             return ERR_PTR(-EINVAL);
> > +     }
> > +
> > +     ddrclk->reg_base = reg_base;
> > +     ddrclk->hw.init = &init;
> > +     ddrclk->mux_offset = mux_offset;
> > +     ddrclk->mux_shift = mux_shift;
> > +     ddrclk->mux_width = mux_width;
> > +     ddrclk->div_shift = div_shift;
> > +     ddrclk->div_width = div_width;
> > +     ddrclk->ddr_flag = ddr_flag;
> > +
> > +     clk = clk_register(NULL, &ddrclk->hw);
> > +     if (IS_ERR(clk))
> > +             kfree(ddrclk);
> > +
> > +     return clk;
> > +}
> > +EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk);
> > diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
> > index b4152b03b1..2931c09ad5 100644
> > --- a/drivers/clk/rockchip/clk-pll.c
> > +++ b/drivers/clk/rockchip/clk-pll.c
> > @@ -913,7 +913,10 @@ static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw, unsigned
> >       }
> >       rate64 = rate64 >> cur.s;
> >
> > -     return (unsigned long)rate64;
> > +     if (pll->type == pll_rk3588_ddr)
> > +             return (unsigned long)rate64 * 2;
> > +     else
> > +             return (unsigned long)rate64;
> >  }
> >
> >  static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
> > @@ -1169,6 +1172,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
> >               break;
> >       case pll_rk3588:
> >       case pll_rk3588_core:
> > +     case pll_rk3588_ddr:
> >               if (!pll->rate_table)
> >                       init.ops = &rockchip_rk3588_pll_clk_norate_ops;
> >               else
> > diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
> > index a154495efd..127b79e2c8 100644
> > --- a/drivers/clk/rockchip/clk.c
> > +++ b/drivers/clk/rockchip/clk.c
> > @@ -497,6 +497,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
> >                               list->gate_flags, flags, &ctx->lock);
> >                       break;
> >               case branch_ddrclk:
> > +                     clk = rockchip_clk_register_ddrclk(
> > +                             list->name, list->flags,
> > +                             list->parent_names, list->num_parents,
> > +                             list->muxdiv_offset, list->mux_shift,
> > +                             list->mux_width, list->div_shift,
> > +                             list->div_width, list->div_flags,
> > +                             ctx->reg_base, &ctx->lock);
> >                       break;
> >               }
> >
> > diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> > index a451229326..6665f8ac90 100644
> > --- a/drivers/clk/rockchip/clk.h
> > +++ b/drivers/clk/rockchip/clk.h
> > @@ -267,6 +267,7 @@ enum rockchip_pll_type {
> >       pll_rk3399,
> >       pll_rk3588,
> >       pll_rk3588_core,
> > +     pll_rk3588_ddr,
> >  };
> >
> >  #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,   \
> > diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
> > new file mode 100644
> > index 0000000000..501ad1fedb
> > --- /dev/null
> > +++ b/include/soc/rockchip/rockchip_sip.h
> > @@ -0,0 +1,23 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
> > + * Author: Lin Huang <hl@rock-chips.com>
> > + */
> > +#ifndef __SOC_ROCKCHIP_SIP_H
> > +#define __SOC_ROCKCHIP_SIP_H
> > +
> > +#define ROCKCHIP_SIP_SUSPEND_MODE            0x82000003
> > +#define ROCKCHIP_SLEEP_PD_CONFIG             0xff
> > +
> > +#define ROCKCHIP_SIP_DRAM_FREQ                       0x82000008
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_INIT                0x00
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE    0x01
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE  0x02
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR   0x03
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW              0x04
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE    0x05
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ     0x06
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM   0x07
> > +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD  0x08
> > +
> > +#endif
> > --
> > 2.39.1
> >
> >
> >
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-04-15  8:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-10 12:07 [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Alexander Shiyan
2025-04-10 12:07 ` [PATCH 2/3] clk: rockchip: Add linked gate clock support Alexander Shiyan
2025-04-10 12:07 ` [PATCH 3/3] clk: rockchip: Update RK3188 driver Alexander Shiyan
2025-04-14 11:32 ` [PATCH 1/3] clk: rockchip: Add new clock-type for the ddrclk Sascha Hauer
2025-04-15  7:48 ` Sascha Hauer
2025-04-15  7:56   ` Alexander Shiyan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox