All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants
@ 2016-08-22  9:19 Linus Walleij
  2016-08-22  9:19 ` [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks Linus Walleij
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Linus Walleij @ 2016-08-22  9:19 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, Linus Walleij, devicetree, Russell King

The Integrator/AP and Integrator/CP core modules have special
versions of the ICST525 interface hardcoding some bits. Create
special compatible strings to identify these variants, also
explain a bit what is going on.

Cc: devicetree@vger.kernel.org
Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Fix spelling mistakes.
- Try to be less specific and more general about the ARM system
  controllers so we do not need to edit the text again for the
  next variant we discover.
---
 .../devicetree/bindings/clock/arm-syscon-icst.txt  | 34 ++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
index 8b7177cecb36..27468119fd94 100644
--- a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
+++ b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
@@ -5,20 +5,50 @@ Technology (IDT). ARM integrated these oscillators deeply into their
 reference designs by adding special control registers that manage such
 oscillators to their system controllers.
 
-The ARM system controller contains logic to serialize and initialize
+The various ARM system controllers contain logic to serialize and initialize
 an ICST clock request after a write to the 32 bit register at an offset
 into the system controller. Furthermore, to even be able to alter one of
 these frequencies, the system controller must first be unlocked by
 writing a special token to another offset in the system controller.
 
+Some ARM hardware contain special versions of the serial interface that only
+connects the low 8 bits of the VDW (missing one bit), hardwires RDW to
+different values and sometimes also hardwire the output divider. They
+therefore have special compatible strings as per this table (the OD value is
+the value on the pins, not the resulting output divider):
+
+Hardware variant:        RDW     OD          VDW
+
+Integrator/AP            22      1           Bit 8 0, rest variable
+integratorap-cm
+
+Integrator/AP            46      3           Bit 8 0, rest variable
+integratorap-sys
+
+Integrator/AP            22 or   1           17 or (33 or 25 MHz)
+integratorap-pci         14      1           14
+
+Integrator/CP            22      variable    Bit 8 0, rest variable
+integratorcp-cm-core
+
+Integrator/CP            22      variable    Bit 8 0, rest variable
+integratorcp-cm-mem
+
 The ICST oscillator must be provided inside a system controller node.
 
 Required properties:
+- compatible: must be one of
+  "arm,syscon-icst525"
+  "arm,syscon-icst307"
+  "arm,syscon-icst525-integratorap-cm"
+  "arm,syscon-icst525-integratorap-sys"
+  "arm,syscon-icst525-integratorap-pci"
+  "arm,syscon-icst525-integratorcp-cm-core"
+  "arm,syscon-icst525-integratorcp-cm-mem"
 - lock-offset: the offset address into the system controller where the
   unlocking register is located
 - vco-offset: the offset address into the system controller where the
   ICST control register is located (even 32 bit address)
-- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307"
 - #clock-cells: must be <0>
 - clocks: parent clock, since the ICST needs a parent clock to derive its
   frequency from, this attribute is compulsory.
-- 
2.7.4


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

* [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks
  2016-08-22  9:19 [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Linus Walleij
@ 2016-08-22  9:19 ` Linus Walleij
  2016-08-25 20:07   ` Stephen Boyd
  2016-08-22  9:19 ` [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks Linus Walleij
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2016-08-22  9:19 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Linus Walleij, Russell King

The Integrator/AP and Integrator/CP have special derivatives
of the ICST525 control registers, where some bits have been
hardwired but others are possible to adjust, resulting in a
control register that makes it possible to set an even,
desired megahertz value.

The Integrator/AP and Integrator/CP have slightly different
layout so we support them using different compatible
strings.

After adding these clocks, the Integrator-specific cpufreq
driver can be switched over to use the generic operating
point device tree cpufreq driver.

Instead of simply writing a value to the oscillator control
register we switch to the more elaborate method of providing
a bitmask and use regmap_update_bits() to poke the right bits
for the desired frequency, this is needed since these control
registers sometimes control more than one clock.

Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Restore a pr_debug() from pr_info() that was used during
  development.
---
 drivers/clk/versatile/clk-icst.c | 174 +++++++++++++++++++++++++++++++++++----
 1 file changed, 160 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index 5e9b65278e4c..8f06473b72ff 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -27,6 +27,21 @@
 /* Magic unlocking token used on all Versatile boards */
 #define VERSATILE_LOCK_VAL	0xA05F
 
+#define VERSATILE_AUX_OSC_BITS 0x7FFFF
+#define INTEGRATOR_AP_CM_BITS 0xFF
+#define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
+#define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
+
+/**
+ * enum icst_control_type - the type of ICST control register
+ */
+enum icst_control_type {
+	ICST_VERSATILE, /* The standard type, all control bits available */
+	ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */
+	ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */
+	ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */
+};
+
 /**
  * struct clk_icst - ICST VCO clock wrapper
  * @hw: corresponding clock hardware entry
@@ -34,6 +49,7 @@
  * @lockreg: VCO lock register address
  * @params: parameters for this ICST instance
  * @rate: current rate
+ * @ctype: the type of control register for the ICST
  */
 struct clk_icst {
 	struct clk_hw hw;
@@ -42,6 +58,7 @@ struct clk_icst {
 	u32 lockreg_off;
 	struct icst_params *params;
 	unsigned long rate;
+	enum icst_control_type ctype;
 };
 
 #define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
@@ -59,6 +76,44 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
 	ret = regmap_read(icst->map, icst->vcoreg_off, &val);
 	if (ret)
 		return ret;
+
+	/*
+	 * The Integrator/AP core clock can only access the low eight
+	 * bits of the v PLL divider. Bit 8 is tied low and always zero,
+	 * r is hardwired to 22 and output divider s is hardwired to 1
+	 * (divide by 2) according to the document
+	 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
+	 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
+	 */
+	if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
+		vco->v = val & INTEGRATOR_AP_CM_BITS;
+		vco->r = 22;
+		vco->s = 1;
+		return 0;
+	}
+
+	/*
+	 * The Integrator/CP core clock can access the low eight bits
+	 * of the v PLL divider. Bit 8 is tied low and always zero,
+	 * r is hardwired to 22 and the output divider s is accessible
+	 * in bits 8 thru 10 according to the document
+	 * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
+	 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
+	 */
+	if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
+		vco->v = val & 0xFF;
+		vco->r = 22;
+		vco->s = (val >> 8) & 7;
+		return 0;
+	}
+
+	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
+		vco->v = (val >> 12) & 0xFF;
+		vco->r = 22;
+		vco->s = (val >> 20) & 7;
+		return 0;
+	}
+
 	vco->v = val & 0x1ff;
 	vco->r = (val >> 9) & 0x7f;
 	vco->s = (val >> 16) & 03;
