All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] clk: xgene: Add PMD clock support
@ 2016-08-23 15:52 ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel, lho,
	Duc Dang, Hoan Tran

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Hoan Tran (3):
  Documentation: dtb: xgene: Add PMD clock binding
  clk: xgene: Add PMD clock
  arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks

 Documentation/devicetree/bindings/clock/xgene.txt |  22 +++
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi        |  64 +++++++
 drivers/clk/clk-xgene.c                           | 223 ++++++++++++++++++++++
 3 files changed, 309 insertions(+)

-- 
1.9.1

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

* [PATCH 0/3] clk: xgene: Add PMD clock support
@ 2016-08-23 15:52 ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: devicetree, Hoan Tran, Duc Dang, linux-kernel, lho, linux-clk,
	linux-arm-kernel

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Hoan Tran (3):
  Documentation: dtb: xgene: Add PMD clock binding
  clk: xgene: Add PMD clock
  arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks

 Documentation/devicetree/bindings/clock/xgene.txt |  22 +++
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi        |  64 +++++++
 drivers/clk/clk-xgene.c                           | 223 ++++++++++++++++++++++
 3 files changed, 309 insertions(+)

-- 
1.9.1

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

* [PATCH 0/3] clk: xgene: Add PMD clock support
@ 2016-08-23 15:52 ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Hoan Tran (3):
  Documentation: dtb: xgene: Add PMD clock binding
  clk: xgene: Add PMD clock
  arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks

 Documentation/devicetree/bindings/clock/xgene.txt |  22 +++
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi        |  64 +++++++
 drivers/clk/clk-xgene.c                           | 223 ++++++++++++++++++++++
 3 files changed, 309 insertions(+)

-- 
1.9.1

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

* [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
  2016-08-23 15:52 ` Hoan Tran
@ 2016-08-23 15:52   ` Hoan Tran
  -1 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel, lho,
	Duc Dang, Hoan Tran

Add APM X-Gene clock binding documentation for PMD clock.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
index 82f9638..c381733 100644
--- a/Documentation/devicetree/bindings/clock/xgene.txt
+++ b/Documentation/devicetree/bindings/clock/xgene.txt
@@ -8,6 +8,7 @@ Required properties:
 - compatible : shall be one of the following:
 	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
 	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
+	"apm,xgene-pmd-clock" - for a X-Gene PMD clock
 	"apm,xgene-device-clock" - for a X-Gene device clock
 	"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
 	"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
@@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
 Optional properties for PLL clocks:
 - clock-names : shall be the name of the PLL. If missing, use the device name.
 
+Required properties for PMD clocks:
+- reg : shall be the physical register address for the pmd clock.
+- clocks : shall be the input parent clock phandle for the clock.
+- #clock-cells : shall be set to 1.
+- clock-output-names : shall be the name of the clock referenced by derive
+  clock.
+- clock-shift: Bit shift of the clock register. Default is 0.
+- clock-width: Width of the clock register. Default is 32.
+Optional properties for PLL clocks:
+- clock-names : shall be the name of the clock. If missing, use the device name.
+
 Required properties for device clocks:
 - reg : shall be a list of address and length pairs describing the CSR
          reset and/or the divider. Either may be omitted, but at least
@@ -59,6 +71,16 @@ For example:
 		type = <0>;
 	};
 
+	pmd0clk: pmd0clk {
+		compatible = "apm,xgene-pmd-clock";
+		#clock-cells = <1>;
+		clocks = <&pmdpll 0>;
+		reg = <0x0 0x7E200200 0x0 0x10>;
+		clock-shift = <8>;
+		clock-width = <3>;
+		clock-output-names = "pmd0clk";
+	};
+
 	socpll: socpll@17000120 {
 		compatible = "apm,xgene-socpll-clock";
 		#clock-cells = <1>;
-- 
1.9.1

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

* [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
@ 2016-08-23 15:52   ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add APM X-Gene clock binding documentation for PMD clock.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
index 82f9638..c381733 100644
--- a/Documentation/devicetree/bindings/clock/xgene.txt
+++ b/Documentation/devicetree/bindings/clock/xgene.txt
@@ -8,6 +8,7 @@ Required properties:
 - compatible : shall be one of the following:
 	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
 	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
+	"apm,xgene-pmd-clock" - for a X-Gene PMD clock
 	"apm,xgene-device-clock" - for a X-Gene device clock
 	"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
 	"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
@@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
 Optional properties for PLL clocks:
 - clock-names : shall be the name of the PLL. If missing, use the device name.
 
+Required properties for PMD clocks:
+- reg : shall be the physical register address for the pmd clock.
+- clocks : shall be the input parent clock phandle for the clock.
+- #clock-cells : shall be set to 1.
+- clock-output-names : shall be the name of the clock referenced by derive
+  clock.
+- clock-shift: Bit shift of the clock register. Default is 0.
+- clock-width: Width of the clock register. Default is 32.
+Optional properties for PLL clocks:
+- clock-names : shall be the name of the clock. If missing, use the device name.
+
 Required properties for device clocks:
 - reg : shall be a list of address and length pairs describing the CSR
          reset and/or the divider. Either may be omitted, but at least
@@ -59,6 +71,16 @@ For example:
 		type = <0>;
 	};
 
+	pmd0clk: pmd0clk {
+		compatible = "apm,xgene-pmd-clock";
+		#clock-cells = <1>;
+		clocks = <&pmdpll 0>;
+		reg = <0x0 0x7E200200 0x0 0x10>;
+		clock-shift = <8>;
+		clock-width = <3>;
+		clock-output-names = "pmd0clk";
+	};
+
 	socpll: socpll at 17000120 {
 		compatible = "apm,xgene-socpll-clock";
 		#clock-cells = <1>;
-- 
1.9.1

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

* [PATCH 2/3] clk: xgene: Add PMD clock
@ 2016-08-23 15:52   ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel, lho,
	Duc Dang, Hoan Tran

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 drivers/clk/clk-xgene.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)

diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 3433132..66ce200 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -217,6 +217,228 @@ static void xgene_pcppllclk_init(struct device_node *np)
 	xgene_pllclk_init(np, PLL_TYPE_PCP);
 }
 
