diff mbox series

[04/12] clk: renesas: clk-vbattb: Add VBATTB clock driver

Message ID 20240614071932.1014067-5-claudiu.beznea.uj@bp.renesas.com (mailing list archive)
State New, archived
Headers show
Series Add RTC support for the Renesas RZ/G3S SoC | expand

Commit Message

Claudiu June 14, 2024, 7:19 a.m. UTC
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

The VBATTB IP of the Renesas RZ/G3S SoC controls the clock that is used
by the RTC. The input to the VBATTB could be a 32KHz crystal connected
to both the RTXIN and RTXOUT pins or an external clock connected to
RTXOUT pin. In case an external clock is connected to the RTXOUT pin the
renesas,vbattb-osc-bypass DT property need to be used when describing the
node.

The load capacitance of the on-board oscillator need to be configured with
renesas,vbattb-load-nanofarads DT property.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
 drivers/clk/renesas/Kconfig      |   4 +
 drivers/clk/renesas/Makefile     |   1 +
 drivers/clk/renesas/clk-vbattb.c | 202 +++++++++++++++++++++++++++++++
 3 files changed, 207 insertions(+)
 create mode 100644 drivers/clk/renesas/clk-vbattb.c

Comments

kernel test robot June 15, 2024, 10:25 p.m. UTC | #1
Hi Claudiu,

kernel test robot noticed the following build warnings:

