Skip to contentSkip to conversation

clk: intel: Add a new driver for a new clock controller IP

PATCH Superseded Rahul Tanwar 7 participants 19 messages Aug 28, 2019 – Dec 24, 2019

Subsystems (2)

v1 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

cover clk: intel: Add a new driver for a new clock controller IP

Hi,

A forthcoming Intel network processor SoC uses a new Clock Generation Unit(CGU) IP for clock controller. This series adds the clock driver for CGU.

Patch 1 adds common clock framework based clock driver for CGU. Patch 2 adds bindings document & include file for CGU.

These patches are baselined upon Linux 5.3-rc1 at below Git link:
git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git

Rahul Tanwar (1):
dt-bindings: clk: intel: Add bindings document & header file for CGU

rtanwar (1):
clk: intel: Add CGU clock driver for a new SoC

 .../devicetree/bindings/clock/intel,cgu-lgm.yaml   |  61 +++
 drivers/clk/Kconfig                                |   1 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/intel/Kconfig                          |  13 +
 drivers/clk/intel/Makefile                         |   4 +
 drivers/clk/intel/clk-cgu-pll.c                    | 160 ++++++
 drivers/clk/intel/clk-cgu-pll.h                    |  24 +
 drivers/clk/intel/clk-cgu.c                        | 544 +++++++++++++++++++++
 drivers/clk/intel/clk-cgu.h                        | 278 +++++++++++
 drivers/clk/intel/clk-lgm.c                        | 352 +++++++++++++
 include/dt-bindings/clock/intel,lgm-clk.h          | 150 ++++++
 11 files changed, 1588 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml
 create mode 100644 drivers/clk/intel/Kconfig
 create mode 100644 drivers/clk/intel/Makefile
 create mode 100644 drivers/clk/intel/clk-cgu-pll.c
 create mode 100644 drivers/clk/intel/clk-cgu-pll.h
 create mode 100644 drivers/clk/intel/clk-cgu.c
 create mode 100644 drivers/clk/intel/clk-cgu.h
 create mode 100644 drivers/clk/intel/clk-lgm.c
 create mode 100644 include/dt-bindings/clock/intel,lgm-clk.h
Signature · 1 line
2.11.0
#1 lore raw

PATCH 1/2 clk: intel: Add CGU clock driver for a new SoC

From: rtanwar <[email protected]>

Clock Generation Unit(CGU) is a new clock controller IP of a forthcoming Intel network processor SoC. It provides programming interfaces to control & configure all CPU & peripheral clocks. Add common clock framework based clock controller driver for CGU.

---
 drivers/clk/Kconfig             |   1 +
 drivers/clk/Makefile            |   1 +
 drivers/clk/intel/Kconfig       |  13 +
 drivers/clk/intel/Makefile      |   4 +
 drivers/clk/intel/clk-cgu-pll.c | 160 ++++++++++++
 drivers/clk/intel/clk-cgu-pll.h |  24 ++
 drivers/clk/intel/clk-cgu.c     | 544 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/intel/clk-cgu.h     | 278 ++++++++++++++++++++
 drivers/clk/intel/clk-lgm.c     | 352 ++++++++++++++++++++++++++
 9 files changed, 1377 insertions(+)
 create mode 100644 drivers/clk/intel/Kconfig
 create mode 100644 drivers/clk/intel/Makefile
 create mode 100644 drivers/clk/intel/clk-cgu-pll.c
 create mode 100644 drivers/clk/intel/clk-cgu-pll.h
 create mode 100644 drivers/clk/intel/clk-cgu.c
 create mode 100644 drivers/clk/intel/clk-cgu.h
 create mode 100644 drivers/clk/intel/clk-lgm.c
drivers/clk/Kconfig +1 -0
index 801fa1cd0321..3b2e0106b305 100644
@@ -336,5 +336,6 @@ source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
 source "drivers/clk/zynqmp/Kconfig"
+source "drivers/clk/intel/Kconfig"
 
 endmenu
drivers/clk/Makefile +1 -0
index 0cad76021297..f7e2ef6931b7 100644
@@ -117,3 +117,4 @@ endif
 obj-$(CONFIG_ARCH_ZX)			+= zte/
 obj-$(CONFIG_ARCH_ZYNQ)			+= zynq/
 obj-$(CONFIG_COMMON_CLK_ZYNQMP)         += zynqmp/
+obj-$(CONFIG_INTEL_LGM_CGU_CLK)		+= intel/
drivers/clk/intel/Kconfig new file +13 -0
new file mode 100644
index 000000000000..6608ae88a9a7
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+	depends on COMMON_CLK
+	select MFD_SYSCON
+	select OF_EARLY_FLATTREE
+	bool "Intel Clock Genration Unit support"
+	help
+	  Support for clock generation unit driver for Intel Lightning
+	  Mountain(LGM) series SoCs. It is based on Common Clock Framework.
+	  CGU driver provides all means to access the clock generation unit
+	  hardware module of LGM in order to generate a series of clocks for
+	  the whole system and individual peripherals. Choose Y here if you
+	  are building for Lightning Mountain(LGM) platform.
drivers/clk/intel/Makefile new file +4 -0
new file mode 100644
index 000000000000..82741528d2fb
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for intel specific clk
+
+obj-$(CONFIG_INTEL_LGM_CGU_CLK) += clk-cgu.o clk-cgu-pll.o clk-lgm.o
drivers/clk/intel/clk-cgu-pll.c new file +160 -0

160 lines not on this page · raw message

drivers/clk/intel/clk-cgu-pll.h new file +24 -0
new file mode 100644
index 000000000000..35e25b242cff
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright(c) 2018 Intel Corporation.
+ *  Zhu YiXin <[email protected]>
+ */
+
+#ifndef __INTEL_CLK_PLL_H
+#define __INTEL_CLK_PLL_H
+
+enum pll_type {
+	TYPE_ROPLL,
+	TYPE_LJPLL,
+};
+
+struct intel_clk_pll {
+	struct clk_hw hw;
+	struct device *dev;
+	struct regmap *map;
+	unsigned int reg;
+	unsigned long flags;
+	enum pll_type type;
+};
+
+#endif				/* __INTEL_CLK_PLL_H */
drivers/clk/intel/clk-cgu.c new file +544 -0

544 lines not on this page · raw message

drivers/clk/intel/clk-cgu.h new file +278 -0

278 lines not on this page · raw message

drivers/clk/intel/clk-lgm.c new file +352 -0

352 lines not on this page · raw message

Signature · 1 line
2.11.0
#2 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoted 9 lines · Rahul Tanwar

From: rtanwar <[email protected]>

Clock Generation Unit(CGU) is a new clock controller IP of a forthcoming Intel network processor SoC. It provides programming interfaces to control & configure all CPU & peripheral clocks. Add common clock framework based clock controller driver for CGU.

 drivers/clk/intel/Kconfig       |  13 +
 drivers/clk/intel/Makefile      |   4 +

Any plans what to do with existing x86 folder there?

drivers/clk/intel/Kconfig line 6

Quoted 8 lines

+++ b/drivers/clk/intel/Kconfig

drivers/clk/intel/Kconfig new file +6 -0
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+	depends on COMMON_CLK
+	select MFD_SYSCON
+	select OF_EARLY_FLATTREE
+	bool "Intel Clock Genration Unit support"