@@ -72,22 +127,52 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
  */
 static int vco_set(struct clk_icst *icst, struct icst_vco vco)
 {
+	u32 mask;
 	u32 val;
 	int ret;
 
-	ret = regmap_read(icst->map, icst->vcoreg_off, &val);
-	if (ret)
-		return ret;
+	/* Mask the bits used by the VCO */
+	switch (icst->ctype) {
+	case ICST_INTEGRATOR_AP_CM:
+		mask = INTEGRATOR_AP_CM_BITS;
+		val = vco.v & 0xFF;
+		if (vco.v & 0x100)
+			pr_err("ICST error: tried to set bit 8 of VDW\n");
+		if (vco.s != 1)
+			pr_err("ICST error: tried to use VOD != 1\n");
+		if (vco.r != 22)
+			pr_err("ICST error: tried to use RDW != 22\n");
+		break;
+	case ICST_INTEGRATOR_CP_CM_CORE:
+		mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
+		val = (vco.v & 0xFF) | vco.s << 8;
+		if (vco.v & 0x100)
+			pr_err("ICST error: tried to set bit 8 of VDW\n");
+		if (vco.r != 22)
+			pr_err("ICST error: tried to use RDW != 22\n");
+		break;
+	case ICST_INTEGRATOR_CP_CM_MEM:
+		mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
+		val = ((vco.v & 0xFF) << 12) | (vco.s << 20);
+		if (vco.v & 0x100)
+			pr_err("ICST error: tried to set bit 8 of VDW\n");
+		if (vco.r != 22)
+			pr_err("ICST error: tried to use RDW != 22\n");
+		break;
+	default:
+		/* Regular auxilary oscillator */
+		mask = VERSATILE_AUX_OSC_BITS;
+		val = vco.v | (vco.r << 9) | (vco.s << 16);
+		break;
+	}
 
-	/* Mask the 18 bits used by the VCO */
-	val &= ~0x7ffff;
-	val |= vco.v | (vco.r << 9) | (vco.s << 16);
+	pr_debug("ICST: new val = 0x%08x\n", val);
 
 	/* This magic unlocks the VCO so it can be controlled */
 	ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
 	if (ret)
 		return ret;
-	ret = regmap_write(icst->map, icst->vcoreg_off, val);
+	ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val);
 	if (ret)
 		return ret;
 	/* This locks the VCO again */