+/**
+ * struct xgene_clk_pmd - PMD clock
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	register containing the fractional scale multiplier (scaler)
+ * @shift:	shift to the unit bit field
+ * @denom:	1/denominator unit
+ * @lock:	register lock
+ * Flags:
+ * XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
+ *	from the register plus one. For example,
+ *		0 for (0 + 1) / denom,
+ *		1 for (1 + 1) / denom and etc.
+ *	If this flag is set, it is
+ *		0 for (denom - 0) / denom,
+ *		1 for (denom - 1) / denom and etc.
+ *
+ */
+struct xgene_clk_pmd {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		shift;
+	u32		mask;
+	u64		denom;
+	u32		flags;
+	spinlock_t	*lock;
+};
+
+#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)
+
+#define XGENE_CLK_PMD_SCALE_INVERTED	BIT(0)
+
+static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 ret, scale;
+	u32 val;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	ret = (u64)parent_rate;
+
+	scale = (val & fd->mask) >> fd->shift;
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale++;
+
+	/* freq = parent_rate * scaler / denom */
+	do_div(ret, fd->denom);
+	ret *= scale;
+	if (ret == 0)
+		ret = (u64)parent_rate;
+
+	return ret;
+}
+
+static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	u64 ret, scale;
+
+	if (!rate || rate >= *parent_rate)
+		return *parent_rate;
+
+	/* freq = parent_rate * scaler / denom */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, *parent_rate);
+
+	ret = (u64)*parent_rate * scale;
+	do_div(ret, fd->denom);
+
+	return ret;
+}
+
+static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 scale, ret;
+	u32 val;
+
+	/*
+	 * Compute the scaler:
+	 *
+	 * freq = parent_rate * scaler / denom, or
+	 * scaler = freq * denom / parent_rate
+	 */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);
+
+	/* Check if inverted */
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale--;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+	val &= ~fd->mask;
+	val |= (scale << fd->shift);
+	clk_writel(val, fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	return 0;
+}
+
+static const struct clk_ops xgene_clk_pmd_ops = {
+	.recalc_rate = xgene_clk_pmd_recalc_rate,
+	.round_rate = xgene_clk_pmd_round_rate,
+	.set_rate = xgene_clk_pmd_set_rate,
+};
+
+static struct clk *
+xgene_register_clk_pmd(struct device *dev,
+		       const char *name, const char *parent_name,
+		       unsigned long flags, void __iomem *reg, u8 shift,
+		       u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
+{
+	struct xgene_clk_pmd *fd;
+	struct clk_init_data init;
+	struct clk *clk;
+
+	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+	if (!fd)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &xgene_clk_pmd_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	fd->reg = reg;
+	fd->shift = shift;
+	fd->mask = (BIT(width) - 1) << shift;
+	fd->denom = denom;
+	fd->flags = clk_flags;
+	fd->lock = lock;
+	fd->hw.init = &init;
+
+	clk = clk_register(dev, &fd->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: could not register clk %s\n", __func__, name);
+		kfree(fd);
+		return NULL;
+	}
+
+	return clk;
+}
+
+static void xgene_pmdclk_init(struct device_node *np)
+{
+	const char *clk_name = np->full_name;
+	void __iomem *csr_reg;
+	struct resource res;
+	struct clk *clk;
+	u32 shift, width;
+	u64 denom;
+	u32 flags = 0;
+	int rc;
+
+	/* Check if the entry is disabled */
+	if (!of_device_is_available(np))
+		return;
+
+	/* Parse the DTS register for resource */
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc != 0) {
+		pr_err("no DTS register for %s\n", np->full_name);
+		return;
+	}
+	csr_reg = of_iomap(np, 0);
+	if (!csr_reg) {
+		pr_err("Unable to map resource for %s\n", np->full_name);
+		return;
+	}
+	if (of_property_read_u32(np, "clock-shift", &shift))
+		shift = 0;
+	if (of_property_read_u32(np, "clock-width", &width))
+		width = 32;
+	of_property_read_string(np, "clock-output-names", &clk_name);
+
+	denom = BIT(width);
+	flags |= XGENE_CLK_PMD_SCALE_INVERTED;
+
+	clk = xgene_register_clk_pmd(NULL, clk_name,
+				     of_clk_get_parent_name(np, 0), 0,
+				     csr_reg, shift, width, denom,
+				     flags, &clk_lock);
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+		clk_register_clkdev(clk, clk_name, NULL);
+		pr_debug("Add %s clock\n", clk_name);
+	} else {
+		if (csr_reg)
+			iounmap(csr_reg);
+	}
+}
+
 /* IP Clock */
 struct xgene_dev_parameters {
 	void __iomem *csr_reg;		/* CSR for IP clock */
@@ -543,6 +765,7 @@ err:
 
 CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
+CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);
 CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
 	       xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