Is it for X86? Don't you need a dependency?

Quoted 5 lines
drivers/clk/intel/clk-cgu-pll.c new file +5 -0
+/*
+ * Calculate formula:
+ * rate = (prate * mult + (prate * frac) / frac_div) / div
+ */
+static unsigned long

drivers/clk/intel/clk-cgu-pll.c line 35

Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+intel_pll_calc_rate(unsigned long prate, unsigned int mult,
+		    unsigned int div, unsigned int frac, unsigned int frac_div)
+{
+	u64 crate, frate, rate64;
+
+	rate64 = prate;
+	crate = rate64 * mult;
+
 
+	if (frac) {

This seems unnecessary.
I think you would like to check for frac_div instead?
Though I would rather to use frac = 0, frac_div = 1 and drop this conditional completely.

drivers/clk/intel/clk-cgu-pll.c

Quoted 12 lines
drivers/clk/intel/clk-cgu-pll.c new file +10 -0
+		frate = rate64 * frac;
+		do_div(frate, frac_div);
+		crate += frate;
+	}
+	do_div(crate, div);
+
+	return (unsigned long)crate;
+}
 
+static struct clk_hw
 
+*intel_clk_register_pll(struct intel_clk_provider *ctx,

* is part of type.

Quoted 16 lines
drivers/clk/intel/clk-cgu-pll.c new file +16 -0
+			const struct intel_pll_clk_data *list)
+{
+	struct clk_init_data init;
+	struct intel_clk_pll *pll;
+	struct device *dev = ctx->dev;
+	struct clk_hw *hw;
+	int ret;
+
+	init.ops = &intel_lgm_pll_ops;
+	init.name = list->name;
+	init.parent_names = list->parent_names;
+	init.num_parents = list->num_parents;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);

drivers/clk/intel/clk-cgu-pll.c line 135

Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+
+	pll->map = ctx->map;
+	pll->dev = ctx->dev;
+	pll->reg = list->reg;
+	pll->flags = list->flags;
+	pll->type = list->type;
+	pll->hw.init = &init;
+
 
+	hw = &pll->hw;

Seems redundant temporary variable.

drivers/clk/intel/clk-cgu-pll.c line 145

Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+	ret = clk_hw_register(dev, hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return hw;
+}
 
+void intel_clk_register_plls(struct intel_clk_provider *ctx,
+			     const struct intel_pll_clk_data *list,
+				unsigned int nr_clk)

Indentation issues.

drivers/clk/intel/clk-cgu-pll.c line 154

Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+{
+	struct clk_hw *hw;
+	int i;
+
+	for (i = 0; i < nr_clk; i++, list++) {
+		hw = intel_clk_register_pll(ctx, list);
+		if (IS_ERR(hw)) {
 
+			dev_err(ctx->dev, "failed to register pll: %s\n",
+				list->name);

Is it fatal or not?

drivers/clk/intel/clk-cgu-pll.c line 159

Quoted 5 lines
drivers/clk/intel/clk-cgu-pll.c new file +5 -0
+			continue;
+		}
+
+		intel_clk_add_lookup(ctx, hw, list->id);
+	}

No error to return? Are all PLLs optional?

Review

Quoted 3 lines
(quoted diff) +2 -0
+}
 
+#endif				/* __INTEL_CLK_PLL_H */

One TAB is enough.

Quoted 3 lines

+/*
+ * Copyright (C) 2018 Intel Corporation.
+ * Zhu YiXin <[email protected]>

On space after asterisk is enough.

drivers/clk/intel/clk-cgu.c line 25

Quoted 4 lines

+ */

drivers/clk/intel/clk-cgu.c new file +2 -0
+#define to_intel_clk_divider(_hw) \
+			container_of(_hw, struct intel_clk_divider, hw)

One TAB is enough.

drivers/clk/intel/clk-cgu.c line 49

Quoted 4 lines
drivers/clk/intel/clk-cgu.c new file +4 -0
+	val >>= shift;
+	val &= BIT(width) - 1;
+
+	return val;

Can be one line, though up to you.

drivers/clk/intel/clk-cgu.c line 55

Quoted 1 line
drivers/clk/intel/clk-cgu.c new file +1 -0
+	pr_debug("Add clk: %s, id: %u\n", clk_hw_get_name(hw), id);

Is this useful?

drivers/clk/intel/clk-cgu.c line 61

Quoted 3 lines
drivers/clk/intel/clk-cgu.c new file +2 -0
+static struct clk_hw
 
+*intel_clk_register_fixed(struct intel_clk_provider *ctx,

* is part of the type.

drivers/clk/intel/clk-cgu.c line 243

Quoted 5 lines
drivers/clk/intel/clk-cgu.c new file +3 -0
+			  const struct intel_clk_branch *list)
 
+static struct clk_hw
 
+*intel_clk_register_fixed_factor(struct intel_clk_provider *ctx,

Ditto.

Review

Quoted 5 lines
(quoted diff) +3 -0
+				 const struct intel_clk_branch *list)
 
+static struct clk_hw
 
+*intel_clk_register_gate(struct intel_clk_provider *ctx,

Ditto.

drivers/clk/intel/clk-lgm.c line 44

Quoted 8 lines
drivers/clk/intel/clk-lgm.c new file +7 -0
+			 const struct intel_clk_branch *list)
 
+/*
+ * Below table defines the pair's of regval & effective dividers.
+ * It's more efficient to provide an explicit table due to non-linear
+ * relation between values.
+ */
+static const struct clk_div_table pll_div[] = {

Does val == 0 follows the table, i.e. makes div == 1?

Quoted 10 lines
drivers/clk/intel/clk-lgm.c new file +10 -0
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },
+	{ .val = 3, .div = 4 },
+	{ .val = 4, .div = 5 },
+	{ .val = 5, .div = 6 },
+	{ .val = 6, .div = 8 },
+	{ .val = 7, .div = 10 },
+	{ .val = 8, .div = 12 },
+	{ .val = 9, .div = 16 },
+	{ .val = 10, .div = 20 },

drivers/clk/intel/clk-lgm.c line 64

Quoted 10 lines
drivers/clk/intel/clk-lgm.c new file +9 -0
+	{ .val = 11, .div = 24 },
+	{ .val = 12, .div = 32 },
+	{ .val = 13, .div = 40 },
+	{ .val = 14, .div = 48 },
+	{ .val = 15, .div = 64 },
+	{}
+};
 
+enum lgm_plls {
+	PLL0CZ, PLL0B, PLL1, PLL2, PLLPP, LJPLL3, LJPLL4

At the end you may put comma just for slightly better maintenance.

drivers/clk/intel/clk-lgm.c line 307

Quoted 13 lines
drivers/clk/intel/clk-lgm.c new file +11 -0
+};
 
+static int __init intel_lgm_cgu_probe(struct platform_device *pdev)
+{
+	struct intel_clk_provider *ctx;
+	struct regmap *map;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
 
+	if (!np)
+		return -ENODEV;

Wouldn't the below fail?
That said, do you need this check at all?

drivers/clk/intel/clk-lgm.c line 311

Quoted 5 lines
drivers/clk/intel/clk-lgm.c new file +4 -0
+
+	map = syscon_node_to_regmap(np);
+	if (IS_ERR(map))
 
+		return -ENODEV;

Why shadow error code?

drivers/clk/intel/clk-lgm.c line 315

Quoted 5 lines
drivers/clk/intel/clk-lgm.c new file +4 -0
+
+	ctx = intel_clk_init(dev, map, CLK_NR_CLKS);
+	if (IS_ERR(ctx))
 
+		return -ENOMEM;

Ditto.

Quoted 1 line

+}

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#3 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Andy,