@@ -121,6 +206,25 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_icst *icst = to_icst(hw);
 	struct icst_vco vco;
 
+	if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
+	    icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
+		if (rate <= 12000000)
+			return 12000000;
+		if (rate >= 160000000)
+			return 160000000;
+		/* Slam to closest megahertz */
+		return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
+	}
+
+	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
+		if (rate <= 6000000)
+			return 6000000;
+		if (rate >= 66000000)
+			return 66000000;
+		/* Slam to closest 0.5 megahertz */
+		return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
+	}
+
 	vco = icst_hz_to_vco(icst->params, rate);
 	return icst_hz(icst->params, vco);
 }
@@ -148,7 +252,8 @@ static struct clk *icst_clk_setup(struct device *dev,
 				  const struct clk_icst_desc *desc,
 				  const char *name,
 				  const char *parent_name,
-				  struct regmap *map)
+				  struct regmap *map,
+				  enum icst_control_type ctype)
 {
 	struct clk *clk;
 	struct clk_icst *icst;
@@ -178,6 +283,7 @@ static struct clk *icst_clk_setup(struct device *dev,
 	icst->params = pclone;
 	icst->vcoreg_off = desc->vco_offset;
 	icst->lockreg_off = desc->lock_offset;
+	icst->ctype = ctype;
 
 	clk = clk_register(dev, &icst->hw);
 	if (IS_ERR(clk)) {
@@ -206,7 +312,8 @@ struct clk *icst_clk_register(struct device *dev,
 		pr_err("could not initialize ICST regmap\n");
 		return ERR_CAST(map);
 	}
-	return icst_clk_setup(dev, desc, name, parent_name, map);
+	return icst_clk_setup(dev, desc, name, parent_name, map,
+			      ICST_VERSATILE);
 }
 EXPORT_SYMBOL_GPL(icst_clk_register);
 
@@ -239,6 +346,28 @@ static const struct icst_params icst307_params = {
 	.idx2s		= icst307_idx2s,
 };
 
+/**
+ * The core modules on the Integrator/AP and Integrator/CP have
+ * especially crippled ICST525 control.
+ */
+static const struct icst_params icst525_apcp_cm_params = {
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
+	/* Minimum 12 MHz, VDW = 4 */
+	.vd_min		= 12,
+	/*
+	 * Maximum 160 MHz, VDW = 152 for all core modules, but
+	 * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
+	 * go to 200 MHz (max VDW = 192).
+	 */
+	.vd_max		= 192,
+	/* r is hardcoded to 22 and this is the actual divisor, +2 */
+	.rd_min		= 24,
+	.rd_max		= 24,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
+};
+
 static void __init of_syscon_icst_setup(struct device_node *np)
 {
 	struct device_node *parent;
@@ -247,6 +376,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
 	const char *name = np->name;
 	const char *parent_name;
 	struct clk *regclk;
+	enum icst_control_type ctype;
 
 	/* We do not release this reference, we are using it perpetually */
 	parent = of_get_parent(np);
@@ -269,11 +399,22 @@ static void __init of_syscon_icst_setup(struct device_node *np)
 		return;
 	}
 
-	if (of_device_is_compatible(np, "arm,syscon-icst525"))
+	if (of_device_is_compatible(np, "arm,syscon-icst525")) {
 		icst_desc.params = &icst525_params;
-	else if (of_device_is_compatible(np, "arm,syscon-icst307"))
+		ctype = ICST_VERSATILE;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst307")) {
 		icst_desc.params = &icst307_params;
-	else {
+		ctype = ICST_VERSATILE;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
+		icst_desc.params = &icst525_apcp_cm_params;
+		ctype = ICST_INTEGRATOR_AP_CM;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
+		icst_desc.params = &icst525_apcp_cm_params;
+		ctype = ICST_INTEGRATOR_CP_CM_CORE;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) {
+		icst_desc.params = &icst525_apcp_cm_params;
+		ctype = ICST_INTEGRATOR_CP_CM_MEM;
+	} else {
 		pr_err("unknown ICST clock %s\n", name);
 		return;
 	}
@@ -281,7 +422,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
 	/* Parent clock name is not the same as node parent */
 	parent_name = of_clk_get_parent_name(np, 0);
 
-	regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map);
+	regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype);
 	if (IS_ERR(regclk)) {
 		pr_err("error setting up syscon ICST clock %s\n", name);
 		return;
@@ -294,5 +435,10 @@ CLK_OF_DECLARE(arm_syscon_icst525_clk,
 	       "arm,syscon-icst525", of_syscon_icst_setup);
 CLK_OF_DECLARE(arm_syscon_icst307_clk,
 	       "arm,syscon-icst307", of_syscon_icst_setup);
-
+CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
+	       "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
+	       "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
+	       "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);
 #endif
-- 
2.7.4

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

* [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks
  2016-08-22  9:19 [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Linus Walleij
  2016-08-22  9:19 ` [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks Linus Walleij
@ 2016-08-22  9:19 ` Linus Walleij
  2016-08-25 20:06   ` Stephen Boyd
       [not found] ` <1471857574-13125-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2016-08-25 20:06 ` Stephen Boyd
  3 siblings, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2016-08-22  9:19 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd; +Cc: linux-clk, Linus Walleij, Russell King

This adds support for the two ICST525-based clocks on the
Integrator/AP baseboard, as documented in the board manual
"Integrator/AP ASIC Development Motherboard", ARM DUI0098 B,
pages 3-15 thru 3-18.

Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Drop DTS patch hunk that need to go into a separate patch.
---
 drivers/clk/versatile/clk-icst.c | 137 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index 8f06473b72ff..5fd54a6a604e 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -29,15 +29,20 @@
 
 #define VERSATILE_AUX_OSC_BITS 0x7FFFF
 #define INTEGRATOR_AP_CM_BITS 0xFF
+#define INTEGRATOR_AP_SYS_BITS 0xFF
 #define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
 #define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
 
+#define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)
+
 /**
  * enum icst_control_type - the type of ICST control register
  */
 enum icst_control_type {
 	ICST_VERSATILE, /* The standard type, all control bits available */
 	ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */
+	ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */
+	ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */
 	ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */
 	ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */
 };
@@ -93,6 +98,38 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
 	}
 
 	/*
+	 * The Integrator/AP system clock on the base board can only
+	 * access the low eight bits of the v PLL divider. Bit 8 is tied low
+	 * and always zero, r is hardwired to 46, and the output divider is
+	 * hardwired to 3 (divide by 4) according to the document
+	 * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
+	 * page 3-16.
+	 */
+	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
+		vco->v = val & INTEGRATOR_AP_SYS_BITS;
+		vco->r = 46;
+		vco->s = 3;
+		return 0;
+	}
+
+	/*
+	 * The Integrator/AP PCI clock is using an odd pattern to create
+	 * the child clock, basically a single bit called DIVX/Y is used
+	 * to select between two different hardwired values: setting the
+	 * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
+	 * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
+	 * 33 or 25 MHz respectively.
+	 */
+	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+		bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);
+
+		vco->v = divxy ? 17 : 14;
+		vco->r = divxy ? 22 : 14;
+		vco->s = 1;
+		return 0;
+	}
+
+	/*
 	 * The Integrator/CP core clock can access the low eight bits
 	 * of the v PLL divider. Bit 8 is tied low and always zero,
 	 * r is hardwired to 22 and the output divider s is accessible
@@ -143,6 +180,17 @@ static int vco_set(struct clk_icst *icst, struct icst_vco vco)
 		if (vco.r != 22)
 			pr_err("ICST error: tried to use RDW != 22\n");
 		break;
+	case ICST_INTEGRATOR_AP_SYS:
+		mask = INTEGRATOR_AP_SYS_BITS;
+		val &= ~0xFF; /* Uses 8 bits */
+		val |= vco.v & 0xFF;
+		if (vco.v & 0x100)
+			pr_err("ICST error: tried to set bit 8 of VDW\n");
+		if (vco.s != 3)
+			pr_err("ICST error: tried to use VOD != 1\n");
+		if (vco.r != 46)
+			pr_err("ICST error: tried to use RDW != 22\n");
+		break;
 	case ICST_INTEGRATOR_CP_CM_CORE:
 		mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
 		val = (vco.v & 0xFF) | vco.s << 8;
@@ -225,6 +273,27 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
 		return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
 	}
 
+	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
+		/* Divides between 3 and 50 MHz in steps of 0.25 MHz */
+		if (rate <= 3000000)
+			return 3000000;
+		if (rate >= 50000000)
+			return 5000000;
+		/* Slam to closest 0.25 MHz */
+		return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
+	}
+
+	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+		/*
+		 * If we're below or less than halfway from 25 to 33 MHz
+		 * select 25 MHz
+		 */
+		if (rate <= 25000000 || rate < 29000000)
+			return 25000000;
+		/* Else just return the default frequency */
+		return 33000000;
+	}
+
 	vco = icst_hz_to_vco(icst->params, rate);
 	return icst_hz(icst->params, vco);
 }
@@ -235,6 +304,36 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_icst *icst = to_icst(hw);
 	struct icst_vco vco;
 
+	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+		/* This clock is especially primitive */
+		unsigned int val;
+		int ret;
+
+		if (rate == 25000000) {
+			val = 0;
+		} else if (rate == 33000000) {
+			val = INTEGRATOR_AP_PCI_25_33_MHZ;
+		} else {
+			pr_err("ICST: cannot set PCI frequency %lu\n",
+			       rate);
+			return -EINVAL;
+		}
+		ret = regmap_write(icst->map, icst->lockreg_off,
+				   VERSATILE_LOCK_VAL);
+		if (ret)
+			return ret;
+		ret = regmap_update_bits(icst->map, icst->vcoreg_off,
+					 INTEGRATOR_AP_PCI_25_33_MHZ,
+					 val);
+		if (ret)
+			return ret;
+		/* This locks the VCO again */
+		ret = regmap_write(icst->map, icst->lockreg_off, 0);
+		if (ret)
+			return ret;
+		return 0;
+	}
+
 	if (parent_rate)
 		icst->params->ref = parent_rate;
 	vco = icst_hz_to_vco(icst->params, rate);
@@ -368,6 +467,34 @@ static const struct icst_params icst525_apcp_cm_params = {
 	.idx2s		= icst525_idx2s,
 };
 
+static const struct icst_params icst525_ap_sys_params = {
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
+	/* Minimum 3 MHz, VDW = 4 */
+	.vd_min		= 3,
+	/* Maximum 50 MHz, VDW = 192 */
+	.vd_max		= 50,
+	/* r is hardcoded to 46 and this is the actual divisor, +2 */
+	.rd_min		= 48,
+	.rd_max		= 48,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
+};
+
+static const struct icst_params icst525_ap_pci_params = {
+	.vco_max	= ICST525_VCO_MAX_5V,
+	.vco_min	= ICST525_VCO_MIN,
+	/* Minimum 25 MHz */
+	.vd_min		= 25,
+	/* Maximum 33 MHz */
+	.vd_max		= 33,
+	/* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
+	.rd_min		= 16,
+	.rd_max		= 24,
+	.s2div		= icst525_s2div,
+	.idx2s		= icst525_idx2s,
+};
+
 static void __init of_syscon_icst_setup(struct device_node *np)
 {
 	struct device_node *parent;
@@ -408,6 +535,12 @@ static void __init of_syscon_icst_setup(struct device_node *np)
 	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
 		icst_desc.params = &icst525_apcp_cm_params;
 		ctype = ICST_INTEGRATOR_AP_CM;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) {
+		icst_desc.params = &icst525_ap_sys_params;
+		ctype = ICST_INTEGRATOR_AP_SYS;
+	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) {
+		icst_desc.params = &icst525_ap_pci_params;
+		ctype = ICST_INTEGRATOR_AP_PCI;
 	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
 		icst_desc.params = &icst525_apcp_cm_params;
 		ctype = ICST_INTEGRATOR_CP_CM_CORE;
@@ -437,6 +570,10 @@ CLK_OF_DECLARE(arm_syscon_icst307_clk,
 	       "arm,syscon-icst307", of_syscon_icst_setup);
 CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
 	       "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk,
+	       "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk,
+	       "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
 CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
 	       "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
 CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
-- 
2.7.4

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

* Re: [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants
  2016-08-22  9:19 [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Linus Walleij
@ 2016-08-23 18:09     ` Rob Herring
  2016-08-22  9:19 ` [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks Linus Walleij
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2016-08-23 18:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Michael Turquette, Stephen Boyd,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King

On Mon, Aug 22, 2016 at 11:19:32AM +0200, Linus Walleij wrote:
> The Integrator/AP and Integrator/CP core modules have special
> versions of the ICST525 interface hardcoding some bits. Create
> special compatible strings to identify these variants, also
> explain a bit what is going on.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Russell King <linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> ChangeLog v1->v2:
> - Fix spelling mistakes.
> - Try to be less specific and more general about the ARM system
>   controllers so we do not need to edit the text again for the
>   next variant we discover.
> ---
>  .../devicetree/bindings/clock/arm-syscon-icst.txt  | 34 ++++++++++++++++++++--
>  1 file changed, 32 insertions(+), 2 deletions(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
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] 9+ messages in thread

* Re: [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants
@ 2016-08-23 18:09     ` Rob Herring
  0 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2016-08-23 18:09 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Michael Turquette, Stephen Boyd, linux-clk, devicetree, Russell King

On Mon, Aug 22, 2016 at 11:19:32AM +0200, Linus Walleij wrote:
> The Integrator/AP and Integrator/CP core modules have special
> versions of the ICST525 interface hardcoding some bits. Create
> special compatible strings to identify these variants, also
> explain a bit what is going on.
> 
> Cc: devicetree@vger.kernel.org
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Fix spelling mistakes.
> - Try to be less specific and more general about the ARM system
>   controllers so we do not need to edit the text again for the
>   next variant we discover.
> ---
>  .../devicetree/bindings/clock/arm-syscon-icst.txt  | 34 ++++++++++++++++++++--
>  1 file changed, 32 insertions(+), 2 deletions(-)

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks
  2016-08-22  9:19 ` [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks Linus Walleij
@ 2016-08-25 20:06   ` Stephen Boyd
  2016-08-27 12:02     ` Linus Walleij
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Boyd @ 2016-08-25 20:06 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Michael Turquette, linux-clk, Russell King

On 08/22, Linus Walleij wrote:
> @@ -143,6 +180,17 @@ static int vco_set(struct clk_icst *icst, struct icst_vco vco)
>  		if (vco.r != 22)
>  			pr_err("ICST error: tried to use RDW != 22\n");
>  		break;
> +	case ICST_INTEGRATOR_AP_SYS:
> +		mask = INTEGRATOR_AP_SYS_BITS;
> +		val &= ~0xFF; /* Uses 8 bits */

drivers/clk/versatile/clk-icst.c: In function ‘icst_set_rate’:
drivers/clk/versatile/clk-icst.c:185:7: warning: ‘val’ may be used uninitialized in this function [-Wuninitialized]

> +		val |= vco.v & 0xFF;
> +		if (vco.v & 0x100)
> +			pr_err("ICST error: tried to set bit 8 of VDW\n");
> +		if (vco.s != 3)
> +			pr_err("ICST error: tried to use VOD != 1\n");
> +		if (vco.r != 46)
> +			pr_err("ICST error: tried to use RDW != 22\n");
> +		break;
>  	case ICST_INTEGRATOR_CP_CM_CORE:
>  		mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
>  		val = (vco.v & 0xFF) | vco.s << 8;

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants
  2016-08-22  9:19 [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Linus Walleij
                   ` (2 preceding siblings ...)
       [not found] ` <1471857574-13125-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-08-25 20:06 ` Stephen Boyd
  3 siblings, 0 replies; 9+ messages in thread
From: Stephen Boyd @ 2016-08-25 20:06 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Michael Turquette, linux-clk, devicetree, Russell King

On 08/22, Linus Walleij wrote:
> The Integrator/AP and Integrator/CP core modules have special
> versions of the ICST525 interface hardcoding some bits. Create
> special compatible strings to identify these variants, also
> explain a bit what is going on.
> 
> Cc: devicetree@vger.kernel.org
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks
  2016-08-22  9:19 ` [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks Linus Walleij
@ 2016-08-25 20:07   ` Stephen Boyd
  0 siblings, 0 replies; 9+ messages in thread
From: Stephen Boyd @ 2016-08-25 20:07 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Michael Turquette, linux-clk, Russell King

On 08/22, Linus Walleij wrote:
> The Integrator/AP and Integrator/CP have special derivatives
> of the ICST525 control registers, where some bits have been
> hardwired but others are possible to adjust, resulting in a
> control register that makes it possible to set an even,
> desired megahertz value.
> 
> The Integrator/AP and Integrator/CP have slightly different
> layout so we support them using different compatible
> strings.
> 
> After adding these clocks, the Integrator-specific cpufreq
> driver can be switched over to use the generic operating
> point device tree cpufreq driver.
> 
> Instead of simply writing a value to the oscillator control
> register we switch to the more elaborate method of providing
> a bitmask and use regmap_update_bits() to poke the right bits
> for the desired frequency, this is needed since these control
> registers sometimes control more than one clock.
> 
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks
  2016-08-25 20:06   ` Stephen Boyd
@ 2016-08-27 12:02     ` Linus Walleij
  0 siblings, 0 replies; 9+ messages in thread
From: Linus Walleij @ 2016-08-27 12:02 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: Michael Turquette, linux-clk, Russell King

On Thu, Aug 25, 2016 at 10:06 PM, Stephen Boyd <sboyd@codeaurora.org> wrote=
:
> On 08/22, Linus Walleij wrote:
>> @@ -143,6 +180,17 @@ static int vco_set(struct clk_icst *icst, struct ic=
st_vco vco)
>>               if (vco.r !=3D 22)
>>                       pr_err("ICST error: tried to use RDW !=3D 22\n");
>>               break;
>> +     case ICST_INTEGRATOR_AP_SYS:
>> +             mask =3D INTEGRATOR_AP_SYS_BITS;
>> +             val &=3D ~0xFF; /* Uses 8 bits */
>
> drivers/clk/versatile/clk-icst.c: In function =E2=80=98icst_set_rate=E2=
=80=99:
> drivers/clk/versatile/clk-icst.c:185:7: warning: =E2=80=98val=E2=80=99 ma=
y be used uninitialized in this function [-Wuninitialized]

Sorry, a dangling oneliner. Resent only this patch as v3.

Yours,
Linus Walleij

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

end of thread, other threads:[~2016-08-27 12:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-22  9:19 [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Linus Walleij
2016-08-22  9:19 ` [PATCH 2/3 v2] clk: versatile/icst: add Integrator core module clocks Linus Walleij
2016-08-25 20:07   ` Stephen Boyd
2016-08-22  9:19 ` [PATCH 3/3 v2] clk: versatile/icst: support for AP baseboard clocks Linus Walleij
2016-08-25 20:06   ` Stephen Boyd
2016-08-27 12:02     ` Linus Walleij
     [not found] ` <1471857574-13125-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-08-23 18:09   ` [PATCH 1/3 v2] clk: versatile add DT bindings for the ICST CM variants Rob Herring
2016-08-23 18:09     ` Rob Herring
2016-08-25 20:06 ` Stephen Boyd

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.