-- 
1.9.1

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

* [PATCH 2/3] clk: xgene: Add PMD clock
@ 2016-08-23 15:52   ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	lho-qTEPVZfXA3Y, Duc Dang, Hoan Tran

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Signed-off-by: Hoan Tran <hotran-qTEPVZfXA3Y@public.gmane.org>
---
 drivers/clk/clk-xgene.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)

diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 3433132..66ce200 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -217,6 +217,228 @@ static void xgene_pcppllclk_init(struct device_node *np)
 	xgene_pllclk_init(np, PLL_TYPE_PCP);
 }
 
+/**
+ * struct xgene_clk_pmd - PMD clock
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	register containing the fractional scale multiplier (scaler)
+ * @shift:	shift to the unit bit field
+ * @denom:	1/denominator unit
+ * @lock:	register lock
+ * Flags:
+ * XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
+ *	from the register plus one. For example,
+ *		0 for (0 + 1) / denom,
+ *		1 for (1 + 1) / denom and etc.
+ *	If this flag is set, it is
+ *		0 for (denom - 0) / denom,
+ *		1 for (denom - 1) / denom and etc.
+ *
+ */
+struct xgene_clk_pmd {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		shift;
+	u32		mask;
+	u64		denom;
+	u32		flags;
+	spinlock_t	*lock;
+};
+
+#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)
+
+#define XGENE_CLK_PMD_SCALE_INVERTED	BIT(0)
+
+static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 ret, scale;
+	u32 val;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	ret = (u64)parent_rate;
+
+	scale = (val & fd->mask) >> fd->shift;
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale++;
+
+	/* freq = parent_rate * scaler / denom */
+	do_div(ret, fd->denom);
+	ret *= scale;
+	if (ret == 0)
+		ret = (u64)parent_rate;
+
+	return ret;
+}
+
+static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	u64 ret, scale;
+
+	if (!rate || rate >= *parent_rate)
+		return *parent_rate;
+
+	/* freq = parent_rate * scaler / denom */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, *parent_rate);
+
+	ret = (u64)*parent_rate * scale;
+	do_div(ret, fd->denom);
+
+	return ret;
+}
+
+static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 scale, ret;
+	u32 val;
+
+	/*
+	 * Compute the scaler:
+	 *
+	 * freq = parent_rate * scaler / denom, or
+	 * scaler = freq * denom / parent_rate
+	 */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);
+
+	/* Check if inverted */
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale--;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+	val &= ~fd->mask;
+	val |= (scale << fd->shift);
+	clk_writel(val, fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	return 0;
+}
+
+static const struct clk_ops xgene_clk_pmd_ops = {
+	.recalc_rate = xgene_clk_pmd_recalc_rate,
+	.round_rate = xgene_clk_pmd_round_rate,
+	.set_rate = xgene_clk_pmd_set_rate,
+};
+
+static struct clk *
+xgene_register_clk_pmd(struct device *dev,
+		       const char *name, const char *parent_name,
+		       unsigned long flags, void __iomem *reg, u8 shift,
+		       u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
+{
+	struct xgene_clk_pmd *fd;
+	struct clk_init_data init;
+	struct clk *clk;
+
+	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+	if (!fd)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &xgene_clk_pmd_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	fd->reg = reg;
+	fd->shift = shift;
+	fd->mask = (BIT(width) - 1) << shift;
+	fd->denom = denom;
+	fd->flags = clk_flags;
+	fd->lock = lock;
+	fd->hw.init = &init;
+
+	clk = clk_register(dev, &fd->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: could not register clk %s\n", __func__, name);
+		kfree(fd);
+		return NULL;
+	}
+
+	return clk;
+}
+
+static void xgene_pmdclk_init(struct device_node *np)
+{
+	const char *clk_name = np->full_name;
+	void __iomem *csr_reg;
+	struct resource res;
+	struct clk *clk;
+	u32 shift, width;
+	u64 denom;
+	u32 flags = 0;
+	int rc;
+
+	/* Check if the entry is disabled */
+	if (!of_device_is_available(np))
+		return;
+
+	/* Parse the DTS register for resource */
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc != 0) {
+		pr_err("no DTS register for %s\n", np->full_name);
+		return;
+	}
+	csr_reg = of_iomap(np, 0);
+	if (!csr_reg) {
+		pr_err("Unable to map resource for %s\n", np->full_name);
+		return;
+	}
+	if (of_property_read_u32(np, "clock-shift", &shift))
+		shift = 0;
+	if (of_property_read_u32(np, "clock-width", &width))
+		width = 32;
+	of_property_read_string(np, "clock-output-names", &clk_name);
+
+	denom = BIT(width);
+	flags |= XGENE_CLK_PMD_SCALE_INVERTED;
+
+	clk = xgene_register_clk_pmd(NULL, clk_name,
+				     of_clk_get_parent_name(np, 0), 0,
+				     csr_reg, shift, width, denom,
+				     flags, &clk_lock);
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+		clk_register_clkdev(clk, clk_name, NULL);
+		pr_debug("Add %s clock\n", clk_name);
+	} else {
+		if (csr_reg)
+			iounmap(csr_reg);
+	}
+}
+
 /* IP Clock */
 struct xgene_dev_parameters {
 	void __iomem *csr_reg;		/* CSR for IP clock */
@@ -543,6 +765,7 @@ err:
 
 CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
+CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);
 CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
 	       xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/3] clk: xgene: Add PMD clock
