linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] clk: keystone: sci-clk: perf improvements
@ 2019-04-12 18:22 Tero Kristo
  2019-04-12 18:22 ` [PATCH 1/3] clk: keystone: sci-clk: cut down the clock name length Tero Kristo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tero Kristo @ 2019-04-12 18:22 UTC (permalink / raw)
  To: linux-clk, linux-arm-kernel, sboyd, mturquette

Hi,

After some thinking, I decided to switch the clock scan method for
the sci-clk completely over to DT based scan. For example, on am65xx,
the boot time improvement for the clock probe is from 398ms down to
7.3ms. I retained the full firmware scan code behind a separate
Kconfig option; this can be useful for some debugging purposes if
someone needs to see all the clocks in a device.

Also, added patch #1 for cropping down the registered clock names,
currently they are pretty long forms containing the full interconnect
node paths, which makes the debugfs sort of un-usable.

-Tero

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* [PATCH 1/3] clk: keystone: sci-clk: cut down the clock name length
  2019-04-12 18:22 [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
@ 2019-04-12 18:22 ` Tero Kristo
  2019-04-12 18:22 ` [PATCH 2/3] clk: keystone: sci-clk: split out the fw clock parsing to own function Tero Kristo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Tero Kristo @ 2019-04-12 18:22 UTC (permalink / raw)
  To: linux-clk, linux-arm-kernel, sboyd, mturquette

There is no need to store the full node name to the individual clocks,
as this will just consome memory and make the clock debug entries
unnecessary long. Just shorten this to "clk" for now.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/keystone/sci-clk.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 4cb70be..e737f24 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -280,8 +280,8 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
 	int i;
 	int ret = 0;
 
-	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
-			 sci_clk->dev_id, sci_clk->clk_id);
+	name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id,
+			 sci_clk->clk_id);
 
 	init.name = name;
 
@@ -306,8 +306,7 @@ static int _sci_clk_build(struct sci_clk_provider *provider,
 		for (i = 0; i < sci_clk->num_parents; i++) {
 			char *parent_name;
 
-			parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
-						dev_name(provider->dev),
+			parent_name = kasprintf(GFP_KERNEL, "clk:%d:%d",
 						sci_clk->dev_id,
 						sci_clk->clk_id + 1 + i);
 			if (!parent_name) {
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* [PATCH 2/3] clk: keystone: sci-clk: split out the fw clock parsing to own function
  2019-04-12 18:22 [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
  2019-04-12 18:22 ` [PATCH 1/3] clk: keystone: sci-clk: cut down the clock name length Tero Kristo