Thanks for your review comments.

Quoted 10 lines · Andy Shevchenko
Quoted 8 lines · Rahul Tanwar

From: rtanwar <[email protected]>

Clock Generation Unit(CGU) is a new clock controller IP of a forthcoming Intel network processor SoC. It provides programming interfaces to control & configure all CPU & peripheral clocks. Add common clock framework based clock controller driver for CGU.

  drivers/clk/intel/Kconfig       |  13 +
  drivers/clk/intel/Makefile      |   4 +

Any plans what to do with existing x86 folder there?

I checked the x86 folder. This driver's clock controller IP is totally

different than other clock drivers inside x86. So having a common

driver source is not a option. It is of course possible to move this

driver inside x86 folder. Please let me know if you think moving

this driver inside x86 folder makes more sense.

Quoted 9 lines

drivers/clk/intel/Kconfig line 6

Quoted 8 lines

+++ b/drivers/clk/intel/Kconfig

drivers/clk/intel/Kconfig new file +6 -0
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+	depends on COMMON_CLK
+	select MFD_SYSCON
+	select OF_EARLY_FLATTREE
+	bool "Intel Clock Genration Unit support"

Is it for X86? Don't you need a dependency?

Yes agree, will update in v2.

Quoted 10 lines
Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +10 -0
+/*
+ * Calculate formula:
+ * rate = (prate * mult + (prate * frac) / frac_div) / div
+ */
+static unsigned long
+intel_pll_calc_rate(unsigned long prate, unsigned int mult,
+		    unsigned int div, unsigned int frac, unsigned int frac_div)
+{
+	u64 crate, frate, rate64;
+
Quoted 8 lines

drivers/clk/intel/clk-cgu-pll.c line 35

Quoted 4 lines
drivers/clk/intel/clk-cgu-pll.c new file +4 -0
+	rate64 = prate;
+	crate = rate64 * mult;
+
+	if (frac) {

This seems unnecessary.
I think you would like to check for frac_div instead?
Though I would rather to use frac = 0, frac_div = 1 and drop this conditional completely.

frac_div value is fixed to BIT(24) i.e. always a non zero value. mult & div

are directly read from registers and by design the register values for

mult & div is also always a non zero value. However, frac can logically

be zero. So, I still find if (frac) condition most suitable here.

Quoted 11 lines

drivers/clk/intel/clk-cgu-pll.c

Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +10 -0
+		frate = rate64 * frac;
+		do_div(frate, frac_div);
+		crate += frate;
+	}
+	do_div(crate, div);
+
+	return (unsigned long)crate;
+}
+static struct clk_hw
+*intel_clk_register_pll(struct intel_clk_provider *ctx,

* is part of type.

Yes, will update in v2.

Quoted 18 lines
Quoted 18 lines
drivers/clk/intel/clk-cgu-pll.c new file +18 -0
+			const struct intel_pll_clk_data *list)
+{
+	struct clk_init_data init;
+	struct intel_clk_pll *pll;
+	struct device *dev = ctx->dev;
+	struct clk_hw *hw;
+	int ret;
+
+	init.ops = &intel_lgm_pll_ops;
+	init.name = list->name;
+	init.parent_names = list->parent_names;
+	init.num_parents = list->num_parents;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	pll->map = ctx->map;
Quoted 8 lines

drivers/clk/intel/clk-cgu-pll.c line 135

Quoted 7 lines
drivers/clk/intel/clk-cgu-pll.c new file +7 -0
+	pll->dev = ctx->dev;
+	pll->reg = list->reg;
+	pll->flags = list->flags;
+	pll->type = list->type;
+	pll->hw.init = &init;
+
+	hw = &pll->hw;

Seems redundant temporary variable.

Agree, will update in v2.

Quoted 10 lines

drivers/clk/intel/clk-cgu-pll.c line 145

Quoted 9 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+	ret = clk_hw_register(dev, hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return hw;
+}
+void intel_clk_register_plls(struct intel_clk_provider *ctx,
+			     const struct intel_pll_clk_data *list,
+				unsigned int nr_clk)

Indentation issues.

Will fix in v2.

Quoted 10 lines

drivers/clk/intel/clk-cgu-pll.c line 154

Quoted 9 lines
drivers/clk/intel/clk-cgu-pll.c new file +9 -0
+{
+	struct clk_hw *hw;
+	int i;
+
+	for (i = 0; i < nr_clk; i++, list++) {
+		hw = intel_clk_register_pll(ctx, list);
+		if (IS_ERR(hw)) {
+			dev_err(ctx->dev, "failed to register pll: %s\n",
+				list->name);

Is it fatal or not?

Agree that its fatal if PLL registration fails, just that its highly unlikely.

I will modify it to return error & make probe fail in failure cases.

Quoted 6 lines

drivers/clk/intel/clk-cgu-pll.c line 159

Quoted 5 lines
drivers/clk/intel/clk-cgu-pll.c new file +5 -0
+			continue;
+		}
+
+		intel_clk_add_lookup(ctx, hw, list->id);
+	}

No error to return? Are all PLLs optional?

Will change it to return error code.

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+}
+#endif				/* __INTEL_CLK_PLL_H */

One TAB is enough.

Will fix in v2.

Quoted 4 lines
Quoted 3 lines

+/*
+ * Copyright (C) 2018 Intel Corporation.
+ * Zhu YiXin <[email protected]>

On space after asterisk is enough.

Will fix in v2.

Quoted 4 lines

drivers/clk/intel/clk-cgu.c line 25

Quoted 3 lines

+ */

drivers/clk/intel/clk-cgu.c new file +2 -0
+#define to_intel_clk_divider(_hw) \
+			container_of(_hw, struct intel_clk_divider, hw)

One TAB is enough.

Will fix in v2.

Quoted 2 lines

drivers/clk/intel/clk-cgu.c line 55

Quoted 1 line
drivers/clk/intel/clk-cgu.c new file +1 -0
+	pr_debug("Add clk: %s, id: %u\n", clk_hw_get_name(hw), id);

Is this useful?

Yes, IMO, this proves very useful for system wide clock issues

debugging during bootup.

Quoted 7 lines

drivers/clk/intel/clk-lgm.c line 44

Quoted 6 lines
drivers/clk/intel/clk-lgm.c new file +6 -0
+/*
+ * Below table defines the pair's of regval & effective dividers.
+ * It's more efficient to provide an explicit table due to non-linear
+ * relation between values.
+ */
+static const struct clk_div_table pll_div[] = {

Does val == 0 follows the table, i.e. makes div == 1?

0 val means output clock is ref clock i.e. div ==1. Agree that adding

.val = 0, .div =1 entry will make it more clear & complete.

Quoted 12 lines
Quoted 12 lines
drivers/clk/intel/clk-lgm.c new file +12 -0
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },
+	{ .val = 3, .div = 4 },
+	{ .val = 4, .div = 5 },
+	{ .val = 5, .div = 6 },
+	{ .val = 6, .div = 8 },
+	{ .val = 7, .div = 10 },
+	{ .val = 8, .div = 12 },
+	{ .val = 9, .div = 16 },
+	{ .val = 10, .div = 20 },
+	{ .val = 11, .div = 24 },
+	{ .val = 12, .div = 32 },
Quoted 8 lines

drivers/clk/intel/clk-lgm.c line 64

Quoted 7 lines
drivers/clk/intel/clk-lgm.c new file +7 -0
+	{ .val = 13, .div = 40 },
+	{ .val = 14, .div = 48 },
+	{ .val = 15, .div = 64 },
+	{}
+};
+enum lgm_plls {
+	PLL0CZ, PLL0B, PLL1, PLL2, PLLPP, LJPLL3, LJPLL4

At the end you may put comma just for slightly better maintenance.

Sure, will add.

Quoted 5 lines
Quoted 5 lines
drivers/clk/intel/clk-lgm.c new file +5 -0
+};
+static int __init intel_lgm_cgu_probe(struct platform_device *pdev)
+{
+	struct intel_clk_provider *ctx;
+	struct regmap *map;
Quoted 8 lines

drivers/clk/intel/clk-lgm.c line 307

Quoted 6 lines
drivers/clk/intel/clk-lgm.c new file +6 -0
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	if (!np)
+		return -ENODEV;

Wouldn't the below fail?
That said, do you need this check at all?

Agree, that this check is not needed. Will update in v2.

Quoted 5 lines

drivers/clk/intel/clk-lgm.c line 311

Quoted 4 lines
drivers/clk/intel/clk-lgm.c new file +4 -0
+
+	map = syscon_node_to_regmap(np);
+	if (IS_ERR(map))
+		return -ENODEV;

Why shadow error code?

Yes, will change in v2.

Quoted 5 lines

drivers/clk/intel/clk-lgm.c line 315

Quoted 4 lines
drivers/clk/intel/clk-lgm.c new file +4 -0
+
+	ctx = intel_clk_init(dev, map, CLK_NR_CLKS);
+	if (IS_ERR(ctx))
+		return -ENOMEM;

Ditto.

Will change in v2.

Regards,

Rahul

Quoted 1 line
Quoted 1 line

+}

