linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] clk: vc5: Allow Versaclock driver to support multiple instances
@ 2020-04-14 19:36 Adam Ford
  2020-04-14 19:36 ` [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock Adam Ford
  2020-04-14 19:36 ` [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock Adam Ford
  0 siblings, 2 replies; 5+ messages in thread
From: Adam Ford @ 2020-04-14 19:36 UTC (permalink / raw)
  To: linux-clk
  Cc: aford, charles.stevens, Adam Ford, Michael Turquette,
	Stephen Boyd, Rob Herring, Marek Vasut, devicetree, linux-kernel

Currently, the Versaclock driver is only expecting one instance and
uses hard-coded names for the various clock names.  Unfortunately,
this is a problem when there is more than one instance of the driver,
because the subsequent instantiations of the driver use the identical
name.  Each clock after the fist fails to load, because the clock
subsystem cannot handle two clocks with identical name.

This patch removes the hard-coded name arrays and uses kasprintf to
assign clock names based on names of their respective node and parent
node which gives each clock a unique identifying name.

For a verasaclock node with a name like:
   versaclock5: versaclock_som@6a

The updated clock names would appear like:
    versaclock_som.mux
       versaclock_som.out0_sel_i2cb
       versaclock_som.pfd
          versaclock_som.pll
             versaclock_som.fod3
                versaclock_som.out4
             versaclock_som.fod2
                versaclock_som.out3
             versaclock_som.fod1
                versaclock_som.out2
             versaclock_som.fod0
                versaclock_som.out1

Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index fa96659f8023..6e4b09f1f074 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -161,30 +161,6 @@ struct vc5_driver_data {
 	struct vc5_hw_data	clk_out[VC5_MAX_CLK_OUT_NUM];
 };
 
-static const char * const vc5_mux_names[] = {
-	"mux"
-};
-
-static const char * const vc5_dbl_names[] = {
-	"dbl"
-};
-
-static const char * const vc5_pfd_names[] = {
-	"pfd"
-};
-
-static const char * const vc5_pll_names[] = {
-	"pll"
-};
-
-static const char * const vc5_fod_names[] = {
-	"fod0", "fod1", "fod2", "fod3",
-};
-
-static const char * const vc5_clk_out_names[] = {
-	"out0_sel_i2cb", "out1", "out2", "out3", "out4",
-};
-
 /*
  * VersaClock5 i2c regmap
  */
@@ -750,12 +726,13 @@ static int vc5_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
-	init.name = vc5_mux_names[0];
+	init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
 	init.ops = &vc5_mux_ops;
 	init.flags = 0;
 	init.parent_names = parent_names;
 	vc5->clk_mux.init = &init;
 	ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
+	kfree(init.name); /* clock framework made a copy of the name */
 	if (ret) {
 		dev_err(&client->dev, "unable to register %s\n", init.name);
 		goto err_clk;
@@ -764,13 +741,16 @@ static int vc5_probe(struct i2c_client *client,
 	if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
 		/* Register frequency doubler */
 		memset(&init, 0, sizeof(init));
-		init.name = vc5_dbl_names[0];
+		init.name = kasprintf(GFP_KERNEL, "%pOFn.dbl",
+				       client->dev.of_node);
 		init.ops = &vc5_dbl_ops;
 		init.flags = CLK_SET_RATE_PARENT;
-		init.parent_names = vc5_mux_names;
+		init.parent_names = parent_names;
+		parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
 		init.num_parents = 1;
 		vc5->clk_mul.init = &init;
 		ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
+		kfree(init.name); /* clock framework made a copy of the name */
 		if (ret) {
 			dev_err(&client->dev, "unable to register %s\n",
 				init.name);
@@ -780,16 +760,18 @@ static int vc5_probe(struct i2c_client *client,
 
 	/* Register PFD */
 	memset(&init, 0, sizeof(init));
-	init.name = vc5_pfd_names[0];
+	init.name = kasprintf(GFP_KERNEL, "%pOFn.pfd", client->dev.of_node);
 	init.ops = &vc5_pfd_ops;
 	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = parent_names;
 	if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
-		init.parent_names = vc5_dbl_names;
+		parent_names[0] = clk_hw_get_name(&vc5->clk_mul);
 	else
-		init.parent_names = vc5_mux_names;
+		parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
 	init.num_parents = 1;
 	vc5->clk_pfd.init = &init;
 	ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
+	kfree(init.name); /* clock framework made a copy of the name */
 	if (ret) {
 		dev_err(&client->dev, "unable to register %s\n", init.name);
 		goto err_clk;
@@ -797,15 +779,17 @@ static int vc5_probe(struct i2c_client *client,
 
 	/* Register PLL */
 	memset(&init, 0, sizeof(init));
-	init.name = vc5_pll_names[0];
+	init.name = kasprintf(GFP_KERNEL, "%pOFn.pll", client->dev.of_node);
 	init.ops = &vc5_pll_ops;
 	init.flags = CLK_SET_RATE_PARENT;
-	init.parent_names = vc5_pfd_names;
+	init.parent_names = parent_names;
+	parent_names[0] = clk_hw_get_name(&vc5->clk_pfd);
 	init.num_parents = 1;
 	vc5->clk_pll.num = 0;
 	vc5->clk_pll.vc5 = vc5;
 	vc5->clk_pll.hw.init = &init;
 	ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
+	kfree(init.name); /* clock framework made a copy of the name */
 	if (ret) {
 		dev_err(&client->dev, "unable to register %s\n", init.name);
 		goto err_clk;
@@ -815,15 +799,18 @@ static int vc5_probe(struct i2c_client *client,
 	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
 		idx = vc5_map_index_to_output(vc5->chip_info->model, n);
 		memset(&init, 0, sizeof(init));
-		init.name = vc5_fod_names[idx];
+		init.name = kasprintf(GFP_KERNEL, "%pOFn.fod%d",
+				       client->dev.of_node, idx);
 		init.ops = &vc5_fod_ops;
 		init.flags = CLK_SET_RATE_PARENT;
-		init.parent_names = vc5_pll_names;
+		init.parent_names = parent_names;
+		parent_names[0] = clk_hw_get_name(&vc5->clk_pll.hw);
 		init.num_parents = 1;
 		vc5->clk_fod[n].num = idx;
 		vc5->clk_fod[n].vc5 = vc5;
 		vc5->clk_fod[n].hw.init = &init;
 		ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
+		kfree(init.name); /* clock framework made a copy of the name */
 		if (ret) {
 			dev_err(&client->dev, "unable to register %s\n",
 				init.name);
@@ -833,15 +820,18 @@ static int vc5_probe(struct i2c_client *client,
 
 	/* Register MUX-connected OUT0_I2C_SELB output */
 	memset(&init, 0, sizeof(init));
-	init.name = vc5_clk_out_names[0];
+	init.name = kasprintf(GFP_KERNEL, "%pOFn.out0_sel_i2cb",
+			       client->dev.of_node);
 	init.ops = &vc5_clk_out_ops;
 	init.flags = CLK_SET_RATE_PARENT;
-	init.parent_names = vc5_mux_names;
+	init.parent_names = parent_names;
+	parent_names[0] = clk_hw_get_name(&vc5->clk_mux);
 	init.num_parents = 1;
 	vc5->clk_out[0].num = idx;
 	vc5->clk_out[0].vc5 = vc5;
 	vc5->clk_out[0].hw.init = &init;
 	ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
+	kfree(init.name); /* clock framework made a copy of the name */
 	if (ret) {
 		dev_err(&client->dev, "unable to register %s\n",
 			init.name);
@@ -851,14 +841,15 @@ static int vc5_probe(struct i2c_client *client,
 	/* Register FOD-connected OUTx outputs */
 	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
 		idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
-		parent_names[0] = vc5_fod_names[idx];
+		parent_names[0] = clk_hw_get_name(&vc5->clk_fod[idx].hw);
 		if (n == 1)
-			parent_names[1] = vc5_mux_names[0];
+			parent_names[1] = clk_hw_get_name(&vc5->clk_mux);
 		else
-			parent_names[1] = vc5_clk_out_names[n - 1];
+			parent_names[1] = clk_hw_get_name(&vc5->clk_out[n-1].hw);
 
 		memset(&init, 0, sizeof(init));
-		init.name = vc5_clk_out_names[idx + 1];
+		init.name = kasprintf(GFP_KERNEL, "%pOFn.out%d",
+				       client->dev.of_node, idx + 1);
 		init.ops = &vc5_clk_out_ops;
 		init.flags = CLK_SET_RATE_PARENT;
 		init.parent_names = parent_names;
@@ -868,6 +859,7 @@ static int vc5_probe(struct i2c_client *client,
 		vc5->clk_out[n].hw.init = &init;
 		ret = devm_clk_hw_register(&client->dev,
 					   &vc5->clk_out[n].hw);
+		kfree(init.name); /* clock framework made a copy of the name */
 		if (ret) {
 			dev_err(&client->dev, "unable to register %s\n",
 				init.name);
-- 
2.25.1


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

* [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock
  2020-04-14 19:36 [PATCH 1/3] clk: vc5: Allow Versaclock driver to support multiple instances Adam Ford
@ 2020-04-14 19:36 ` Adam Ford
  2020-04-22 10:00   ` Stephen Boyd
  2020-04-14 19:36 ` [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock Adam Ford
  1 sibling, 1 reply; 5+ messages in thread
From: Adam Ford @ 2020-04-14 19:36 UTC (permalink / raw)
  To: linux-clk
  Cc: aford, charles.stevens, Adam Ford, Michael Turquette,
	Stephen Boyd, Rob Herring, Marek Vasut, devicetree, linux-kernel

The existing driver is expecting the Versaclock to be pre-programmed,
and only sets the output frequency.  Unfortunately, not all devices
are pre-programmed, and the Versaclock chip has more options beyond
just the frequency.

This patch enables the following additional features:

   - Programmable voltage: 1.8V, 2.5V, or 3.3V​
   - Slew Percentage of normal: 85%, 90%, or 100%
   - Output Type: LVPECL, CMOS, HCSL, or LVDS

Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 6e4b09f1f074..a1da88baf28c 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -24,6 +24,8 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
+#include <dt-bindings/clk/versaclock.h>
+
 /* VersaClock5 registers */
 #define VC5_OTP_CONTROL				0x00
 
@@ -89,6 +91,28 @@
 
 /* Clock control register for clock 1,2 */
 #define VC5_CLK_OUTPUT_CFG(idx, n)	(0x60 + ((idx) * 0x2) + (n))
+#define VC5_CLK_OUTPUT_CFG0_CFG_SHIFT	5
+#define VC5_CLK_OUTPUT_CFG0_CFG_MASK	GENMASK(7, VC5_CLK_OUTPUT_CFG0_CFG_SHIFT)
+
+#define VC5_CLK_OUTPUT_CFG0_CFG_LVPECL	(VC5_LVPECL)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS		(VC5_CMOS)
+#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL33	(VC5_HCSL33)
+#define VC5_CLK_OUTPUT_CFG0_CFG_LVDS		(VC5_LVDS)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS2		(VC5_CMOS2)
+#define VC5_CLK_OUTPUT_CFG0_CFG_CMOSD		(VC5_CMOSD)
+#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL25	(VC5_HCSL25)
+
+#define VC5_CLK_OUTPUT_CFG0_PWR_SHIFT	3
+#define VC5_CLK_OUTPUT_CFG0_PWR_MASK	GENMASK(4, VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_18	(0<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_25	(2<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_PWR_33	(3<<VC5_CLK_OUTPUT_CFG0_PWR_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT	0
+#define VC5_CLK_OUTPUT_CFG0_SLEW_MASK	GENMASK(1, VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_80	(0<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_85	(1<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_90	(2<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
+#define VC5_CLK_OUTPUT_CFG0_SLEW_100	(3<<VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT)
 #define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF	BIT(0)
 
 #define VC5_CLK_OE_SHDN				0x68
@@ -143,6 +167,8 @@ struct vc5_hw_data {
 	u32			div_int;
 	u32			div_frc;
 	unsigned int		num;
+	unsigned int		clk_output_cfg0;
+	unsigned int		clk_output_cfg0_mask;
 };
 
 struct vc5_driver_data {
@@ -567,6 +593,16 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
 	regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
 			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
 			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
+	if (hwdata->clk_output_cfg0_mask) {
+		dev_dbg(&vc5->client->dev, "Update output %d mask 0x%0X val 0x%0X\n",
+			hwdata->num, hwdata->clk_output_cfg0_mask,
+			hwdata->clk_output_cfg0);
+
+		regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
+			hwdata->clk_output_cfg0_mask,
+			hwdata->clk_output_cfg0);
+	}
+
 	return 0;
 }
 
@@ -675,6 +711,9 @@ static int vc5_probe(struct i2c_client *client,
 	struct clk_init_data init;
 	const char *parent_names[2];
 	unsigned int n, idx = 0;
+	u32 value;
+	struct device_node *np_output;
+	char *child_name;
 	int ret;
 
 	vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
@@ -865,6 +904,77 @@ static int vc5_probe(struct i2c_client *client,
 				init.name);
 			goto err_clk;
 		}
+
+		/* Fetch Clock Output configuration from DT (if specified) */
+		child_name = kasprintf(GFP_KERNEL, "OUT%d", n);
+		np_output = of_get_child_by_name(client->dev.of_node, child_name);
+		kfree(child_name);
+		if (!np_output)
+			continue;
+		if (!(ret || of_property_read_u32(np_output,
+			"idt,mode", &value))) {
+			vc5->clk_out[n].clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_CFG_MASK;
+			switch (value) {
+			case VC5_CLK_OUTPUT_CFG0_CFG_LVPECL:
+			case VC5_CLK_OUTPUT_CFG0_CFG_CMOS:
+			case VC5_CLK_OUTPUT_CFG0_CFG_HCSL33:
+			case VC5_CLK_OUTPUT_CFG0_CFG_LVDS:
+			case VC5_CLK_OUTPUT_CFG0_CFG_CMOS2:
+			case VC5_CLK_OUTPUT_CFG0_CFG_CMOSD:
+			case VC5_CLK_OUTPUT_CFG0_CFG_HCSL25:
+				vc5->clk_out[n].clk_output_cfg0 |= value << VC5_CLK_OUTPUT_CFG0_CFG_SHIFT;
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+			}
+		}
+		if (!(ret || of_property_read_u32(np_output,
+			"idt,voltage-microvolts", &value))) {
+			vc5->clk_out[n].clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK;
+			switch (value) {
+			case 1800000:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_18;
+				break;
+			case 2500000:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_25;
+				break;
+			case 3300000:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_PWR_33;
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+			}
+		}
+		if (!(ret || of_property_read_u32(np_output,
+			"idt,slew-percent", &value))) {
+			vc5->clk_out[n].clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_SLEW_MASK;
+			switch (value) {
+			case 80:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_80;
+				break;
+			case 85:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_85;
+				break;
+			case 90:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_90;
+				break;
+			case 100:
+				vc5->clk_out[n].clk_output_cfg0 |= VC5_CLK_OUTPUT_CFG0_SLEW_100;
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+			}
+		}
+		of_node_put(np_output);
+		if (ret) {
+			dev_err(&client->dev,
+				 "Invalid clock output configuration OUT%d\n",
+				 n);
+			goto err_clk;
+		}
 	}
 
 	ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
diff --git a/include/dt-bindings/clk/versaclock.h b/include/dt-bindings/clk/versaclock.h
new file mode 100644
index 000000000000..30add3488713
--- /dev/null
+++ b/include/dt-bindings/clk/versaclock.h
@@ -0,0 +1,13 @@
+/* HEADER */
+
+/* This file defines field values used by the versaclock 6 family
+ * for defining output type
+ */
+
+#define VC5_LVPECL	0
+#define VC5_CMOS	1
+#define VC5_HCSL33	2
+#define VC5_LVDS	3
+#define VC5_CMOS2	4
+#define VC5_CMOSD	5
+#define VC5_HCSL25	6
-- 
2.25.1


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

* [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock
  2020-04-14 19:36 [PATCH 1/3] clk: vc5: Allow Versaclock driver to support multiple instances Adam Ford
  2020-04-14 19:36 ` [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock Adam Ford
@ 2020-04-14 19:36 ` Adam Ford
  2020-04-20 21:13   ` Rob Herring
  1 sibling, 1 reply; 5+ messages in thread
From: Adam Ford @ 2020-04-14 19:36 UTC (permalink / raw)
  To: linux-clk
  Cc: aford, charles.stevens, Adam Ford, Michael Turquette,
	Stephen Boyd, Rob Herring, Marek Vasut, devicetree, linux-kernel

The VersaClock driver now supports some additional bindings to support
child nodes which can configure optional settings like mode, voltage
and slew.

This patch updates the binding document to describe what is available
in the driver.

Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
index bcff681a4bd0..6165b6ddb1a9 100644
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
@@ -31,6 +31,29 @@ Required properties:
 		- 5p49v5933 and
 		- 5p49v5935: (optional) property not present or "clkin".
 
+For all output ports, a corresponding, optional child node named OUT1,
+OUT2, etc. can represent a each output, and the node can be used to
+specify the following:
+
+- itd,mode: can be one of the following:
+                 - VC5_LVPECL
+                 - VC5_CMOS
+                 - VC5_HCSL33
+                 - VC5_LVDS
+                 - VC5_CMOS2
+                 - VC5_CMOSD
+                 - VC5_HCSL25
+
+- idt,voltage-microvolts:  can be one of the following
+                 - 1800000
+                 - 2500000
+                 - 3300000
+-  idt,slew-percent: Percent of normal, can be one of
+                 - 80
+                 - 85
+                 - 90
+                 - 100
+
 ==Mapping between clock specifier and physical pins==
 
 When referencing the provided clock in the DT using phandle and
@@ -81,6 +104,16 @@ i2c-master-node {
 		/* Connect XIN input to 25MHz reference */
 		clocks = <&ref25m>;
 		clock-names = "xin";
+
+		OUT1 {
+			itd,mode = <VC5_CMOS>;
+			idt,voltage-microvolts = <1800000>;
+			idt,slew-percent = <80>;
+		};
+		OUT2 {
+			...
+		};
+		...
 	};
 };
 
-- 
2.25.1


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

* Re: [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock
  2020-04-14 19:36 ` [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock Adam Ford
@ 2020-04-20 21:13   ` Rob Herring
  0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2020-04-20 21:13 UTC (permalink / raw)
  To: Adam Ford
  Cc: linux-clk, aford, charles.stevens, Adam Ford, Michael Turquette,
	Stephen Boyd, Marek Vasut, devicetree, linux-kernel

On Tue, 14 Apr 2020 14:36:16 -0500, Adam Ford wrote:
> The VersaClock driver now supports some additional bindings to support
> child nodes which can configure optional settings like mode, voltage
> and slew.
> 
> This patch updates the binding document to describe what is available
> in the driver.
> 
> Signed-off-by: Adam Ford <aford173@gmail.com>
> 

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

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

* Re: [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock
  2020-04-14 19:36 ` [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock Adam Ford
@ 2020-04-22 10:00   ` Stephen Boyd
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Boyd @ 2020-04-22 10:00 UTC (permalink / raw)
  To: Adam Ford, linux-clk
  Cc: aford, charles.stevens, Adam Ford, Michael Turquette,
	Rob Herring, Marek Vasut, devicetree, linux-kernel

Quoting Adam Ford (2020-04-14 12:36:15)
> @@ -865,6 +904,77 @@ static int vc5_probe(struct i2c_client *client,
>                                 init.name);
>                         goto err_clk;
>                 }
> +
> +               /* Fetch Clock Output configuration from DT (if specified) */
> +               child_name = kasprintf(GFP_KERNEL, "OUT%d", n);
> +               np_output = of_get_child_by_name(client->dev.of_node, child_name);
> +               kfree(child_name);
> +               if (!np_output)
> +                       continue;
> +               if (!(ret || of_property_read_u32(np_output,
> +                       "idt,mode", &value))) {
> +                       vc5->clk_out[n].clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_CFG_MASK;
> +                       switch (value) {
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_LVPECL:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_CMOS:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_HCSL33:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_LVDS:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_CMOS2:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_CMOSD:
> +                       case VC5_CLK_OUTPUT_CFG0_CFG_HCSL25:
> +                               vc5->clk_out[n].clk_output_cfg0 |= value << VC5_CLK_OUTPUT_CFG0_CFG_SHIFT;
> +                               break;
> +                       default:
> +                               ret = -EINVAL;
> +                               break;
> +                       }
> +               }

Can these three things be functions that are called and passed a
vc5->clk_out[n] pointer? Then the code would be something like 

 ret = prop1_parse_and_update(vc5->clk_out[n]);
 if (ret)
 	goto err_clk;
 ret = prop2_parse_and_update(...)
 if (ret)
 	goto err_clk;


> +               if (!(ret || of_property_read_u32(np_output,
> +                       "idt,voltage-microvolts", &value))) {
> +                       vc5->clk_out[n].clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK;
> diff --git a/include/dt-bindings/clk/versaclock.h b/include/dt-bindings/clk/versaclock.h
> new file mode 100644
> index 000000000000..30add3488713
> --- /dev/null
> +++ b/include/dt-bindings/clk/versaclock.h
> @@ -0,0 +1,13 @@
> +/* HEADER */

Any SPDX license for this in place of HEADER?

> +
> +/* This file defines field values used by the versaclock 6 family
> + * for defining output type
> + */
> +
> +#define VC5_LVPECL     0
> +#define VC5_CMOS       1
> +#define VC5_HCSL33     2
> +#define VC5_LVDS       3
> +#define VC5_CMOS2      4
> +#define VC5_CMOSD      5
> +#define VC5_HCSL25     6

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

end of thread, other threads:[~2020-04-22 10:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-14 19:36 [PATCH 1/3] clk: vc5: Allow Versaclock driver to support multiple instances Adam Ford
2020-04-14 19:36 ` [PATCH 2/3] clk: vc5: Enable addition output configurations of the Versaclock Adam Ford
2020-04-22 10:00   ` Stephen Boyd
2020-04-14 19:36 ` [PATCH 3/3] dt: Add additional option bindings for IDT VersaClock Adam Ford
2020-04-20 21:13   ` Rob Herring

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