[auto build test WARNING on geert-renesas-drivers/renesas-clk]
[also build test WARNING on geert-renesas-devel/next linus/master v6.10-rc3 next-20240613]
[cannot apply to abelloni/rtc-next]
[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/Claudiu/clk-renesas-r9a08g045-Add-clock-reset-and-power-domain-support-for-the-VBATTB-IP/20240614-152418
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk
patch link:    https://lore.kernel.org/r/20240614071932.1014067-5-claudiu.beznea.uj%40bp.renesas.com
patch subject: [PATCH 04/12] clk: renesas: clk-vbattb: Add VBATTB clock driver
config: arm64-randconfig-r131-20240615 (https://download.01.org/0day-ci/archive/20240616/202406160533.s4RRLDes-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240616/202406160533.s4RRLDes-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/202406160533.s4RRLDes-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/clk/renesas/clk-vbattb.c:132:35: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected unsigned long [usertype] size @@     got restricted gfp_t @@
   drivers/clk/renesas/clk-vbattb.c:132:35: sparse:     expected unsigned long [usertype] size
   drivers/clk/renesas/clk-vbattb.c:132:35: sparse:     got restricted gfp_t
>> drivers/clk/renesas/clk-vbattb.c:132:47: sparse: sparse: incorrect type in argument 3 (different base types) @@     expected restricted gfp_t [usertype] gfp @@     got unsigned long @@
   drivers/clk/renesas/clk-vbattb.c:132:47: sparse:     expected restricted gfp_t [usertype] gfp
   drivers/clk/renesas/clk-vbattb.c:132:47: sparse:     got unsigned long
   drivers/clk/renesas/clk-vbattb.c: note: in included file (through include/linux/mmzone.h, include/linux/gfp.h, include/linux/xarray.h, ...):
   include/linux/page-flags.h:240:46: sparse: sparse: self-comparison always evaluates to false
   include/linux/page-flags.h:240:46: sparse: sparse: self-comparison always evaluates to false

vim +132 drivers/clk/renesas/clk-vbattb.c

   119	
   120	static int vbattb_clk_probe(struct platform_device *pdev)
   121	{
   122		struct clk_parent_data parent_data = { .fw_name = "vbattb_xtal" };
   123		struct device_node *np = pdev->dev.of_node;
   124		struct device *dev = &pdev->dev;
   125		struct clk_init_data init = {};
   126		struct vbattb_clk *vbclk;
   127		u32 load_capacitance;
   128		struct clk_hw *hw;
   129		bool bypass;
   130		int ret;
   131	
 > 132		vbclk = devm_kzalloc(dev, GFP_KERNEL, sizeof(*vbclk));
   133		if (!vbclk)
   134			return -ENOMEM;
   135	
   136		vbclk->regmap = syscon_node_to_regmap(np->parent);
   137		if (IS_ERR(vbclk->regmap))
   138			return PTR_ERR(vbclk->regmap);
   139	
   140		bypass = of_property_read_bool(np, "renesas,vbattb-osc-bypass");
   141		ret = of_property_read_u32(np, "renesas,vbattb-load-nanofarads", &load_capacitance);
   142		if (ret)
   143			return ret;
   144	
   145		ret = vbattb_clk_validate_load_capacitance(vbclk, load_capacitance);
   146		if (ret)
   147			return ret;
   148	
   149		ret = devm_pm_runtime_enable(dev);
   150		if (ret)
   151			return ret;
   152	
   153		ret = pm_runtime_resume_and_get(dev);
   154		if (ret)
   155			return ret;
   156	
   157		regmap_update_bits(vbclk->regmap, VBATTB_BKSCCR, VBATTB_BKSCCR_SOSEL,
   158				   bypass ? VBATTB_BKSCCR_SOSEL : 0);
   159	
   160		init.name = "vbattclk";
   161		init.ops = &vbattb_clk_ops;
   162		init.parent_data = &parent_data;
   163		init.num_parents = 1;
   164		init.flags = 0;
   165	
   166		vbclk->hw.init = &init;
   167		hw = &vbclk->hw;
   168	
   169		spin_lock_init(&vbclk->lock);
   170	
   171		ret = devm_clk_hw_register(dev, hw);
   172		if (ret)
   173			goto rpm_put;
   174	
   175		ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
   176		if (ret)
   177			goto rpm_put;
   178	
   179		return 0;
   180	
   181	rpm_put:
   182		pm_runtime_put(dev);
   183		return ret;
   184	}
   185
kernel test robot June 16, 2024, 12:19 a.m. UTC | #2
Hi Claudiu,

kernel test robot noticed the following build warnings:

[auto build test WARNING on geert-renesas-drivers/renesas-clk]
[also build test WARNING on geert-renesas-devel/next linus/master v6.10-rc3 next-20240613]
[cannot apply to abelloni/rtc-next]
[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/Claudiu/clk-renesas-r9a08g045-Add-clock-reset-and-power-domain-support-for-the-VBATTB-IP/20240614-152418
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk
patch link:    https://lore.kernel.org/r/20240614071932.1014067-5-claudiu.beznea.uj%40bp.renesas.com
patch subject: [PATCH 04/12] clk: renesas: clk-vbattb: Add VBATTB clock driver
config: mips-randconfig-r122-20240616 (https://download.01.org/0day-ci/archive/20240616/202406160847.Ns62KOVc-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240616/202406160847.Ns62KOVc-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/202406160847.Ns62KOVc-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/clk/renesas/clk-vbattb.c:132:35: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected unsigned int [usertype] size @@     got restricted gfp_t @@
   drivers/clk/renesas/clk-vbattb.c:132:35: sparse:     expected unsigned int [usertype] size
   drivers/clk/renesas/clk-vbattb.c:132:35: sparse:     got restricted gfp_t
>> drivers/clk/renesas/clk-vbattb.c:132:47: sparse: sparse: incorrect type in argument 3 (different base types) @@     expected restricted gfp_t [usertype] gfp @@     got unsigned int @@
   drivers/clk/renesas/clk-vbattb.c:132:47: sparse:     expected restricted gfp_t [usertype] gfp
   drivers/clk/renesas/clk-vbattb.c:132:47: sparse:     got unsigned int
   drivers/clk/renesas/clk-vbattb.c: note: in included file (through include/linux/mmzone.h, include/linux/gfp.h, include/linux/xarray.h, ...):
   include/linux/page-flags.h:240:46: sparse: sparse: self-comparison always evaluates to false
   include/linux/page-flags.h:240:46: sparse: sparse: self-comparison always evaluates to false

vim +132 drivers/clk/renesas/clk-vbattb.c

   119	
   120	static int vbattb_clk_probe(struct platform_device *pdev)
   121	{
   122		struct clk_parent_data parent_data = { .fw_name = "vbattb_xtal" };
   123		struct device_node *np = pdev->dev.of_node;
   124		struct device *dev = &pdev->dev;
   125		struct clk_init_data init = {};
   126		struct vbattb_clk *vbclk;
   127		u32 load_capacitance;
   128		struct clk_hw *hw;
   129		bool bypass;
   130		int ret;
   131	
 > 132		vbclk = devm_kzalloc(dev, GFP_KERNEL, sizeof(*vbclk));
   133		if (!vbclk)
   134			return -ENOMEM;
   135	
   136		vbclk->regmap = syscon_node_to_regmap(np->parent);
   137		if (IS_ERR(vbclk->regmap))
   138			return PTR_ERR(vbclk->regmap);
   139	
   140		bypass = of_property_read_bool(np, "renesas,vbattb-osc-bypass");
   141		ret = of_property_read_u32(np, "renesas,vbattb-load-nanofarads", &load_capacitance);
   142		if (ret)
   143			return ret;
   144	
   145		ret = vbattb_clk_validate_load_capacitance(vbclk, load_capacitance);
   146		if (ret)
   147			return ret;
   148	
   149		ret = devm_pm_runtime_enable(dev);
   150		if (ret)
   151			return ret;
   152	
   153		ret = pm_runtime_resume_and_get(dev);
   154		if (ret)
   155			return ret;
   156	
   157		regmap_update_bits(vbclk->regmap, VBATTB_BKSCCR, VBATTB_BKSCCR_SOSEL,
   158				   bypass ? VBATTB_BKSCCR_SOSEL : 0);
   159	
   160		init.name = "vbattclk";
   161		init.ops = &vbattb_clk_ops;
   162		init.parent_data = &parent_data;
   163		init.num_parents = 1;
   164		init.flags = 0;
   165	
   166		vbclk->hw.init = &init;
   167		hw = &vbclk->hw;
   168	
   169		spin_lock_init(&vbclk->lock);
   170	
   171		ret = devm_clk_hw_register(dev, hw);
   172		if (ret)
   173			goto rpm_put;
   174	
   175		ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
   176		if (ret)
   177			goto rpm_put;
   178	
   179		return 0;
   180	
   181	rpm_put:
   182		pm_runtime_put(dev);
   183		return ret;
   184	}
   185
diff mbox series

Patch

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index d252150402e8..1dc38e3a8326 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -228,6 +228,10 @@  config CLK_RZG2L
 	bool "Renesas RZ/{G2L,G2UL,G3S,V2L} family clock support" if COMPILE_TEST
 	select RESET_CONTROLLER
 
+config CLK_VBATTB
+	bool "Renesas VBATTB clock controller"
+	select RESET_CONTROLLER
+
 # Generic
 config CLK_RENESAS_CPG_MSSR
 	bool "CPG/MSSR clock support" if COMPILE_TEST
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index f7e18679c3b8..e9e487f53577 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -51,3 +51,4 @@  obj-$(CONFIG_CLK_RZG2L)			+= rzg2l-cpg.o
 obj-$(CONFIG_CLK_RENESAS_CPG_MSSR)	+= renesas-cpg-mssr.o
 obj-$(CONFIG_CLK_RENESAS_CPG_MSTP)	+= clk-mstp.o
 obj-$(CONFIG_CLK_RENESAS_DIV6)		+= clk-div6.o
+obj-$(CONFIG_CLK_VBATTB)		+= clk-vbattb.o
diff --git a/drivers/clk/renesas/clk-vbattb.c b/drivers/clk/renesas/clk-vbattb.c
new file mode 100644
index 000000000000..0a5cc886e89c
--- /dev/null
+++ b/drivers/clk/renesas/clk-vbattb.c
@@ -0,0 +1,202 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * VBATTB clock driver
+ *
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define VBATTB_BKSCCR			0x1c
+#define VBATTB_BKSCCR_SOSEL		BIT(6)
+#define VBATTB_SOSCCR2			0x24
+#define VBATTB_SOSCCR2_SOSTP2		BIT(0)
+#define VBATTB_XOSCCR			0x30
+#define VBATTB_XOSCCR_OUTEN		BIT(16)
+#define VBATTB_XOSCCR_XSEL		GENMASK(1, 0)
+#define VBATTB_XOSCCR_XSEL_4_PF		0x0
+#define VBATTB_XOSCCR_XSEL_7_PF		0x1
+#define VBATTB_XOSCCR_XSEL_9_PF		0x2
+#define VBATTB_XOSCCR_XSEL_12_5_PF	0x3
+
+/**
+ * struct vbattb_clk - VBATTB clock data structure
+ * @regmap: regmap
+ * @hw: clk hw
+ * @lock: device lock
+ * @load_capacitance: load capacitance
+ */
+struct vbattb_clk {
+	struct regmap *regmap;
+	struct clk_hw hw;
+	spinlock_t lock;
+	u8 load_capacitance;
+};
+
+#define to_vbattb_clk(_hw) container_of(_hw, struct vbattb_clk, hw)
+
+static int vbattb_clk_enable(struct clk_hw *hw)
+{
+	struct vbattb_clk *vbclk = to_vbattb_clk(hw);
+	struct regmap *regmap = vbclk->regmap;
+
+	spin_lock(&vbclk->lock);
+	regmap_update_bits(regmap, VBATTB_SOSCCR2, VBATTB_SOSCCR2_SOSTP2, 0);
+	regmap_update_bits(regmap, VBATTB_XOSCCR, VBATTB_XOSCCR_OUTEN | VBATTB_XOSCCR_XSEL,
+			   VBATTB_XOSCCR_OUTEN | vbclk->load_capacitance);
+	spin_unlock(&vbclk->lock);
+
+	return 0;
+}
+
+static void vbattb_clk_disable(struct clk_hw *hw)
+{
+	struct vbattb_clk *vbclk = to_vbattb_clk(hw);
+	struct regmap *regmap = vbclk->regmap;
+
+	spin_lock(&vbclk->lock);
+	regmap_update_bits(regmap, VBATTB_XOSCCR, VBATTB_XOSCCR_OUTEN, 0);
+	regmap_update_bits(regmap, VBATTB_SOSCCR2, VBATTB_SOSCCR2_SOSTP2, VBATTB_SOSCCR2_SOSTP2);
+	spin_unlock(&vbclk->lock);
+}
+
+static int vbattb_clk_is_enabled(struct clk_hw *hw)
+{
+	struct vbattb_clk *vbclk = to_vbattb_clk(hw);
+	struct regmap *regmap = vbclk->regmap;
+	unsigned int xosccr, sosccr2;
+	int ret;
+
+	spin_lock(&vbclk->lock);
+	ret = regmap_read(regmap, VBATTB_XOSCCR, &xosccr);
+	if (ret)
+		goto unlock;
+
+	ret = regmap_read(regmap, VBATTB_SOSCCR2, &sosccr2);
+unlock:
+	spin_unlock(&vbclk->lock);
+
+	if (ret)
+		return 0;
+
+	return ((xosccr & VBATTB_XOSCCR_OUTEN) && !(sosccr2 & VBATTB_SOSCCR2_SOSTP2));
+}
+
+static const struct clk_ops vbattb_clk_ops = {
+	.enable = vbattb_clk_enable,
+	.disable = vbattb_clk_disable,
+	.is_enabled = vbattb_clk_is_enabled,
+};
+
+static int vbattb_clk_validate_load_capacitance(struct vbattb_clk *vbclk, u32 load_capacitance)
+{
+	switch (load_capacitance) {
+	case 4000:
+		vbclk->load_capacitance = VBATTB_XOSCCR_XSEL_4_PF;
+		break;
+	case 7000:
+		vbclk->load_capacitance = VBATTB_XOSCCR_XSEL_7_PF;
+		break;
+	case 9000:
+		vbclk->load_capacitance = VBATTB_XOSCCR_XSEL_9_PF;
+		break;
+	case 12500:
+		vbclk->load_capacitance = VBATTB_XOSCCR_XSEL_12_5_PF;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vbattb_clk_probe(struct platform_device *pdev)
+{
+	struct clk_parent_data parent_data = { .fw_name = "vbattb_xtal" };
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct clk_init_data init = {};
+	struct vbattb_clk *vbclk;
+	u32 load_capacitance;
+	struct clk_hw *hw;
+	bool bypass;
+	int ret;
+
+	vbclk = devm_kzalloc(dev, GFP_KERNEL, sizeof(*vbclk));
+	if (!vbclk)
+		return -ENOMEM;
+
+	vbclk->regmap = syscon_node_to_regmap(np->parent);
+	if (IS_ERR(vbclk->regmap))
+		return PTR_ERR(vbclk->regmap);
+
+	bypass = of_property_read_bool(np, "renesas,vbattb-osc-bypass");
+	ret = of_property_read_u32(np, "renesas,vbattb-load-nanofarads", &load_capacitance);
+	if (ret)
+		return ret;
+
+	ret = vbattb_clk_validate_load_capacitance(vbclk, load_capacitance);
+	if (ret)
+		return ret;
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		return ret;
+
+	regmap_update_bits(vbclk->regmap, VBATTB_BKSCCR, VBATTB_BKSCCR_SOSEL,
+			   bypass ? VBATTB_BKSCCR_SOSEL : 0);
+
+	init.name = "vbattclk";
+	init.ops = &vbattb_clk_ops;
+	init.parent_data = &parent_data;
+	init.num_parents = 1;
+	init.flags = 0;
+
+	vbclk->hw.init = &init;
+	hw = &vbclk->hw;
+
+	spin_lock_init(&vbclk->lock);
+
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret)
+		goto rpm_put;
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+	if (ret)
+		goto rpm_put;
+
+	return 0;
+
+rpm_put:
+	pm_runtime_put(dev);
+	return ret;
+}
+
+static const struct of_device_id vbattb_clk_match[] = {
+	{ .compatible = "renesas,rzg3s-vbattb-clk" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver vbattb_clk_driver = {
+	.driver		= {
+		.name	= "vbattb-clk",
+		.of_match_table = vbattb_clk_match,
+	},
+	.probe = vbattb_clk_probe,
+};
+module_platform_driver(vbattb_clk_driver);
+
+MODULE_DESCRIPTION("Renesas VBATTB Clock Driver");
+MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>");
+MODULE_LICENSE("GPL");