#4 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoted 5 lines · Rahul
Quoted 4 lines · Andy Shevchenko
Quoted 2 lines · Rahul Tanwar
  drivers/clk/intel/Kconfig       |  13 +
  drivers/clk/intel/Makefile      |   4 +
Quoted 7 lines
Quoted 1 line

Any plans what to do with existing x86 folder there?

I checked the x86 folder. This driver's clock controller IP is totally different than other clock drivers inside x86. So having a common driver source is not a option. It is of course possible to move this driver inside x86 folder. Please let me know if you think moving this driver inside x86 folder makes more sense.

I'm talking about unambiguous folder where we keep Intel's drivers. With your series it will be confusing x86 vs intel.

Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
drivers/clk/intel/clk-cgu-pll.c new file +10 -0
+/*
+ * Calculate formula:
+ * rate = (prate * mult + (prate * frac) / frac_div) / div
+ */
+static unsigned long
+intel_pll_calc_rate(unsigned long prate, unsigned int mult,
+		    unsigned int div, unsigned int frac, unsigned int frac_div)
+{
+	u64 crate, frate, rate64;
+
Quoted 8 lines

drivers/clk/intel/clk-cgu-pll.c line 35

Quoted 4 lines
drivers/clk/intel/clk-cgu-pll.c new file +4 -0
+	rate64 = prate;
+	crate = rate64 * mult;
+
+	if (frac) {

This seems unnecessary.
I think you would like to check for frac_div instead?
Though I would rather to use frac = 0, frac_div = 1 and drop this conditional completely.

Quoted 4 lines

frac_div value is fixed to BIT(24) i.e. always a non zero value. mult & div are directly read from registers and by design the register values for mult & div is also always a non zero value. However, frac can logically be zero. So, I still find if (frac) condition most suitable here.

Then it's simple not needed.

Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
drivers/clk/intel/clk-cgu-pll.c new file +7 -0
+		frate = rate64 * frac;
+		do_div(frate, frac_div);
+		crate += frate;
+	}
+	do_div(crate, div);
+
+	return (unsigned long)crate;
Quoted 4 lines
Quoted 2 lines

drivers/clk/intel/clk-cgu-pll.c line 135

Quoted 1 line
drivers/clk/intel/clk-cgu-pll.c new file +1 -0
+	hw = &pll->hw;

Seems redundant temporary variable.

Agree, will update in v2.

Though in another method you have similar pattern. So, perhaps you may leave it for sake of consistency with patterns.

Quoted 5 lines
Quoted 2 lines

drivers/clk/intel/clk-cgu.c line 55

Quoted 1 line
drivers/clk/intel/clk-cgu.c new file +1 -0
+	pr_debug("Add clk: %s, id: %u\n", clk_hw_get_name(hw), id);

Is this useful?

Yes, IMO, this proves very useful for system wide clock issues debugging during bootup.

You may use function tracer for that.

Quoted 8 lines
Quoted 1 line

Does val == 0 follows the table, i.e. makes div == 1?

0 val means output clock is ref clock i.e. div ==1. Agree that adding .val = 0, .div =1 entry will make it more clear & complete.

Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 46

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 49

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 3, .div = 4 },
+	{ .val = 4, .div = 5 },
+	{ .val = 5, .div = 6 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 52

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 6, .div = 8 },
+	{ .val = 7, .div = 10 },
+	{ .val = 8, .div = 12 },

2

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 55

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 9, .div = 16 },
+	{ .val = 10, .div = 20 },
+	{ .val = 11, .div = 24 },

4

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 58

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 12, .div = 32 },
+	{ .val = 13, .div = 40 },
+	{ .val = 14, .div = 48 },

8

Quoted 1 line
Quoted 1 line

drivers/clk/intel/clk-lgm.c line 59

Quoted 1 line
drivers/clk/intel/clk-lgm.c new file +1 -0
+	{ .val = 15, .div = 64 },

16

So, now we see the pattern:

	div = val < 3 ? (val + 1) : (1 << ((val - 3) / 3));

So, can we eliminate table?

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#5 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoted 39 lines · Andy Shevchenko
Quoted 11 lines · Rahul
Quoted 3 lines · Andy Shevchenko

On Wed, Aug 28, 2019 at 03:00:17PM +0800, Rahul Tanwar wrote:

Does val == 0 follows the table, i.e. makes div == 1?

0 val means output clock is ref clock i.e. div ==1. Agree that adding .val = 0, .div =1 entry will make it more clear & complete.

Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 46

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 49

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 3, .div = 4 },
+	{ .val = 4, .div = 5 },
+	{ .val = 5, .div = 6 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 52

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 6, .div = 8 },
+	{ .val = 7, .div = 10 },
+	{ .val = 8, .div = 12 },

2

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 55

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 9, .div = 16 },
+	{ .val = 10, .div = 20 },
+	{ .val = 11, .div = 24 },

4

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 58

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 12, .div = 32 },
+	{ .val = 13, .div = 40 },
+	{ .val = 14, .div = 48 },

8

Quoted 8 lines
Quoted 1 line
Quoted 1 line

drivers/clk/intel/clk-lgm.c line 59

Quoted 1 line
drivers/clk/intel/clk-lgm.c new file +1 -0
+	{ .val = 15, .div = 64 },