@ 2019-04-12 18:22 ` Tero Kristo
  2019-04-12 18:22 ` [PATCH 3/3] clk: keystone: sci-clk: probe clocks from DT instead of firmware Tero Kristo
  2019-04-17 11:14 ` [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
  3 siblings, 0 replies; 5+ messages in thread
From: Tero Kristo @ 2019-04-12 18:22 UTC (permalink / raw)
  To: linux-clk, linux-arm-kernel, sboyd, mturquette

This makes it both easier to see what the probe does, and also makes it
possible to add alternative implementations for the clock data source.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/keystone/sci-clk.c | 68 +++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index e737f24..1e465de 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -403,22 +403,8 @@ static int ti_sci_init_clocks(struct sci_clk_provider *p)
 };
 MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
 
-/**
- * ti_sci_clk_probe - Probe function for the TI SCI clock driver
- * @pdev: platform device pointer to be probed
- *
- * Probes the TI SCI clock device. Allocates a new clock provider
- * and registers this to the common clock framework. Also applies
- * any required flags to the identified clocks via clock lists
- * supplied from DT. Returns 0 for success, negative error value
- * for failure.
- */
-static int ti_sci_clk_probe(struct platform_device *pdev)
+static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
 {
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	struct sci_clk_provider *provider;
-	const struct ti_sci_handle *handle;
 	int ret;
 	int num_clks = 0;
 	struct sci_clk **clks = NULL;
@@ -429,18 +415,7 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
 	int dev_id = 0;
 	u8 num_parents;
 	int gap_size = 0;
-
-	handle = devm_ti_sci_get_handle(dev);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-
-	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
-	if (!provider)
-		return -ENOMEM;
-
-	provider->sci = handle;
-	provider->ops = &handle->ops.clk_ops;
-	provider->dev = dev;
+	struct device *dev = provider->dev;
 
 	while (1) {
 		ret = provider->ops->get_num_parents(provider->sci, dev_id,
@@ -501,6 +476,45 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
 
 	devm_kfree(dev, clks);
 
+	return 0;
+}
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct sci_clk_provider *provider;
+	const struct ti_sci_handle *handle;
+	int ret;
+
+	handle = devm_ti_sci_get_handle(dev);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	provider->sci = handle;
+	provider->ops = &handle->ops.clk_ops;
+	provider->dev = dev;
+
+	ret = ti_sci_scan_clocks_from_fw(provider);
+	if (ret) {
+		dev_err(dev, "scan clocks from FW failed: %d\n", ret);
+		return ret;
+	}
+
 	ret = ti_sci_init_clocks(provider);
 	if (ret) {
 		pr_err("ti-sci-init-clocks failed.\n");
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* [PATCH 3/3] clk: keystone: sci-clk: probe clocks from DT instead of firmware
  2019-04-12 18:22 [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
  2019-04-12 18:22 ` [PATCH 1/3] clk: keystone: sci-clk: cut down the clock name length Tero Kristo
  2019-04-12 18:22 ` [PATCH 2/3] clk: keystone: sci-clk: split out the fw clock parsing to own function Tero Kristo
@ 2019-04-12 18:22 ` Tero Kristo
  2019-04-17 11:14 ` [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
  3 siblings, 0 replies; 5+ messages in thread
From: Tero Kristo @ 2019-04-12 18:22 UTC (permalink / raw)
  To: linux-clk, linux-arm-kernel, sboyd, mturquette

Probing all the available clocks from the PM firmware takes quite a lot
of time, increasing boot time. Instead, implement functionality that
parses only the used clocks from DT, and registers these to clock core.
This way, the boot time is greatly improved.

Additionally, provide a Kconfig option for parsing all the clocks from
firmware, if someone requires this. It is mostly useful as a debugging
functionality if we want to inspect the whole clock tree.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/clk/keystone/Kconfig   |  11 ++++
 drivers/clk/keystone/sci-clk.c | 123 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig
index b04927d..aaaee7d 100644
--- a/drivers/clk/keystone/Kconfig
+++ b/drivers/clk/keystone/Kconfig
@@ -14,3 +14,14 @@ config TI_SCI_CLK
 	  This adds the clock driver support over TI System Control Interface.
 	  If you wish to use clock resources from the PMMC firmware, say Y.
 	  Otherwise, say N.
+
+config TI_SCI_CLK_PROBE_FROM_FW
+	bool "Probe available clocks from firmware"
+	depends on TI_SCI_CLK
+	default n
+	help
+	  Forces the TI SCI clock driver to probe available clocks from the
+	  firmware. By default, only the used clocks are probed from DT.
+	  This is mostly only useful for debugging purposes, and will
+	  increase the boot time of the device. If you want the clocks probed
+	  from firmware, say Y. Otherwise, say N.
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 1e465de..6e5268c 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
 #include <linux/bsearch.h>
+#include <linux/list_sort.h>
 
 #define SCI_CLK_SSC_ENABLE		BIT(0)
 #define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
@@ -52,6 +53,7 @@ struct sci_clk_provider {
  * @num_parents: Number of parents for this clock
  * @provider:	 Master clock provider
  * @flags:	 Flags for the clock
+ * @node:	 Link for handling clocks probed via DT
  */
 struct sci_clk {
 	struct clk_hw hw;
@@ -60,6 +62,7 @@ struct sci_clk {
 	u8 num_parents;
 	struct sci_clk_provider *provider;
 	u8 flags;
+	struct list_head node;
 };
 
 #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
@@ -403,6 +406,7 @@ static int ti_sci_init_clocks(struct sci_clk_provider *p)
 };
 MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
 
+#ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW
 static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
 {
 	int ret;
@@ -479,6 +483,117 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
 	return 0;
 }
 
+#else
+
+static int _cmp_sci_clk_list(void *priv, struct list_head *a,
+			     struct list_head *b)
+{
+	struct sci_clk *ca = container_of(a, struct sci_clk, node);
+	struct sci_clk *cb = container_of(b, struct sci_clk, node);
+
+	return _cmp_sci_clk(ca, &cb);
+}
+
+static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
+{
+	struct device *dev = provider->dev;
+	struct device_node *np = NULL;
+	int ret;
+	int index;
+	struct of_phandle_args args;
+	struct list_head clks;
+	struct sci_clk *sci_clk, *prev;
+	int num_clks = 0;
+	int num_parents;
+	int clk_id;
+
+	INIT_LIST_HEAD(&clks);
+
+	while (1) {
+		np = of_find_node_with_property(np, "clocks");
+		if (!np)
+			break;
+
+		if (!of_device_is_available(np))
+			continue;
+
+		index = 0;
+
+		do {
+			ret = of_parse_phandle_with_args(np, "clocks",
+							 "#clock-cells", index,
+							 &args);
+			if (ret)
+				break;
+
+			if (args.args_count == 2 && args.np == dev->of_node) {
+				sci_clk = devm_kzalloc(dev, sizeof(*sci_clk),
+						       GFP_KERNEL);
+				if (!sci_clk)
+					return -ENOMEM;
+
+				sci_clk->dev_id = args.args[0];
+				sci_clk->clk_id = args.args[1];
+				sci_clk->provider = provider;
+				provider->ops->
+					get_num_parents(provider->sci,
+							sci_clk->dev_id,
+							sci_clk->clk_id,
+							&sci_clk->num_parents);
+				list_add_tail(&sci_clk->node, &clks);
+
+				num_clks++;
+
+				num_parents = sci_clk->num_parents;
+				if (num_parents == 1)
+					num_parents = 0;
+
+				clk_id = args.args[1] + 1;
+
+				while (num_parents--) {
+					sci_clk = devm_kzalloc(dev,
+							       sizeof(*sci_clk),
+							       GFP_KERNEL);
+					if (!sci_clk)
+						return -ENOMEM;
+					sci_clk->dev_id = args.args[0];
+					sci_clk->clk_id = clk_id++;
+					sci_clk->provider = provider;
+					list_add_tail(&sci_clk->node, &clks);
+
+					num_clks++;
+				}
+			}
+
+			index++;
+		} while (args.np);
+	}
+
+	list_sort(NULL, &clks, _cmp_sci_clk_list);
+
+	provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk),
+					      GFP_KERNEL);
+	if (!provider->clocks)
+		return -ENOMEM;
+
+	num_clks = 0;
+	prev = NULL;
+
+	list_for_each_entry(sci_clk, &clks, node) {
+		if (prev && prev->dev_id == sci_clk->dev_id &&
+		    prev->clk_id == sci_clk->clk_id)
+			continue;
+
+		provider->clocks[num_clks++] = sci_clk;
+		prev = sci_clk;
+	}
+
+	provider->num_clocks = num_clks;
+
+	return 0;
+}
+#endif
+
 /**
  * ti_sci_clk_probe - Probe function for the TI SCI clock driver
  * @pdev: platform device pointer to be probed
@@ -509,11 +624,19 @@ static int ti_sci_clk_probe(struct platform_device *pdev)
 	provider->ops = &handle->ops.clk_ops;
 	provider->dev = dev;
 
+#ifdef CONFIG_TI_SCI_CLK_PROBE_FROM_FW
 	ret = ti_sci_scan_clocks_from_fw(provider);
 	if (ret) {
 		dev_err(dev, "scan clocks from FW failed: %d\n", ret);
 		return ret;
 	}
+#else
+	ret = ti_sci_scan_clocks_from_dt(provider);
+	if (ret) {
+		dev_err(dev, "scan clocks from DT failed: %d\n", ret);
+		return ret;
+	}
+#endif
 
 	ret = ti_sci_init_clocks(provider);
 	if (ret) {
-- 
1.9.1

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH 0/3] clk: keystone: sci-clk: perf improvements
  2019-04-12 18:22 [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
                   ` (2 preceding siblings ...)
  2019-04-12 18:22 ` [PATCH 3/3] clk: keystone: sci-clk: probe clocks from DT instead of firmware Tero Kristo
@ 2019-04-17 11:14 ` Tero Kristo
  3 siblings, 0 replies; 5+ messages in thread