@ 2016-08-23 15:52   ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add X-Gene PMD clock support.

PMD clock is implemented for a single register field.
  Output rate = parent_rate * (denominator - scale) / denominator
with
  - denominator = bitmask of register field + 1
  - scale = value of register field

For example, for bitmask is 0x7, denominator will be 8 and scale
will be computed and programmed accordingly.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 drivers/clk/clk-xgene.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)

diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 3433132..66ce200 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -217,6 +217,228 @@ static void xgene_pcppllclk_init(struct device_node *np)
 	xgene_pllclk_init(np, PLL_TYPE_PCP);
 }
 
+/**
+ * struct xgene_clk_pmd - PMD clock
+ *
+ * @hw:		handle between common and hardware-specific interfaces
+ * @reg:	register containing the fractional scale multiplier (scaler)
+ * @shift:	shift to the unit bit field
+ * @denom:	1/denominator unit
+ * @lock:	register lock
+ * Flags:
+ * XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
+ *	from the register plus one. For example,
+ *		0 for (0 + 1) / denom,
+ *		1 for (1 + 1) / denom and etc.
+ *	If this flag is set, it is
+ *		0 for (denom - 0) / denom,
+ *		1 for (denom - 1) / denom and etc.
+ *
+ */
+struct xgene_clk_pmd {
+	struct clk_hw	hw;
+	void __iomem	*reg;
+	u8		shift;
+	u32		mask;
+	u64		denom;
+	u32		flags;
+	spinlock_t	*lock;
+};
+
+#define to_xgene_clk_pmd(_hw) container_of(_hw, struct xgene_clk_pmd, hw)
+
+#define XGENE_CLK_PMD_SCALE_INVERTED	BIT(0)
+
+static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 ret, scale;
+	u32 val;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	ret = (u64)parent_rate;
+
+	scale = (val & fd->mask) >> fd->shift;
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale++;
+
+	/* freq = parent_rate * scaler / denom */
+	do_div(ret, fd->denom);
+	ret *= scale;
+	if (ret == 0)
+		ret = (u64)parent_rate;
+
+	return ret;
+}
+
+static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	u64 ret, scale;
+
+	if (!rate || rate >= *parent_rate)
+		return *parent_rate;
+
+	/* freq = parent_rate * scaler / denom */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, *parent_rate);
+
+	ret = (u64)*parent_rate * scale;
+	do_div(ret, fd->denom);
+
+	return ret;
+}
+
+static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long parent_rate)
+{
+	struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw);
+	unsigned long flags = 0;
+	u64 scale, ret;
+	u32 val;
+
+	/*
+	 * Compute the scaler:
+	 *
+	 * freq = parent_rate * scaler / denom, or
+	 * scaler = freq * denom / parent_rate
+	 */
+	ret = rate * fd->denom;
+	scale = DIV_ROUND_UP_ULL(ret, (u64)parent_rate);
+
+	/* Check if inverted */
+	if (fd->flags & XGENE_CLK_PMD_SCALE_INVERTED)
+		scale = fd->denom - scale;
+	else
+		scale--;
+
+	if (fd->lock)
+		spin_lock_irqsave(fd->lock, flags);
+	else
+		__acquire(fd->lock);
+
+	val = clk_readl(fd->reg);
+	val &= ~fd->mask;
+	val |= (scale << fd->shift);
+	clk_writel(val, fd->reg);
+
+	if (fd->lock)
+		spin_unlock_irqrestore(fd->lock, flags);
+	else
+		__release(fd->lock);
+
+	return 0;
+}
+
+static const struct clk_ops xgene_clk_pmd_ops = {
+	.recalc_rate = xgene_clk_pmd_recalc_rate,
+	.round_rate = xgene_clk_pmd_round_rate,
+	.set_rate = xgene_clk_pmd_set_rate,
+};
+
+static struct clk *
+xgene_register_clk_pmd(struct device *dev,
+		       const char *name, const char *parent_name,
+		       unsigned long flags, void __iomem *reg, u8 shift,
+		       u8 width, u64 denom, u32 clk_flags, spinlock_t *lock)
+{
+	struct xgene_clk_pmd *fd;
+	struct clk_init_data init;
+	struct clk *clk;
+
+	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+	if (!fd)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &xgene_clk_pmd_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	fd->reg = reg;
+	fd->shift = shift;
+	fd->mask = (BIT(width) - 1) << shift;
+	fd->denom = denom;
+	fd->flags = clk_flags;
+	fd->lock = lock;
+	fd->hw.init = &init;
+
+	clk = clk_register(dev, &fd->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: could not register clk %s\n", __func__, name);
+		kfree(fd);
+		return NULL;
+	}
+
+	return clk;
+}
+
+static void xgene_pmdclk_init(struct device_node *np)
+{
+	const char *clk_name = np->full_name;
+	void __iomem *csr_reg;
+	struct resource res;
+	struct clk *clk;
+	u32 shift, width;
+	u64 denom;
+	u32 flags = 0;
+	int rc;
+
+	/* Check if the entry is disabled */
+	if (!of_device_is_available(np))
+		return;
+
+	/* Parse the DTS register for resource */
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc != 0) {
+		pr_err("no DTS register for %s\n", np->full_name);
+		return;
+	}
+	csr_reg = of_iomap(np, 0);
+	if (!csr_reg) {
+		pr_err("Unable to map resource for %s\n", np->full_name);
+		return;
+	}
+	if (of_property_read_u32(np, "clock-shift", &shift))
+		shift = 0;
+	if (of_property_read_u32(np, "clock-width", &width))
+		width = 32;
+	of_property_read_string(np, "clock-output-names", &clk_name);
+
+	denom = BIT(width);
+	flags |= XGENE_CLK_PMD_SCALE_INVERTED;
+
+	clk = xgene_register_clk_pmd(NULL, clk_name,
+				     of_clk_get_parent_name(np, 0), 0,
+				     csr_reg, shift, width, denom,
+				     flags, &clk_lock);
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+		clk_register_clkdev(clk, clk_name, NULL);
+		pr_debug("Add %s clock\n", clk_name);
+	} else {
+		if (csr_reg)
+			iounmap(csr_reg);
+	}
+}
+
 /* IP Clock */
 struct xgene_dev_parameters {
 	void __iomem *csr_reg;		/* CSR for IP clock */
@@ -543,6 +765,7 @@ err:
 
 CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
+CLK_OF_DECLARE(xgene_pmd_clock, "apm,xgene-pmd-clock", xgene_pmdclk_init);
 CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
 	       xgene_socpllclk_init);
 CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