16

So, now we see the pattern:

	div = val < 3 ? (val + 1) : (1 << ((val - 3) / 3));

It's not complete, but I think you got the idea.

Quoted 1 line

So, can we eliminate table?

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#6 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Andy,

Quoted 33 lines · Andy Shevchenko
Quoted 32 lines · Andy Shevchenko
Quoted 9 lines · Rahul
Quoted 2 lines · Andy Shevchenko

On Wed, Aug 28, 2019 at 03:00:17PM +0800, Rahul Tanwar wrote:
Does val == 0 follows the table, i.e. makes div == 1?

0 val means output clock is ref clock i.e. div ==1. Agree that adding .val = 0, .div =1 entry will make it more clear & complete.

Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 46

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 49

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 3, .div = 4 },
+	{ .val = 4, .div = 5 },
+	{ .val = 5, .div = 6 },

1

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 52

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 6, .div = 8 },
+	{ .val = 7, .div = 10 },
+	{ .val = 8, .div = 12 },

2

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 55

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 9, .div = 16 },
+	{ .val = 10, .div = 20 },
+	{ .val = 11, .div = 24 },

4

Quoted 3 lines
Quoted 3 lines

drivers/clk/intel/clk-lgm.c line 58

Quoted 3 lines
drivers/clk/intel/clk-lgm.c new file +3 -0
+	{ .val = 12, .div = 32 },
+	{ .val = 13, .div = 40 },
+	{ .val = 14, .div = 48 },

8

Quoted 10 lines
Quoted 7 lines
Quoted 1 line
Quoted 1 line

drivers/clk/intel/clk-lgm.c line 59

Quoted 1 line
drivers/clk/intel/clk-lgm.c new file +1 -0
+	{ .val = 15, .div = 64 },

16

So, now we see the pattern:

	div = val < 3 ? (val + 1) : (1 << ((val - 3) / 3));

It's not complete, but I think you got the idea.

Quoted 1 line

So, can we eliminate table?

In the desperation to eliminate table, below is what i can come up with:

        struct clk_div_table div_table[16];
        int i, j;

        for (i = 0; i < 16; i++)
                div_table[i].val = i;

        for (i = 0, j=0; i < 16; i+=3, j++) { div_table[i].div = (i == 0) ? (1 << j) : (1 << (j + 1)); if (i == 15)
                        break;

                div_table[i + 1].div = (i == 0) ? ((1 << j) + 1) :
                                        (1 << (j + 1)) + (1 << (j - 1)); div_table[i + 2].div = (3 << j);
        }

To me, table still looks a better approach. Also, table is more extendable & consistent w.r.t. clk framework & other referenced clk drivers.

Whats your opinion ?

Regards,
Rahul

#7 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoted 37 lines · Rahul
Quoted 36 lines · Andy Shevchenko
Quoted 35 lines · Andy Shevchenko
Quoted 6 lines · Rahul
Quoted 5 lines · Andy Shevchenko
Quoted 3 lines · Rahul Tanwar

+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },

1

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 5 },
+ { .val = 5, .div = 6 },

1

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

+ { .val = 6, .div = 8 },
+ { .val = 7, .div = 10 },
+ { .val = 8, .div = 12 },

2

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

+ { .val = 9, .div = 16 },
+ { .val = 10, .div = 20 },
+ { .val = 11, .div = 24 },

4

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

+ { .val = 12, .div = 32 },
+ { .val = 13, .div = 40 },
+ { .val = 14, .div = 48 },

8

Quoted 1 line
Quoted 1 line
Quoted 1 line

+ { .val = 15, .div = 64 },

16

So, now we see the pattern:

Quoted 8 lines
Quoted 4 lines
Quoted 1 line
     div = val < 3 ? (val + 1) : (1 << ((val - 3) / 3));

It's not complete, but I think you got the idea.

Quoted 1 line

So, can we eliminate table?

In the desperation to eliminate table, below is what i can come up with:

        struct clk_div_table div_table[16];

But this is not an elimination, it's just a replacement from static to dynamically calculated one.

Quoted 15 lines
        int i, j;

        for (i = 0; i < 16; i++)
                div_table[i].val = i;

        for (i = 0, j=0; i < 16; i+=3, j++) {
                div_table[i].div = (i == 0) ? (1 << j) : (1 << (j + 1));
                if (i == 15)
                        break;

                div_table[i + 1].div = (i == 0) ? ((1 << j) + 1) :
                                        (1 << (j + 1)) + (1 << (j - 1));
                div_table[i + 2].div = (3 << j);
        }
Quoted 4 lines

To me, table still looks a better approach. Also, table is more extendable & consistent w.r.t. clk framework & other referenced clk drivers.

Whats your opinion ?

Whatever CCF maintainers is fine with.

--
With Best Regards,
Andy Shevchenko

maintainer
#8 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoting Andy Shevchenko (2019-12-07 06:57:43)

Quoted 31 lines
Quoted 10 lines · Rahul
Quoted 5 lines · Andy Shevchenko
Quoted 2 lines
     div = val < 3 ? (val + 1) : (1 << ((val - 3) / 3));

It's not complete, but I think you got the idea.

Quoted 1 line

So, can we eliminate table?

In the desperation to eliminate table, below is what i can come up with:

        struct clk_div_table div_table[16];

But this is not an elimination, it's just a replacement from static to dynamically calculated one.

Quoted 15 lines
        int i, j;

        for (i = 0; i < 16; i++)
                div_table[i].val = i;

        for (i = 0, j=0; i < 16; i+=3, j++) {
                div_table[i].div = (i == 0) ? (1 << j) : (1 << (j + 1));
                if (i == 15)
                        break;

                div_table[i + 1].div = (i == 0) ? ((1 << j) + 1) :
                                        (1 << (j + 1)) + (1 << (j - 1));
                div_table[i + 2].div = (3 << j);
        }
Quoted 7 lines
Quoted 4 lines

To me, table still looks a better approach. Also, table is more extendable & consistent w.r.t. clk framework & other referenced clk drivers.

Whats your opinion ?

Whatever CCF maintainers is fine with.

Table is fine. Or something that calculates is also fine. Is it going to be extended in the future? If we're talking about a driver for hardware I wonder if this is really going to change in the future.

Please resend so your binding can be reviewed.

#9 lore raw

RE: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

In reply to Rahul Tanwar

Hello,

I only noticed this patchset today and I don't have much time left. Here's my initial impressions without going through the code in detail. I'll continue my review in the next days (as time permits).

As with all other Intel LGM patches: I don't have access to the datasheets, so it's possible that I don't understand <insert topic here> feel free to correct me in this case (I appreciate an explanation where I was wrong, so I can learn from it)

[...]

drivers/clk/intel/Kconfig new file +4 -0
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+	depends on COMMON_CLK
+	select MFD_SYSCON

can you please explain the reason why you need to use syscon? also please see [0] for a comment from Rob on another LGM dt-binding regarding syscon

+ select OF_EARLY_FLATTREE
there's not a single other "select OF_EARLY_FLATTREE" in driver/clk I'm not saying this is wrong but it makes me curious why you need this

[...]

drivers/clk/intel/clk-cgu.h new file +54 -0

54 lines not on this page · raw message

I know at least two existing regmap clock implementations:
- drivers/clk/qcom/clk-regmap*
- drivers/clk/meson/clk-regmap*