From: Tero Kristo @ 2019-04-17 11:14 UTC (permalink / raw)
  To: linux-clk, linux-arm-kernel, sboyd, mturquette, Santosh Shilimkar

Hi Santosh,

Seems I missed adding you to delivery of this series, sorry about that. 
Do you want me to re-post?

-Tero

On 12/04/2019 21:22, Tero Kristo wrote:
> Hi,
> 
> After some thinking, I decided to switch the clock scan method for
> the sci-clk completely over to DT based scan. For example, on am65xx,
> the boot time improvement for the clock probe is from 398ms down to
> 7.3ms. I retained the full firmware scan code behind a separate
> Kconfig option; this can be useful for some debugging purposes if
> someone needs to see all the clocks in a device.
> 
> Also, added patch #1 for cropping down the registered clock names,
> currently they are pretty long forms containing the full interconnect
> node paths, which makes the debugfs sort of un-usable.
> 
> -Tero
> 
> --
> 

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

end of thread, other threads:[~2019-04-17 11:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-12 18:22 [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo
2019-04-12 18:22 ` [PATCH 1/3] clk: keystone: sci-clk: cut down the clock name length Tero Kristo
2019-04-12 18:22 ` [PATCH 2/3] clk: keystone: sci-clk: split out the fw clock parsing to own function Tero Kristo
2019-04-12 18:22 ` [PATCH 3/3] clk: keystone: sci-clk: probe clocks from DT instead of firmware Tero Kristo
2019-04-17 11:14 ` [PATCH 0/3] clk: keystone: sci-clk: perf improvements Tero Kristo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).