-- 
1.9.1

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

* [PATCH 3/3] arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks
  2016-08-23 15:52 ` Hoan Tran
@ 2016-08-23 15:52   ` Hoan Tran
  -1 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: Michael Turquette, Rob Herring, Stephen Boyd, Mark Rutland
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel, lho,
	Duc Dang, Hoan Tran

Add DT nodes to enable APM X-Gene 2 CPU clocks.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 64 ++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index 1425ed4..e656e16 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -26,6 +26,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_0>;
+			#clock-cells = <1>;
+			clocks = <&pmd0clk 0>;
 		};
 		cpu@001 {
 			device_type = "cpu";
@@ -34,6 +36,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_0>;
+			#clock-cells = <1>;
+			clocks = <&pmd0clk 0>;
 		};
 		cpu@100 {
 			device_type = "cpu";
@@ -42,6 +46,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_1>;
+			#clock-cells = <1>;
+			clocks = <&pmd1clk 0>;
 		};
 		cpu@101 {
 			device_type = "cpu";
@@ -50,6 +56,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_1>;
+			#clock-cells = <1>;
+			clocks = <&pmd1clk 0>;
 		};
 		cpu@200 {
 			device_type = "cpu";
@@ -58,6 +66,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_2>;
+			#clock-cells = <1>;
+			clocks = <&pmd2clk 0>;
 		};
 		cpu@201 {
 			device_type = "cpu";
@@ -66,6 +76,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_2>;
+			#clock-cells = <1>;
+			clocks = <&pmd2clk 0>;
 		};
 		cpu@300 {
 			device_type = "cpu";
@@ -74,6 +86,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_3>;
+			#clock-cells = <1>;
+			clocks = <&pmd3clk 0>;
 		};
 		cpu@301 {
 			device_type = "cpu";
@@ -82,6 +96,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_3>;
+			#clock-cells = <1>;
+			clocks = <&pmd3clk 0>;
 		};
 		xgene_L2_0: l2-cache-0 {
 			compatible = "cache";
@@ -223,6 +239,54 @@
 				clock-output-names = "refclk";
 			};
 
+			pmdpll: pmdpll@170000f0 {
+				compatible = "apm,xgene-pcppll-v2-clock";
+				#clock-cells = <1>;
+				clocks = <&refclk 0>;
+				reg = <0x0 0x170000f0 0x0 0x10>;
+				clock-output-names = "pmdpll";
+			};
+
+			pmd0clk: pmd0clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200200 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd0clk";
+			};
+
+			pmd1clk: pmd1clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200210 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd1clk";
+			};
+
+			pmd2clk: pmd2clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200220 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd2clk";
+			};
+
+			pmd3clk: pmd3clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200230 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd3clk";
+			};
+
 			socpll: socpll@17000120 {
 				compatible = "apm,xgene-socpll-v2-clock";
 				#clock-cells = <1>;
-- 
1.9.1

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

* [PATCH 3/3] arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks
@ 2016-08-23 15:52   ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-23 15:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add DT nodes to enable APM X-Gene 2 CPU clocks.

Signed-off-by: Hoan Tran <hotran@apm.com>
---
 arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 64 ++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index 1425ed4..e656e16 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -26,6 +26,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_0>;
+			#clock-cells = <1>;
+			clocks = <&pmd0clk 0>;
 		};
 		cpu at 001 {
 			device_type = "cpu";
@@ -34,6 +36,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_0>;
+			#clock-cells = <1>;
+			clocks = <&pmd0clk 0>;
 		};
 		cpu at 100 {
 			device_type = "cpu";
@@ -42,6 +46,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_1>;
+			#clock-cells = <1>;
+			clocks = <&pmd1clk 0>;
 		};
 		cpu at 101 {
 			device_type = "cpu";
@@ -50,6 +56,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_1>;
+			#clock-cells = <1>;
+			clocks = <&pmd1clk 0>;
 		};
 		cpu at 200 {
 			device_type = "cpu";
@@ -58,6 +66,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_2>;
+			#clock-cells = <1>;
+			clocks = <&pmd2clk 0>;
 		};
 		cpu at 201 {
 			device_type = "cpu";
@@ -66,6 +76,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_2>;
+			#clock-cells = <1>;
+			clocks = <&pmd2clk 0>;
 		};
 		cpu at 300 {
 			device_type = "cpu";
@@ -74,6 +86,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_3>;
+			#clock-cells = <1>;
+			clocks = <&pmd3clk 0>;
 		};
 		cpu at 301 {
 			device_type = "cpu";
@@ -82,6 +96,8 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x1 0x0000fff8>;
 			next-level-cache = <&xgene_L2_3>;
+			#clock-cells = <1>;
+			clocks = <&pmd3clk 0>;
 		};
 		xgene_L2_0: l2-cache-0 {
 			compatible = "cache";
@@ -223,6 +239,54 @@
 				clock-output-names = "refclk";
 			};
 