it would be great if we could decide to re-use one of those for the "generic" clock types (mux, divider and gate).
Stephen, do you have any preference here?
personally I like the meson one, but I'm biased because I've used it a lot in the past and I haven't used the qcom one at all.

Martin

[0] https://lkml.org/lkml/2019/8/27/849

#10 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Martin,

Quoted 20 lines · Martin Blumenstingl

Hello,

I only noticed this patchset today and I don't have much time left. Here's my initial impressions without going through the code in detail. I'll continue my review in the next days (as time permits).

As with all other Intel LGM patches: I don't have access to the datasheets, so it's possible that I don't understand <insert topic here> feel free to correct me in this case (I appreciate an explanation where I was wrong, so I can learn from it)

[...]

drivers/clk/intel/Kconfig new file +4 -0
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+	depends on COMMON_CLK
+	select MFD_SYSCON
Quoted 3 lines

can you please explain the reason why you need to use syscon? also please see [0] for a comment from Rob on another LGM dt-binding regarding syscon

Actually, there is no need to use syscon for CGU in LGM. It got carried

over from older SoCs (Falcon Mountain) where CGU was a MFD device

because it included PHY registers as well. And PHY drivers were using

syscon node to access CGU regmap. But for LGM, this is not the case.

My understanding is that if we do not use syscon, then there is no

point in using regmap because this driver uses simple 32 bit register

access. Can directly read/write registers using readl() & writel().

Would you agree ?

Yi Xin, please correct me if you think i am mistaken anywhere. If not,

i will change the driver to not use regmap & instead use readl() &

writel().

Quoted 3 lines
drivers/clk/intel/Kconfig new file +1 -0
+	select OF_EARLY_FLATTREE

there's not a single other "select OF_EARLY_FLATTREE" in driver/clk I'm not saying this is wrong but it makes me curious why you need this

We need OF_EARLY_FLATTREE for LGM. But adding a new x86

platform for LGM is discouraged because that would lead to too

many platforms. Only differentiating factor for LGM is CPU model

ID but it can differentiate only at run time. So i had no option

other then enabling it with some LGM specific core system module

driver and CGU seemed perfect for this purpose.

Quoted 65 lines

[...]

drivers/clk/intel/clk-cgu.h new file +54 -0
new file mode 100644
index 000000000000..e44396b4aad7
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright(c) 2018 Intel Corporation.
+ *  Zhu YiXin <[email protected]>
+ */
+
+#ifndef __INTEL_CLK_H
+#define __INTEL_CLK_H
+
+struct intel_clk_mux {
+	struct clk_hw hw;
+	struct device *dev;
+	struct regmap *map;
+	unsigned int reg;
+	u8 shift;
+	u8 width;
+	unsigned long flags;
+};
+
+struct intel_clk_divider {
+	struct clk_hw hw;
+	struct device *dev;
+	struct regmap *map;
+	unsigned int reg;
+	u8 shift;
+	u8 width;
+	unsigned long flags;
+	const struct clk_div_table *table;
+};
+
+struct intel_clk_ddiv {
+	struct clk_hw hw;
+	struct device *dev;
+	struct regmap *map;
+	unsigned int reg;
+	u8 shift0;
+	u8 width0;
+	u8 shift1;
+	u8 width1;
+	u8 shift2;
+	u8 width2;
+	unsigned int mult;
+	unsigned int div;
+	unsigned long flags;
+};
+
+struct intel_clk_gate {
+	struct clk_hw hw;
+	struct device *dev;
+	struct regmap *map;
+	unsigned int reg;
+	u8 shift;
+	unsigned long flags;
+};

I know at least two existing regmap clock implementations:
- drivers/clk/qcom/clk-regmap*
- drivers/clk/meson/clk-regmap*

Quoted 5 lines

it would be great if we could decide to re-use one of those for the "generic" clock types (mux, divider and gate).
Stephen, do you have any preference here?
personally I like the meson one, but I'm biased because I've used it a lot in the past and I haven't used the qcom one at all.

I went through meson & qcom regmap clock code. Agree, it can be

reused for mux, divider and gate. But as mentioned above, i am now

considering to move away from using regmap.

Regards,

Rahul

#11 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Rahul,

Quoted 26 lines · Rahul

Hi Martin,

Quoted 21 lines · Martin Blumenstingl

Hello,

I only noticed this patchset today and I don't have much time left. Here's my initial impressions without going through the code in detail. I'll continue my review in the next days (as time permits).

As with all other Intel LGM patches: I don't have access to the datasheets, so it's possible that I don't understand <insert topic here> feel free to correct me in this case (I appreciate an explanation where I was wrong, so I can learn from it)

[...]

drivers/clk/intel/Kconfig new file +4 -0
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+config INTEL_LGM_CGU_CLK
+     depends on COMMON_CLK
+     select MFD_SYSCON

can you please explain the reason why you need to use syscon?

Quoted 8 lines
Quoted 2 lines

also please see [0] for a comment from Rob on another LGM dt-binding regarding syscon

Actually, there is no need to use syscon for CGU in LGM. It got carried over from older SoCs (Falcon Mountain) where CGU was a MFD device because it included PHY registers as well. And PHY drivers were using syscon node to access CGU regmap. But for LGM, this is not the case.

I see, to me it seems like LGM got a nice set of register cleanups! so I'm all for dropping the syscon compatible

Quoted 5 lines

My understanding is that if we do not use syscon, then there is no point in using regmap because this driver uses simple 32 bit register access. Can directly read/write registers using readl() & writel().

Would you agree ?

if there was only the LGM SoC then I would say: drop regmap

however, last year a driver for the GRX350/GRX550 SoCs was proposed: [0] this was never updated but it seems to use the same "framework" as the LGM driver
with this in mind I am for keeping regmap support because.
I think it will be easier to add support for old SoCs like GRX350/GRX550 (but also VRX200), because the PLL sub-driver (I am assuming that it is similar on all SoCs) or some other helpers can be re-used across various SoCs instead of "duplicating" code (where one variant would use regmap and the other readl/writel).

[...]

Quoted 11 lines
Quoted 3 lines

+ select OF_EARLY_FLATTREE
there's not a single other "select OF_EARLY_FLATTREE" in driver/clk I'm not saying this is wrong but it makes me curious why you need this

We need OF_EARLY_FLATTREE for LGM. But adding a new x86 platform for LGM is discouraged because that would lead to too many platforms. Only differentiating factor for LGM is CPU model ID but it can differentiate only at run time. So i had no option other then enabling it with some LGM specific core system module driver and CGU seemed perfect for this purpose.

so when my x86 kernel maintainer enables CONFIG_INTEL_LGM_CGU_CLK then OF_EARLY_FLATTREE is enabled as well.
does this hurt any existing x86 platform? if not: why can't we enable it for x86 unconditionally?

[...]

