Thread (71 messages) 71 messages, 6 authors, 2023-11-23

RE: [PATCH v8 14/26] PM / devfreq: rockchip-dfi: Prepare for multiple users

From: "Chanwoo Choi" <cw00.choi@samsung.com>
Date: 2023-10-19 11:58:36
Also in: linux-devicetree, linux-pm, linux-rockchip, lkml

quoted hunk ↗ jump to hunk
-----Original Message-----
From: Sascha Hauer <s.hauer@pengutronix.de>
Sent: Wednesday, October 18, 2023 3:17 PM
To: linux-rockchip@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
linux-pm@vger.kernel.org; Heiko Stuebner [off-list ref]; Chanwoo Choi
[off-list ref]; Kyungmin Park [off-list ref]; MyungJoo
Ham [off-list ref]; Will Deacon [off-list ref]; Mark
Rutland [off-list ref]; kernel@pengutronix.de; Michael Riesch
[off-list ref]; Robin Murphy [off-list ref];
Vincent Legoll [off-list ref]; Rob Herring
[off-list ref]; Krzysztof Kozlowski
[off-list ref]; Conor Dooley [off-list ref];
devicetree@vger.kernel.org; Sebastian Reichel
[off-list ref]; Sascha Hauer [off-list ref];
Jonathan Cameron [off-list ref]; Chanwoo Choi
[off-list ref]
Subject: [PATCH v8 14/26] PM / devfreq: rockchip-dfi: Prepare for multiple
users

When adding perf support later the DFI must be enabled when either of
devfreq-event or perf is active. Prepare for that by adding a usage
counter for the DFI. Also move enabling and disabling of the clock away
from the devfreq-event specific functions to which the perf specific part
won't have access.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Sebastian Reichel <redacted>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/devfreq/event/rockchip-dfi.c | 57 +++++++++++++++++++---------
 1 file changed, 40 insertions(+), 17 deletions(-)
diff --git a/drivers/devfreq/event/rockchip-dfi.c
b/drivers/devfreq/event/rockchip-dfi.c
index d56a33d03db4c..7a4f1901314d4 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -68,14 +68,29 @@ struct rockchip_dfi {
 	void __iomem *regs;
 	struct regmap *regmap_pmu;
 	struct clk *clk;
+	int usecount;
+	struct mutex mutex;
 	u32 ddr_type;
 	unsigned int channel_mask;
 	unsigned int max_channels;
 };

-static void rockchip_dfi_start_hardware_counter(struct rockchip_dfi *dfi)
+static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
 {
 	void __iomem *dfi_regs = dfi->regs;
+	int ret = 0;
+
+	mutex_lock(&dfi->mutex);
+
+	dfi->usecount++;
+	if (dfi->usecount > 1)
+		goto out;
+
+	ret = clk_prepare_enable(dfi->clk);
+	if (ret) {
+		dev_err(&dfi->edev->dev, "failed to enable dfi clk: %d\n",
ret);
+		goto out;
+	}

 	/* clear DDRMON_CTRL setting */
 	writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN |
DDRMON_CTRL_SOFTWARE_EN | @@ -100,14 +115,30 @@ static void
rockchip_dfi_start_hardware_counter(struct rockchip_dfi *dfi)
 	/* enable count, use software mode */
 	writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN,
DDRMON_CTRL_SOFTWARE_EN),
 		       dfi_regs + DDRMON_CTRL);
+out:
+	mutex_unlock(&dfi->mutex);
+
+	return ret;
 }

-static void rockchip_dfi_stop_hardware_counter(struct rockchip_dfi *dfi)
+static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
 {
 	void __iomem *dfi_regs = dfi->regs;

+	mutex_lock(&dfi->mutex);
+
+	dfi->usecount--;
+
+	WARN_ON_ONCE(dfi->usecount < 0);
+
+	if (dfi->usecount > 0)
+		goto out;
+
 	writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
 		       dfi_regs + DDRMON_CTRL);
+	clk_disable_unprepare(dfi->clk);
+out:
+	mutex_unlock(&dfi->mutex);
 }

 static void rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct
dmc_count *count) @@ -125,29 +156,20 @@ static void
rockchip_dfi_read_counters(struct rockchip_dfi *dfi, struct dmc_coun
 	}
 }

-static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
+static int rockchip_dfi_event_disable(struct devfreq_event_dev *edev)
 {
 	struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);

-	rockchip_dfi_stop_hardware_counter(dfi);
-	clk_disable_unprepare(dfi->clk);
+	rockchip_dfi_disable(dfi);

 	return 0;
 }

-static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
+static int rockchip_dfi_event_enable(struct devfreq_event_dev *edev)
 {
 	struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);
-	int ret;
-
-	ret = clk_prepare_enable(dfi->clk);
-	if (ret) {
-		dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret);
-		return ret;
-	}

-	rockchip_dfi_start_hardware_counter(dfi);
-	return 0;
+	return rockchip_dfi_enable(dfi);
 }

 static int rockchip_dfi_set_event(struct devfreq_event_dev *edev) @@ -
191,8 +213,8 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev
*edev,  }

 static const struct devfreq_event_ops rockchip_dfi_ops = {
-	.disable = rockchip_dfi_disable,
-	.enable = rockchip_dfi_enable,
+	.disable = rockchip_dfi_event_disable,
+	.enable = rockchip_dfi_event_enable,
 	.get_event = rockchip_dfi_get_event,
 	.set_event = rockchip_dfi_set_event,
 };
@@ -280,6 +302,7 @@ static int rockchip_dfi_probe(struct platform_device
*pdev)
 		return PTR_ERR(dfi->regmap_pmu);

 	dfi->dev = dev;
+	mutex_init(&dfi->mutex);

 	desc = &dfi->desc;
 	desc->ops = &rockchip_dfi_ops;
--
2.39.2

Applied it. Thanks

Best Regards,
Chanwoo Choi


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help