+			pmdpll: pmdpll at 170000f0 {
+				compatible = "apm,xgene-pcppll-v2-clock";
+				#clock-cells = <1>;
+				clocks = <&refclk 0>;
+				reg = <0x0 0x170000f0 0x0 0x10>;
+				clock-output-names = "pmdpll";
+			};
+
+			pmd0clk: pmd0clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200200 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd0clk";
+			};
+
+			pmd1clk: pmd1clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200210 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd1clk";
+			};
+
+			pmd2clk: pmd2clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200220 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd2clk";
+			};
+
+			pmd3clk: pmd3clk {
+				compatible = "apm,xgene-pmd-clock";
+				#clock-cells = <1>;
+				clocks = <&pmdpll 0>;
+				reg = <0x0 0x7E200230 0x0 0x10>;
+				clock-shift = <8>;
+				clock-width = <3>;
+				clock-output-names = "pmd3clk";
+			};
+
 			socpll: socpll at 17000120 {
 				compatible = "apm,xgene-socpll-v2-clock";
 				#clock-cells = <1>;
-- 
1.9.1

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

* Re: [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
@ 2016-08-29 15:42     ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2016-08-29 15:42 UTC (permalink / raw)
  To: Hoan Tran
  Cc: Michael Turquette, Stephen Boyd, Mark Rutland, linux-clk,
	devicetree, linux-kernel, linux-arm-kernel, lho, Duc Dang

On Tue, Aug 23, 2016 at 08:52:39AM -0700, Hoan Tran wrote:
> Add APM X-Gene clock binding documentation for PMD clock.
> 
> Signed-off-by: Hoan Tran <hotran@apm.com>
> ---
>  Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
> index 82f9638..c381733 100644
> --- a/Documentation/devicetree/bindings/clock/xgene.txt
> +++ b/Documentation/devicetree/bindings/clock/xgene.txt
> @@ -8,6 +8,7 @@ Required properties:
>  - compatible : shall be one of the following:
>  	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
>  	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
> +	"apm,xgene-pmd-clock" - for a X-Gene PMD clock
>  	"apm,xgene-device-clock" - for a X-Gene device clock
>  	"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
>  	"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
> @@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
>  Optional properties for PLL clocks:
>  - clock-names : shall be the name of the PLL. If missing, use the device name.
>  
> +Required properties for PMD clocks:
> +- reg : shall be the physical register address for the pmd clock.
> +- clocks : shall be the input parent clock phandle for the clock.
> +- #clock-cells : shall be set to 1.
> +- clock-output-names : shall be the name of the clock referenced by derive
> +  clock.
> +- clock-shift: Bit shift of the clock register. Default is 0.
> +- clock-width: Width of the clock register. Default is 32.
> +Optional properties for PLL clocks:
> +- clock-names : shall be the name of the clock. If missing, use the device name.
> +
>  Required properties for device clocks:
>  - reg : shall be a list of address and length pairs describing the CSR
>           reset and/or the divider. Either may be omitted, but at least
> @@ -59,6 +71,16 @@ For example:
>  		type = <0>;
>  	};
>  
> +	pmd0clk: pmd0clk {
> +		compatible = "apm,xgene-pmd-clock";
> +		#clock-cells = <1>;
> +		clocks = <&pmdpll 0>;
> +		reg = <0x0 0x7E200200 0x0 0x10>;
> +		clock-shift = <8>;
> +		clock-width = <3>;

These should be implied by the compatible string. It's not a big deal 
for just adding this clock, but if you have lots more clocks to add then 
it is a problem. We only want leaf clocks (the ones going to devices) in 
DT unless there is only a few clocks.

Rob

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

* Re: [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
@ 2016-08-29 15:42     ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2016-08-29 15:42 UTC (permalink / raw)
  To: Hoan Tran
  Cc: Michael Turquette, Stephen Boyd, Mark Rutland,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	lho-qTEPVZfXA3Y, Duc Dang

On Tue, Aug 23, 2016 at 08:52:39AM -0700, Hoan Tran wrote:
> Add APM X-Gene clock binding documentation for PMD clock.
> 
> Signed-off-by: Hoan Tran <hotran-qTEPVZfXA3Y@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
> index 82f9638..c381733 100644
> --- a/Documentation/devicetree/bindings/clock/xgene.txt
> +++ b/Documentation/devicetree/bindings/clock/xgene.txt
> @@ -8,6 +8,7 @@ Required properties:
>  - compatible : shall be one of the following:
>  	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
>  	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
> +	"apm,xgene-pmd-clock" - for a X-Gene PMD clock
>  	"apm,xgene-device-clock" - for a X-Gene device clock
>  	"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
>  	"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
> @@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
>  Optional properties for PLL clocks:
>  - clock-names : shall be the name of the PLL. If missing, use the device name.
>  
> +Required properties for PMD clocks:
> +- reg : shall be the physical register address for the pmd clock.
> +- clocks : shall be the input parent clock phandle for the clock.
> +- #clock-cells : shall be set to 1.
> +- clock-output-names : shall be the name of the clock referenced by derive
> +  clock.
> +- clock-shift: Bit shift of the clock register. Default is 0.
> +- clock-width: Width of the clock register. Default is 32.
> +Optional properties for PLL clocks:
> +- clock-names : shall be the name of the clock. If missing, use the device name.
> +
>  Required properties for device clocks:
>  - reg : shall be a list of address and length pairs describing the CSR
>           reset and/or the divider. Either may be omitted, but at least
> @@ -59,6 +71,16 @@ For example:
>  		type = <0>;
>  	};
>  
> +	pmd0clk: pmd0clk {
> +		compatible = "apm,xgene-pmd-clock";
> +		#clock-cells = <1>;
> +		clocks = <&pmdpll 0>;
> +		reg = <0x0 0x7E200200 0x0 0x10>;
> +		clock-shift = <8>;
> +		clock-width = <3>;

These should be implied by the compatible string. It's not a big deal 
for just adding this clock, but if you have lots more clocks to add then 
it is a problem. We only want leaf clocks (the ones going to devices) in 
DT unless there is only a few clocks.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
@ 2016-08-29 15:42     ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2016-08-29 15:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 23, 2016 at 08:52:39AM -0700, Hoan Tran wrote:
> Add APM X-Gene clock binding documentation for PMD clock.
> 
> Signed-off-by: Hoan Tran <hotran@apm.com>
> ---
>  Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
> index 82f9638..c381733 100644
> --- a/Documentation/devicetree/bindings/clock/xgene.txt
> +++ b/Documentation/devicetree/bindings/clock/xgene.txt
> @@ -8,6 +8,7 @@ Required properties:
>  - compatible : shall be one of the following:
>  	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
>  	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
> +	"apm,xgene-pmd-clock" - for a X-Gene PMD clock
>  	"apm,xgene-device-clock" - for a X-Gene device clock
>  	"apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
>  	"apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
> @@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
>  Optional properties for PLL clocks:
>  - clock-names : shall be the name of the PLL. If missing, use the device name.
>  
> +Required properties for PMD clocks:
> +- reg : shall be the physical register address for the pmd clock.
> +- clocks : shall be the input parent clock phandle for the clock.
> +- #clock-cells : shall be set to 1.
> +- clock-output-names : shall be the name of the clock referenced by derive
> +  clock.
> +- clock-shift: Bit shift of the clock register. Default is 0.
> +- clock-width: Width of the clock register. Default is 32.
> +Optional properties for PLL clocks:
> +- clock-names : shall be the name of the clock. If missing, use the device name.
> +
>  Required properties for device clocks:
>  - reg : shall be a list of address and length pairs describing the CSR
>           reset and/or the divider. Either may be omitted, but at least
> @@ -59,6 +71,16 @@ For example:
>  		type = <0>;
>  	};
>  
> +	pmd0clk: pmd0clk {
> +		compatible = "apm,xgene-pmd-clock";
> +		#clock-cells = <1>;
> +		clocks = <&pmdpll 0>;
> +		reg = <0x0 0x7E200200 0x0 0x10>;
> +		clock-shift = <8>;
> +		clock-width = <3>;

These should be implied by the compatible string. It's not a big deal 
for just adding this clock, but if you have lots more clocks to add then 
it is a problem. We only want leaf clocks (the ones going to devices) in 
DT unless there is only a few clocks.

Rob

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

* Re: [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
  2016-08-29 15:42     ` Rob Herring
@ 2016-08-29 16:05       ` Hoan Tran
  -1 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-29 16:05 UTC (permalink / raw)
  To: Rob Herring
  Cc: Michael Turquette, Stephen Boyd, Mark Rutland, linux-clk,
	Devicetree List, lkml, linux-arm-kernel, Loc Ho, Duc Dang

Hi Rob,



On Mon, Aug 29, 2016 at 8:42 AM, Rob Herring <robh@kernel.org> wrote:
> On Tue, Aug 23, 2016 at 08:52:39AM -0700, Hoan Tran wrote:
>> Add APM X-Gene clock binding documentation for PMD clock.
>>
>> Signed-off-by: Hoan Tran <hotran@apm.com>
>> ---
>>  Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
>> index 82f9638..c381733 100644
>> --- a/Documentation/devicetree/bindings/clock/xgene.txt
>> +++ b/Documentation/devicetree/bindings/clock/xgene.txt
>> @@ -8,6 +8,7 @@ Required properties:
>>  - compatible : shall be one of the following:
>>       "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
>>       "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
>> +     "apm,xgene-pmd-clock" - for a X-Gene PMD clock
>>       "apm,xgene-device-clock" - for a X-Gene device clock
>>       "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
>>       "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
>> @@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
>>  Optional properties for PLL clocks:
>>  - clock-names : shall be the name of the PLL. If missing, use the device name.
>>
>> +Required properties for PMD clocks:
>> +- reg : shall be the physical register address for the pmd clock.
>> +- clocks : shall be the input parent clock phandle for the clock.
>> +- #clock-cells : shall be set to 1.
>> +- clock-output-names : shall be the name of the clock referenced by derive
>> +  clock.
>> +- clock-shift: Bit shift of the clock register. Default is 0.
>> +- clock-width: Width of the clock register. Default is 32.
>> +Optional properties for PLL clocks:
>> +- clock-names : shall be the name of the clock. If missing, use the device name.
>> +
>>  Required properties for device clocks:
>>  - reg : shall be a list of address and length pairs describing the CSR
>>           reset and/or the divider. Either may be omitted, but at least
>> @@ -59,6 +71,16 @@ For example:
>>               type = <0>;
>>       };
>>
>> +     pmd0clk: pmd0clk {
>> +             compatible = "apm,xgene-pmd-clock";
>> +             #clock-cells = <1>;
>> +             clocks = <&pmdpll 0>;
>> +             reg = <0x0 0x7E200200 0x0 0x10>;
>> +             clock-shift = <8>;
>> +             clock-width = <3>;
>
> These should be implied by the compatible string. It's not a big deal
> for just adding this clock, but if you have lots more clocks to add then
> it is a problem. We only want leaf clocks (the ones going to devices) in
> DT unless there is only a few clocks.
>

This clock node is the clock of CPU.
A PMD has 2 CPUs, and they are using the same PMD clock.

Thanks
Hoan

> Rob

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

* [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding
@ 2016-08-29 16:05       ` Hoan Tran
  0 siblings, 0 replies; 15+ messages in thread
From: Hoan Tran @ 2016-08-29 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rob,



On Mon, Aug 29, 2016 at 8:42 AM, Rob Herring <robh@kernel.org> wrote:
> On Tue, Aug 23, 2016 at 08:52:39AM -0700, Hoan Tran wrote:
>> Add APM X-Gene clock binding documentation for PMD clock.
>>
>> Signed-off-by: Hoan Tran <hotran@apm.com>
>> ---
>>  Documentation/devicetree/bindings/clock/xgene.txt | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt
>> index 82f9638..c381733 100644
>> --- a/Documentation/devicetree/bindings/clock/xgene.txt
>> +++ b/Documentation/devicetree/bindings/clock/xgene.txt
>> @@ -8,6 +8,7 @@ Required properties:
>>  - compatible : shall be one of the following:
>>       "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
>>       "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
>> +     "apm,xgene-pmd-clock" - for a X-Gene PMD clock
>>       "apm,xgene-device-clock" - for a X-Gene device clock
>>       "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock
>>       "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock
>> @@ -22,6 +23,17 @@ Required properties for SoC or PCP PLL clocks:
>>  Optional properties for PLL clocks:
>>  - clock-names : shall be the name of the PLL. If missing, use the device name.
>>
>> +Required properties for PMD clocks:
>> +- reg : shall be the physical register address for the pmd clock.
>> +- clocks : shall be the input parent clock phandle for the clock.
>> +- #clock-cells : shall be set to 1.
>> +- clock-output-names : shall be the name of the clock referenced by derive
>> +  clock.
>> +- clock-shift: Bit shift of the clock register. Default is 0.
>> +- clock-width: Width of the clock register. Default is 32.
>> +Optional properties for PLL clocks:
>> +- clock-names : shall be the name of the clock. If missing, use the device name.
>> +
>>  Required properties for device clocks:
>>  - reg : shall be a list of address and length pairs describing the CSR
>>           reset and/or the divider. Either may be omitted, but at least
>> @@ -59,6 +71,16 @@ For example:
>>               type = <0>;
>>       };
>>
>> +     pmd0clk: pmd0clk {
>> +             compatible = "apm,xgene-pmd-clock";
>> +             #clock-cells = <1>;
>> +             clocks = <&pmdpll 0>;
>> +             reg = <0x0 0x7E200200 0x0 0x10>;
>> +             clock-shift = <8>;
>> +             clock-width = <3>;
>
> These should be implied by the compatible string. It's not a big deal
> for just adding this clock, but if you have lots more clocks to add then
> it is a problem. We only want leaf clocks (the ones going to devices) in
> DT unless there is only a few clocks.
>

This clock node is the clock of CPU.
A PMD has 2 CPUs, and they are using the same PMD clock.

Thanks
Hoan

> Rob

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

end of thread, other threads:[~2016-08-29 16:05 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-23 15:52 [PATCH 0/3] clk: xgene: Add PMD clock support Hoan Tran
2016-08-23 15:52 ` Hoan Tran
2016-08-23 15:52 ` Hoan Tran
2016-08-23 15:52 ` [PATCH 1/3] Documentation: dtb: xgene: Add PMD clock binding Hoan Tran
2016-08-23 15:52   ` Hoan Tran
2016-08-29 15:42   ` Rob Herring
2016-08-29 15:42     ` Rob Herring
2016-08-29 15:42     ` Rob Herring
2016-08-29 16:05     ` Hoan Tran
2016-08-29 16:05       ` Hoan Tran
2016-08-23 15:52 ` [PATCH 2/3] clk: xgene: Add PMD clock Hoan Tran
2016-08-23 15:52   ` Hoan Tran
2016-08-23 15:52   ` Hoan Tran
2016-08-23 15:52 ` [PATCH 3/3] arm64: dts: xgene: Add DT node for APM X-Gene 2 CPU clocks Hoan Tran
2016-08-23 15:52   ` Hoan Tran

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.