Quoted 64 lines
Quoted 64 lines
drivers/clk/intel/clk-cgu.h new file +54 -0
new file mode 100644
index 000000000000..e44396b4aad7
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright(c) 2018 Intel Corporation.
+ *  Zhu YiXin <[email protected]>
+ */
+
+#ifndef __INTEL_CLK_H
+#define __INTEL_CLK_H
+
+struct intel_clk_mux {
+     struct clk_hw hw;
+     struct device *dev;
+     struct regmap *map;
+     unsigned int reg;
+     u8 shift;
+     u8 width;
+     unsigned long flags;
+};
+
+struct intel_clk_divider {
+     struct clk_hw hw;
+     struct device *dev;
+     struct regmap *map;
+     unsigned int reg;
+     u8 shift;
+     u8 width;
+     unsigned long flags;
+     const struct clk_div_table *table;
+};
+
+struct intel_clk_ddiv {
+     struct clk_hw hw;
+     struct device *dev;
+     struct regmap *map;
+     unsigned int reg;
+     u8 shift0;
+     u8 width0;
+     u8 shift1;
+     u8 width1;
+     u8 shift2;
+     u8 width2;
+     unsigned int mult;
+     unsigned int div;
+     unsigned long flags;
+};
+
+struct intel_clk_gate {
+     struct clk_hw hw;
+     struct device *dev;
+     struct regmap *map;
+     unsigned int reg;
+     u8 shift;
+     unsigned long flags;
+};

I know at least two existing regmap clock implementations:
- drivers/clk/qcom/clk-regmap*
- drivers/clk/meson/clk-regmap*

Quoted 10 lines
Quoted 5 lines

it would be great if we could decide to re-use one of those for the "generic" clock types (mux, divider and gate).
Stephen, do you have any preference here?
personally I like the meson one, but I'm biased because I've used it a lot in the past and I haven't used the qcom one at all.

I went through meson & qcom regmap clock code. Agree, it can be reused for mux, divider and gate. But as mentioned above, i am now considering to move away from using regmap.

thank you for evaluating them. let's continue the discussion above whether regmap should be used - after that we decide (if needed) which regmap implementation to use

Martin

[0] https://patchwork.kernel.org/patch/10554401/

#12 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Martin,

Quoted 7 lines · Martin Blumenstingl
Quoted 5 lines

My understanding is that if we do not use syscon, then there is no point in using regmap because this driver uses simple 32 bit register access. Can directly read/write registers using readl() & writel().

Would you agree ?

if there was only the LGM SoC then I would say: drop regmap

Quoted 9 lines

however, last year a driver for the GRX350/GRX550 SoCs was proposed: [0] this was never updated but it seems to use the same "framework" as the LGM driver
with this in mind I am for keeping regmap support because.
I think it will be easier to add support for old SoCs like GRX350/GRX550 (but also VRX200), because the PLL sub-driver (I am assuming that it is similar on all SoCs) or some other helpers can be re-used across various SoCs instead of "duplicating" code (where one variant would use regmap and the other readl/writel).

Earlier, we had discussed about it in our team.  There are no plans to

upstream mips based platform code, past up-streaming efforts for mips

platforms were also dropped. GRX350/GRX550/VRX200 are all mips

based platforms. Plan is to upstream only x86 based platforms. In-fact,

i had removed GRX & other older SoCs support from this driver before

sending for review. So we can consider only x86 based LGM family of

SoCs for this driver & all of them will be reusing same IP.

Quoted 11 lines

[...]

Quoted 10 lines
Quoted 3 lines

+ select OF_EARLY_FLATTREE
there's not a single other "select OF_EARLY_FLATTREE" in driver/clk I'm not saying this is wrong but it makes me curious why you need this

We need OF_EARLY_FLATTREE for LGM. But adding a new x86 platform for LGM is discouraged because that would lead to too many platforms. Only differentiating factor for LGM is CPU model ID but it can differentiate only at run time. So i had no option other then enabling it with some LGM specific core system module driver and CGU seemed perfect for this purpose.

Quoted 4 lines

so when my x86 kernel maintainer enables CONFIG_INTEL_LGM_CGU_CLK then OF_EARLY_FLATTREE is enabled as well.
does this hurt any existing x86 platform? if not: why can't we enable it for x86 unconditionally?

IMHO, it will not hurt any other existing x86 platform but enabling it for

x86 unconditionally also doesn't sound like a good idea. I now get your

point that enabling OF_EARLY_FLATTREE here is a bit odd. I will remove

it in next patch.

Regards,

Rahul

Quoted 12 lines

I went through meson & qcom regmap clock code. Agree, it can be reused for mux, divider and gate. But as mentioned above, i am now considering to move away from using regmap.
thank you for evaluating them. let's continue the discussion above whether regmap should be used - after that we decide (if needed) which regmap implementation to use

Martin

[0] https://patchwork.kernel.org/patch/10554401/

#13 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Hi Rahul,

Quoted 23 lines · Rahul

Hi Martin,

Quoted 7 lines · Martin Blumenstingl
Quoted 5 lines

My understanding is that if we do not use syscon, then there is no point in using regmap because this driver uses simple 32 bit register access. Can directly read/write registers using readl() & writel().

Would you agree ?

if there was only the LGM SoC then I would say: drop regmap

Quoted 9 lines

however, last year a driver for the GRX350/GRX550 SoCs was proposed: [0] this was never updated but it seems to use the same "framework" as the LGM driver
with this in mind I am for keeping regmap support because.
I think it will be easier to add support for old SoCs like GRX350/GRX550 (but also VRX200), because the PLL sub-driver (I am assuming that it is similar on all SoCs) or some other helpers can be re-used across various SoCs instead of "duplicating" code (where one variant would use regmap and the other readl/writel).

Quoted 7 lines

Earlier, we had discussed about it in our team. There are no plans to upstream mips based platform code, past up-streaming efforts for mips platforms were also dropped. GRX350/GRX550/VRX200 are all mips based platforms. Plan is to upstream only x86 based platforms. In-fact, i had removed GRX & other older SoCs support from this driver before sending for review. So we can consider only x86 based LGM family of SoCs for this driver & all of them will be reusing same IP.

this is very sad news
as far as I can tell many IP cores are similar/identical on GRX350/GRX550, LGM and even VRX200

I already know that VRX200 is a legacy product and you won't be supporting it once LGM support lands upstream you could add support for GRX350/GRX550 with small to medium effort
that is a big win (in my opinion) because it means happier end-users (see XWAY and VRX200 support in OpenWrt for example: while support from Intel/Lantiq has died long ago these devices can still run a recent LTS kernel and get security updates. without OpenWrt these devices would probably end up as electronic waste)

maybe implementing a re-usable regmap clock driver (for mux, gate and divider) means less effort (compared to converting everything to standard clock ops) for you.
(we did the switch from standard clock ops to regmap for the Amlogic Meson clock drivers when we discovered that there were some non-clock registers that belong to other IP blocks in it and it was a lot of effort)
this will allow you to add support for GRX350/GRX550 in the future if demand for upstream drivers rises.

Martin

#14 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoted 36 lines · Martin Blumenstingl

Hi Rahul,

Quoted 21 lines · Rahul

Hi Martin,

Quoted 7 lines · Martin Blumenstingl
Quoted 5 lines

My understanding is that if we do not use syscon, then there is no point in using regmap because this driver uses simple 32 bit register access. Can directly read/write registers using readl() & writel().

Would you agree ?

if there was only the LGM SoC then I would say: drop regmap

Quoted 9 lines

however, last year a driver for the GRX350/GRX550 SoCs was proposed: [0] this was never updated but it seems to use the same "framework" as the LGM driver
with this in mind I am for keeping regmap support because.
I think it will be easier to add support for old SoCs like GRX350/GRX550 (but also VRX200), because the PLL sub-driver (I am assuming that it is similar on all SoCs) or some other helpers can be re-used across various SoCs instead of "duplicating" code (where one variant would use regmap and the other readl/writel).

Quoted 7 lines

Earlier, we had discussed about it in our team. There are no plans to upstream mips based platform code, past up-streaming efforts for mips platforms were also dropped. GRX350/GRX550/VRX200 are all mips based platforms. Plan is to upstream only x86 based platforms. In-fact, i had removed GRX & other older SoCs support from this driver before sending for review. So we can consider only x86 based LGM family of SoCs for this driver & all of them will be reusing same IP.

this is very sad news
as far as I can tell many IP cores are similar/identical on GRX350/GRX550, LGM and even VRX200

Quoted 8 lines

I already know that VRX200 is a legacy product and you won't be supporting it once LGM support lands upstream you could add support for GRX350/GRX550 with small to medium effort
that is a big win (in my opinion) because it means happier end-users (see XWAY and VRX200 support in OpenWrt for example: while support from Intel/Lantiq has died long ago these devices can still run a recent LTS kernel and get security updates. without OpenWrt these devices would probably end up as electronic waste)

I'm sorry to say that we don't plan to support legacy SOCs. As you might know, we tried to upstream some of drivers last year but found a lot of problems to support both legacy SOCs and LGM.

It was a real pain to support all of them with limited resources/time and we couldn't make it. Our new plan was to reattempt to upstream LGM drivers only. This can be more realistic target for us.

Quoted 10 lines

maybe implementing a re-usable regmap clock driver (for mux, gate and divider) means less effort (compared to converting everything to standard clock ops) for you.
(we did the switch from standard clock ops to regmap for the Amlogic Meson clock drivers when we discovered that there were some non-clock registers that belong to other IP blocks in it and it was a lot of effort)
this will allow you to add support for GRX350/GRX550 in the future if demand for upstream drivers rises.

I've discussed internally the amount of efforts to create a reusable regmap clock driver which might be reused by other companies too.

It seems it requires significant efforts for implementation/tests. As we don't plan to support our old SOCs for now, I'm not sure if we need to put such a big efforts.

Stephan,

It seems you don't like both meson/qcom regmap clock implementation.

What is your opinion for our current CGU clock driver implementation?

Quoted 3 lines

Martin

maintainer
#15 lore raw

Re: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

Quoting Kim, Cheol Yong (2019-09-09 07:16:29)

Quoted 8 lines

I've discussed internally the amount of efforts to create a reusable regmap clock driver which might be reused by other companies too.

It seems it requires significant efforts for implementation/tests. As we don't plan to support our old SOCs for now, I'm not sure if we need to put such a big efforts.

Quoted 7 lines

Stephan,

It seems you don't like both meson/qcom regmap clock implementation.

What is your opinion for our current CGU clock driver implementation?

If you're not going to use regmap in CGU then it doesn't matter to try to consolidate the regmap clk implementations.

maintainer
#16 lore raw

RE: [PATCH v1 1/2] clk: intel: Add CGU clock driver for a new SoC

In reply to Martin Blumenstingl

Quoting Martin Blumenstingl (2019-09-02 15:20:15)

Quoted 12 lines
drivers/clk/intel/clk-cgu.h new file +8 -0
+struct intel_clk_gate {
+       struct clk_hw hw;
+       struct device *dev;
+       struct regmap *map;
+       unsigned int reg;
+       u8 shift;
+       unsigned long flags;
+};

I know at least two existing regmap clock implementations:
- drivers/clk/qcom/clk-regmap*
- drivers/clk/meson/clk-regmap*

Quoted 5 lines

it would be great if we could decide to re-use one of those for the "generic" clock types (mux, divider and gate).
Stephen, do you have any preference here?
personally I like the meson one, but I'm biased because I've used it a lot in the past and I haven't used the qcom one at all.

The topic comes up once in a while. Making a set of regmap clk_ops and structures might work to consolidate the code across the different drivers. I can't recall why we didn't combine the two implementations at that point. I do remember that Mike was opposed to pushing it directly into the core framework as part of struct clk_hw out of fear of bloating the clk_hw structure.

I don't particularly like how the meson implementation makes every clk the same type and has a 'data' member of clk_regmap to differentiate the types (mux, gate, div, etc.) It avoids nesting structures but otherwise serves the same purpose as having there be container structures for the different types that all have a clk_regmap structure inside. qcom implementation also takes a shortcut and adds enable/disable logic into the clk_regmap structure. To consolidate the two I imagine we would need to change both implementations to use a struct like:

	struct clk_regmap {
		struct clk_hw hw;
		struct regmap *map;
	};
#17 lore raw

PATCH 2/2 dt-bindings: clk: intel: Add bindings document & header file for CGU

In reply to Rahul Tanwar

Clock generation unit(CGU) is a clock controller IP of Intel's Lightning Mountain(LGM) SoC. Add DT bindings include file and document for CGU clock controller driver of LGM.

---
 .../devicetree/bindings/clock/intel,cgu-lgm.yaml   |  61 +++++++++
 include/dt-bindings/clock/intel,lgm-clk.h          | 150 +++++++++++++++++++++
 2 files changed, 211 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml
 create mode 100644 include/dt-bindings/clock/intel,lgm-clk.h
Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml new file +61 -0
new file mode 100644
index 000000000000..8bc5c6f9f792
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bindings/clock/intel,cgu-lgm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel Lightning Mountain SoC's Clock Controller(CGU) Binding
+
+maintainers:
+  - Rahul Tanwar <[email protected]>
+
+description: |
+  Lightning Mountain(LGM) SoC's Clock Generation Unit(CGU) driver provides
+  all means to access the CGU hardware module in order to generate a series
+  of clocks for the whole system and individual peripherals.
+
+  This binding uses the common clock bindings
+  [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+properties:
+  compatible:
+    const: intel,cgu-lgm
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+examples:
+  # CGU node
+  - |
+    cgu: cgu@e0200000 {
+        compatible = "intel,cgu-lgm", "syscon";
+        reg = <0xe0200000 0x33c>;
+        #clock-cells = <1>;
+    };
+
+  # Example of clock consumer (UART driver)
+  - |
+    asc0: serial@e0a00000 {
+        compatible = "intel,lgm-asc";
+        reg = <0xe0a00000 0x1000>;
+        interrupt-parent = <&ioapic1>;
+        interrupts = <128 1>;
+        interrupt-names = "asc_irq";
+        clocks = <&cgu0 LGM_CLK_NOC4>, <&cgu0 LGM_GCLK_ASC0>;
+        clock-names = "freq", "asc";
+        pinctrl-names = "default";
+        pinctrl-0 = <&uart0>;
+    };
+
+...
include/dt-bindings/clock/intel,lgm-clk.h new file +150 -0

150 lines not on this page · raw message

Signature · 1 line
2.11.0
#18 lore raw

Re: [PATCH v1 2/2] dt-bindings: clk: intel: Add bindings document & header file for CGU

Quoted 4 lines · Rahul Tanwar

Clock generation unit(CGU) is a clock controller IP of Intel's Lightning Mountain(LGM) SoC. Add DT bindings include file and document for CGU clock controller driver of LGM.

If you want your binding patch reviewed, you must resend it to the DT list.