linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver
@ 2020-07-02 21:28 Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 2/5] clk: vc5: use a dedicated struct to describe the output drivers Luca Ceresoli
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-02 21:28 UTC (permalink / raw)
  To: linux-clk
  Cc: Luca Ceresoli, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, linux-kernel, Marek Vasut

Marek has been the primary developer of this driver (thanks!). Now as
he is not working on it anymore he suggested I take over maintainership.

Cc: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 496fd4eafb68..079e19ed2ec9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8324,7 +8324,7 @@ W:	https://github.com/o2genum/ideapad-slidebar
 F:	drivers/input/misc/ideapad_slidebar.c
 
 IDT VersaClock 5 CLOCK DRIVER
-M:	Marek Vasut <marek.vasut@gmail.com>
+M:	Luca Ceresoli <luca@lucaceresoli.net>
 S:	Maintained
 F:	drivers/clk/clk-versaclock5.c
 
-- 
2.27.0


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

* [PATCH 2/5] clk: vc5: use a dedicated struct to describe the output drivers
  2020-07-02 21:28 [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver Luca Ceresoli
@ 2020-07-02 21:28 ` Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 3/5] dt-bindings: clk: versaclock5: convert to yaml Luca Ceresoli
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-02 21:28 UTC (permalink / raw)
  To: linux-clk
  Cc: Luca Ceresoli, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, linux-kernel, Marek Vasut

Reusing the generic struct vc5_hw_data for all blocks is handy. However
it implies we allocate space the div_int and div_frc fields even for
the output drivers where they are unused. Moreover a follow-up commit
will add a new field needed only for output drivers, thus the memory
waste would increase.

Use a dedicated struct for the output drivers so that each block uses
exactly the fields it needs, not more.

Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
 drivers/clk/clk-versaclock5.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index fa96659f8023..60c7cf9acde3 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -145,6 +145,12 @@ struct vc5_hw_data {
 	unsigned int		num;
 };
 
+struct vc5_out_data {
+	struct clk_hw		hw;
+	struct vc5_driver_data	*vc5;
+	unsigned int		num;
+};
+
 struct vc5_driver_data {
 	struct i2c_client	*client;
 	struct regmap		*regmap;
@@ -158,7 +164,7 @@ struct vc5_driver_data {
 	struct clk_hw		clk_pfd;
 	struct vc5_hw_data	clk_pll;
 	struct vc5_hw_data	clk_fod[VC5_MAX_FOD_NUM];
-	struct vc5_hw_data	clk_out[VC5_MAX_CLK_OUT_NUM];
+	struct vc5_out_data	clk_out[VC5_MAX_CLK_OUT_NUM];
 };
 
 static const char * const vc5_mux_names[] = {
@@ -565,7 +571,7 @@ static const struct clk_ops vc5_fod_ops = {
 
 static int vc5_clk_out_prepare(struct clk_hw *hw)
 {
-	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
 	struct vc5_driver_data *vc5 = hwdata->vc5;
 	const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
 			VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -596,7 +602,7 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
 
 static void vc5_clk_out_unprepare(struct clk_hw *hw)
 {
-	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
 	struct vc5_driver_data *vc5 = hwdata->vc5;
 
 	/* Disable the clock buffer */
@@ -606,7 +612,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw)
 
 static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
 {
-	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
 	struct vc5_driver_data *vc5 = hwdata->vc5;
 	const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
 			VC5_OUT_DIV_CONTROL_SEL_EXT |
@@ -636,7 +642,7 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
 
 static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
 {
-	struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
+	struct vc5_out_data *hwdata = container_of(hw, struct vc5_out_data, hw);
 	struct vc5_driver_data *vc5 = hwdata->vc5;
 	const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
 			VC5_OUT_DIV_CONTROL_SELB_NORM |
-- 
2.27.0


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

* [PATCH 3/5] dt-bindings: clk: versaclock5: convert to yaml
  2020-07-02 21:28 [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 2/5] clk: vc5: use a dedicated struct to describe the output drivers Luca Ceresoli
@ 2020-07-02 21:28 ` Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 4/5] dt-bindings: clk: versaclock5: add output drive mode property Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 5/5] clk: vc5: optionally configure the output drive mode Luca Ceresoli
  3 siblings, 0 replies; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-02 21:28 UTC (permalink / raw)
  To: linux-clk
  Cc: Luca Ceresoli, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, linux-kernel, Marek Vasut

Convert to yaml the VersaClock bindings document. The mapping between
clock specifier and physical pins cannot be described formally in yaml
schema, then keep it verbatim in the description field.

Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
 .../bindings/clock/idt,versaclock5.txt        |  92 --------------
 .../bindings/clock/idt,versaclock5.yaml       | 120 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 3 files changed, 121 insertions(+), 92 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/idt,versaclock5.txt
 create mode 100644 Documentation/devicetree/bindings/clock/idt,versaclock5.yaml

diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
deleted file mode 100644
index bcff681a4bd0..000000000000
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-Binding for IDT VersaClock 5,6 programmable i2c clock generators.
-
-The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock
-generators providing from 3 to 12 output clocks.
-
-==I2C device node==
-
-Required properties:
-- compatible:	shall be one of
-		"idt,5p49v5923"
-		"idt,5p49v5925"
-		"idt,5p49v5933"
-		"idt,5p49v5935"
-		"idt,5p49v6901"
-		"idt,5p49v6965"
-- reg:		i2c device address, shall be 0x68 or 0x6a.
-- #clock-cells:	from common clock binding; shall be set to 1.
-- clocks:	from common clock binding; list of parent clock handles,
-		- 5p49v5923 and
-		  5p49v5925 and
-		  5p49v6901: (required) either or both of XTAL or CLKIN
-					reference clock.
-		- 5p49v5933 and
-		- 5p49v5935: (optional) property not present (internal
-					Xtal used) or CLKIN reference
-					clock.
-- clock-names:	from common clock binding; clock input names, can be
-		- 5p49v5923 and
-		  5p49v5925 and
-		  5p49v6901: (required) either or both of "xin", "clkin".
-		- 5p49v5933 and
-		- 5p49v5935: (optional) property not present or "clkin".
-
-==Mapping between clock specifier and physical pins==
-
-When referencing the provided clock in the DT using phandle and
-clock specifier, the following mapping applies:
-
-5P49V5923:
-	0 -- OUT0_SEL_I2CB
-	1 -- OUT1
-	2 -- OUT2
-
-5P49V5933:
-	0 -- OUT0_SEL_I2CB
-	1 -- OUT1
-	2 -- OUT4
-
-5P49V5925 and
-5P49V5935:
-	0 -- OUT0_SEL_I2CB
-	1 -- OUT1
-	2 -- OUT2
-	3 -- OUT3
-	4 -- OUT4
-
-5P49V6901:
-	0 -- OUT0_SEL_I2CB
-	1 -- OUT1
-	2 -- OUT2
-	3 -- OUT3
-	4 -- OUT4
-
-==Example==
-
-/* 25MHz reference crystal */
-ref25: ref25m {
-	compatible = "fixed-clock";
-	#clock-cells = <0>;
-	clock-frequency = <25000000>;
-};
-
-i2c-master-node {
-
-	/* IDT 5P49V5923 i2c clock generator */
-	vc5: clock-generator@6a {
-		compatible = "idt,5p49v5923";
-		reg = <0x6a>;
-		#clock-cells = <1>;
-
-		/* Connect XIN input to 25MHz reference */
-		clocks = <&ref25m>;
-		clock-names = "xin";
-	};
-};
-
-/* Consumer referencing the 5P49V5923 pin OUT1 */
-consumer {
-	...
-	clocks = <&vc5 1>;
-	...
-}
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
new file mode 100644
index 000000000000..d8b8e35f16d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/idt,versaclock5.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Binding for IDT VersaClock 5 and 6 programmable I2C clock generators
+
+description: |
+  The IDT VersaClock 5 and VersaClock 6 are programmable I2C
+  clock generators providing from 3 to 12 output clocks.
+
+  When referencing the provided clock in the DT using phandle and clock
+  specifier, the following mapping applies:
+
+  - 5P49V5923:
+    0 -- OUT0_SEL_I2CB
+    1 -- OUT1
+    2 -- OUT2
+
+  - 5P49V5933:
+    0 -- OUT0_SEL_I2CB
+    1 -- OUT1
+    2 -- OUT4
+
+  - other parts:
+    0 -- OUT0_SEL_I2CB
+    1 -- OUT1
+    2 -- OUT2
+    3 -- OUT3
+    4 -- OUT4
+
+maintainers:
+  - Luca Ceresoli <luca@lucaceresoli.net>
+
+properties:
+  compatible:
+    enum:
+      - idt,5p49v5923
+      - idt,5p49v5925
+      - idt,5p49v5933
+      - idt,5p49v5935
+      - idt,5p49v6901
+      - idt,5p49v6965
+
+  reg:
+    maxItems: 1
+    description: I2C device address, shall be 0x68 or 0x6a.
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - idt,5p49v5933
+              - idt,5p49v5935
+    then:
+      # Devices with builtin crystal, optional external input
+      properties:
+        clock-names:
+          const: clkin
+        clocks:
+          maxItems: 1
+    else:
+      # Devices without builtin crystal
+      properties:
+        clock-names:
+          anyOf:
+            - required: [ xin ]
+            - required: [ clkin ]
+        clocks:
+          minItems: 1
+          maxItems: 2
+      required:
+        - clock-names
+        - clocks
+
+examples:
+  - |
+    /* 25MHz reference crystal */
+    ref25: ref25m {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <25000000>;
+    };
+
+    i2c@0 {
+        reg = <0x0 0x100>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        /* IDT 5P49V5923 I2C clock generator */
+        vc5: clock-generator@6a {
+            compatible = "idt,5p49v5923";
+            reg = <0x6a>;
+            #clock-cells = <1>;
+
+            /* Connect XIN input to 25MHz reference */
+            clocks = <&ref25m>;
+            clock-names = "xin";
+        };
+    };
+
+    /* Consumer referencing the 5P49V5923 pin OUT1 */
+    consumer {
+        /* ... */
+        clocks = <&vc5 1>;
+        /* ... */
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 079e19ed2ec9..e979f5026353 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8326,6 +8326,7 @@ F:	drivers/input/misc/ideapad_slidebar.c
 IDT VersaClock 5 CLOCK DRIVER
 M:	Luca Ceresoli <luca@lucaceresoli.net>
 S:	Maintained
+F:	Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
 F:	drivers/clk/clk-versaclock5.c
 
 IEEE 802.15.4 SUBSYSTEM
-- 
2.27.0


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

* [PATCH 4/5] dt-bindings: clk: versaclock5: add output drive mode property
  2020-07-02 21:28 [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 2/5] clk: vc5: use a dedicated struct to describe the output drivers Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 3/5] dt-bindings: clk: versaclock5: convert to yaml Luca Ceresoli
@ 2020-07-02 21:28 ` Luca Ceresoli
  2020-07-02 21:28 ` [PATCH 5/5] clk: vc5: optionally configure the output drive mode Luca Ceresoli
  3 siblings, 0 replies; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-02 21:28 UTC (permalink / raw)
  To: linux-clk
  Cc: Luca Ceresoli, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, linux-kernel, Marek Vasut

Add a node with properties for each output port, and a property inside it
to describe the output drive mode.

Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
 .../bindings/clock/idt,versaclock5.yaml       | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
index d8b8e35f16d2..f0ee612f573b 100644
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
@@ -50,6 +50,35 @@ properties:
   '#clock-cells':
     const: 1
 
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+patternProperties:
+  "^out@[1-4]$":
+    type: object
+    description:
+      Description of one of the outputs (OUT1..OUT4).
+    properties:
+      idt,drive-mode:
+        description:
+          The output drive mode. See "Clock1 Output Configuration" in the
+          Versaclock 5/6/6E Family Register Description and Programming
+          Guide.
+          Allowed values are:-
+            * 0 = LVPECL
+            * 1 = CMOS
+            * 2 = HCSL33
+            * 3 = LVDS
+            * 4 = CMOS2
+            * 5 = CMOSD
+            * 6 = HCSL25
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 0
+        maximum: 6
+
 required:
   - compatible
   - reg
@@ -107,6 +136,19 @@ examples:
             /* Connect XIN input to 25MHz reference */
             clocks = <&ref25m>;
             clock-names = "xin";
+
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            out@1 {
+                reg = <1>; /* OUT1 */
+                idt,drive-mode = <5>; /* CMOSD */
+            };
+
+            out@4 {
+                reg = <4>; /* OUT4 */
+                idt,drive-mode = <3>; /* LVDS */
+            };
         };
     };
 
-- 
2.27.0


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

* [PATCH 5/5] clk: vc5: optionally configure the output drive mode
  2020-07-02 21:28 [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver Luca Ceresoli
                   ` (2 preceding siblings ...)
  2020-07-02 21:28 ` [PATCH 4/5] dt-bindings: clk: versaclock5: add output drive mode property Luca Ceresoli
@ 2020-07-02 21:28 ` Luca Ceresoli
  2020-07-06 20:03   ` Adam Ford
  3 siblings, 1 reply; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-02 21:28 UTC (permalink / raw)
  To: linux-clk
  Cc: Luca Ceresoli, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, linux-kernel, Marek Vasut

The Versaclock chips can drive the output pins in several modes: LVDS,
CMOS, LVPECL etc. Allow configuring the output mode from device tree.

The configuration is optional. If not specified, the mode will not be
configured and the drive mode will be the chip default.

Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
---
 drivers/clk/clk-versaclock5.c | 71 +++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 60c7cf9acde3..eec57286fae0 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -89,6 +89,8 @@
 
 /* Clock control register for clock 1,2 */
 #define VC5_CLK_OUTPUT_CFG(idx, n)	(0x60 + ((idx) * 0x2) + (n))
+#define VC5_CLK_OUTPUT_CFG0_MODE_SHIFT	5
+#define VC5_CLK_OUTPUT_CFG0_MODE_MASK	GENMASK(7, 5)
 #define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF	BIT(0)
 
 #define VC5_CLK_OE_SHDN				0x68
@@ -117,6 +119,23 @@
 /* chip has PFD requency doubler */
 #define VC5_HAS_PFD_FREQ_DBL	BIT(1)
 
+/*
+ * Output modes. Values for VC5_CLK_OUTPUT_CFG(idx,0) bits [7:5].
+ * IDT_VC5_OUT_UNKNOWN = keep the hardware default.
+ */
+enum vc5_out_mode {
+	IDT_VC5_OUT_MODE_LVPECL   = 0,
+	IDT_VC5_OUT_MODE_CMOS     = 1,
+	IDT_VC5_OUT_MODE_HCSL33   = 2,
+	IDT_VC5_OUT_MODE_LVDS     = 3,
+	IDT_VC5_OUT_MODE_CMOS2    = 4,
+	IDT_VC5_OUT_MODE_CMOSD    = 5,
+	IDT_VC5_OUT_MODE_HCSL25   = 6,
+
+	IDT_VC5_OUT_NUM_MODES,
+	IDT_VC5_OUT_MODE_UNKNOWN  = 99,
+};
+
 /* Supported IDT VC5 models. */
 enum vc5_model {
 	IDT_VC5_5P49V5923,
@@ -149,6 +168,7 @@ struct vc5_out_data {
 	struct clk_hw		hw;
 	struct vc5_driver_data	*vc5;
 	unsigned int		num;
+	enum vc5_out_mode	mode:8;
 };
 
 struct vc5_driver_data {
@@ -593,6 +613,13 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
 			return ret;
 	}
 
+	/* Set output drive mode */
+	if (hwdata->mode != IDT_VC5_OUT_MODE_UNKNOWN)
+		regmap_update_bits(vc5->regmap,
+				   VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
+				   VC5_CLK_OUTPUT_CFG0_MODE_MASK,
+				   (hwdata->mode << VC5_CLK_OUTPUT_CFG0_MODE_SHIFT));
+
 	/* Enable the clock buffer */
 	regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
 			   VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
@@ -696,6 +723,46 @@ static int vc5_map_index_to_output(const enum vc5_model model,
 	}
 }
 
+static int vc5_parse_dt(struct vc5_driver_data *vc5)
+{
+	struct device *dev = &vc5->client->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	u32 val;
+	int n;
+
+	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++)
+		vc5->clk_out[n].mode = IDT_VC5_OUT_MODE_UNKNOWN;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_u32(child, "reg", &n)) {
+			dev_err(dev, "%pOF: missing reg property\n", child);
+			break;
+		}
+
+		if (n == 0 || n >= vc5->chip_info->clk_out_cnt) {
+			dev_err(dev, "%pOF: invalid reg %d\n", child, n);
+			break;
+		}
+
+		if (!of_property_read_u32(child, "idt,drive-mode", &val)) {
+			if (val >= IDT_VC5_OUT_NUM_MODES) {
+				dev_err(dev, "%pOF: invalid idt,drive-mode %u\n",
+					child, val);
+				break;
+			}
+			vc5->clk_out[n].mode = val;
+		}
+	}
+
+	if (child) {
+		of_node_put(child);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct of_device_id clk_vc5_of_match[];
 
 static int vc5_probe(struct i2c_client *client,
@@ -723,6 +790,10 @@ static int vc5_probe(struct i2c_client *client,
 	if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	ret = vc5_parse_dt(vc5);
+	if (ret)
+		return ret;
+
 	vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
 	if (IS_ERR(vc5->regmap)) {
 		dev_err(&client->dev, "failed to allocate register map\n");
-- 
2.27.0


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

* Re: [PATCH 5/5] clk: vc5: optionally configure the output drive mode
  2020-07-02 21:28 ` [PATCH 5/5] clk: vc5: optionally configure the output drive mode Luca Ceresoli
@ 2020-07-06 20:03   ` Adam Ford
  2020-07-06 20:31     ` Luca Ceresoli
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Ford @ 2020-07-06 20:03 UTC (permalink / raw)
  To: Luca Ceresoli
  Cc: linux-clk, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, Linux Kernel Mailing List, Marek Vasut

On Thu, Jul 2, 2020 at 5:40 PM Luca Ceresoli <luca@lucaceresoli.net> wrote:
>
> The Versaclock chips can drive the output pins in several modes: LVDS,
> CMOS, LVPECL etc. Allow configuring the output mode from device tree.
>
> The configuration is optional. If not specified, the mode will not be
> configured and the drive mode will be the chip default.
>
> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>

This might be duplicating what's been applied to linux-next already.

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/clk/clk-versaclock5.c?h=next-20200706&id=260249f929e81d3d5764117fdd6b9e43eb8fb1d5


> ---
>  drivers/clk/clk-versaclock5.c | 71 +++++++++++++++++++++++++++++++++++
>  1 file changed, 71 insertions(+)
>
> diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
> index 60c7cf9acde3..eec57286fae0 100644
> --- a/drivers/clk/clk-versaclock5.c
> +++ b/drivers/clk/clk-versaclock5.c
> @@ -89,6 +89,8 @@
>
>  /* Clock control register for clock 1,2 */
>  #define VC5_CLK_OUTPUT_CFG(idx, n)     (0x60 + ((idx) * 0x2) + (n))
> +#define VC5_CLK_OUTPUT_CFG0_MODE_SHIFT 5
> +#define VC5_CLK_OUTPUT_CFG0_MODE_MASK  GENMASK(7, 5)
>  #define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF  BIT(0)
>
>  #define VC5_CLK_OE_SHDN                                0x68
> @@ -117,6 +119,23 @@
>  /* chip has PFD requency doubler */
>  #define VC5_HAS_PFD_FREQ_DBL   BIT(1)
>
> +/*
> + * Output modes. Values for VC5_CLK_OUTPUT_CFG(idx,0) bits [7:5].
> + * IDT_VC5_OUT_UNKNOWN = keep the hardware default.
> + */
> +enum vc5_out_mode {
> +       IDT_VC5_OUT_MODE_LVPECL   = 0,
> +       IDT_VC5_OUT_MODE_CMOS     = 1,
> +       IDT_VC5_OUT_MODE_HCSL33   = 2,
> +       IDT_VC5_OUT_MODE_LVDS     = 3,
> +       IDT_VC5_OUT_MODE_CMOS2    = 4,
> +       IDT_VC5_OUT_MODE_CMOSD    = 5,
> +       IDT_VC5_OUT_MODE_HCSL25   = 6,
> +
> +       IDT_VC5_OUT_NUM_MODES,
> +       IDT_VC5_OUT_MODE_UNKNOWN  = 99,
> +};
> +
>  /* Supported IDT VC5 models. */
>  enum vc5_model {
>         IDT_VC5_5P49V5923,
> @@ -149,6 +168,7 @@ struct vc5_out_data {
>         struct clk_hw           hw;
>         struct vc5_driver_data  *vc5;
>         unsigned int            num;
> +       enum vc5_out_mode       mode:8;
>  };
>
>  struct vc5_driver_data {
> @@ -593,6 +613,13 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
>                         return ret;
>         }
>
> +       /* Set output drive mode */
> +       if (hwdata->mode != IDT_VC5_OUT_MODE_UNKNOWN)
> +               regmap_update_bits(vc5->regmap,
> +                                  VC5_CLK_OUTPUT_CFG(hwdata->num, 0),
> +                                  VC5_CLK_OUTPUT_CFG0_MODE_MASK,
> +                                  (hwdata->mode << VC5_CLK_OUTPUT_CFG0_MODE_SHIFT));
> +
>         /* Enable the clock buffer */
>         regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
>                            VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
> @@ -696,6 +723,46 @@ static int vc5_map_index_to_output(const enum vc5_model model,
>         }
>  }
>
> +static int vc5_parse_dt(struct vc5_driver_data *vc5)
> +{
> +       struct device *dev = &vc5->client->dev;
> +       struct device_node *np = dev->of_node;
> +       struct device_node *child;
> +       u32 val;
> +       int n;
> +
> +       for (n = 1; n < vc5->chip_info->clk_out_cnt; n++)
> +               vc5->clk_out[n].mode = IDT_VC5_OUT_MODE_UNKNOWN;
> +
> +       for_each_child_of_node(np, child) {
> +               if (of_property_read_u32(child, "reg", &n)) {
> +                       dev_err(dev, "%pOF: missing reg property\n", child);
> +                       break;
> +               }
> +
> +               if (n == 0 || n >= vc5->chip_info->clk_out_cnt) {
> +                       dev_err(dev, "%pOF: invalid reg %d\n", child, n);
> +                       break;
> +               }
> +
> +               if (!of_property_read_u32(child, "idt,drive-mode", &val)) {
> +                       if (val >= IDT_VC5_OUT_NUM_MODES) {
> +                               dev_err(dev, "%pOF: invalid idt,drive-mode %u\n",
> +                                       child, val);
> +                               break;
> +                       }
> +                       vc5->clk_out[n].mode = val;
> +               }
> +       }
> +
> +       if (child) {
> +               of_node_put(child);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
>  static const struct of_device_id clk_vc5_of_match[];
>
>  static int vc5_probe(struct i2c_client *client,
> @@ -723,6 +790,10 @@ static int vc5_probe(struct i2c_client *client,
>         if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
>                 return -EPROBE_DEFER;
>
> +       ret = vc5_parse_dt(vc5);
> +       if (ret)
> +               return ret;
> +
>         vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
>         if (IS_ERR(vc5->regmap)) {
>                 dev_err(&client->dev, "failed to allocate register map\n");
> --
> 2.27.0
>

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

* Re: [PATCH 5/5] clk: vc5: optionally configure the output drive mode
  2020-07-06 20:03   ` Adam Ford
@ 2020-07-06 20:31     ` Luca Ceresoli
  0 siblings, 0 replies; 7+ messages in thread
From: Luca Ceresoli @ 2020-07-06 20:31 UTC (permalink / raw)
  To: Adam Ford
  Cc: linux-clk, Michael Turquette, Stephen Boyd, Rob Herring,
	devicetree, Linux Kernel Mailing List, Marek Vasut

Hi Adam,

On 06/07/20 22:03, Adam Ford wrote:
> On Thu, Jul 2, 2020 at 5:40 PM Luca Ceresoli <luca@lucaceresoli.net> wrote:
>>
>> The Versaclock chips can drive the output pins in several modes: LVDS,
>> CMOS, LVPECL etc. Allow configuring the output mode from device tree.
>>
>> The configuration is optional. If not specified, the mode will not be
>> configured and the drive mode will be the chip default.
>>
>> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
> 
> This might be duplicating what's been applied to linux-next already.

Oh dear, it is! I hadn't found this patch when I needed it...

Please consider this series superseded. There are still some (minor-ish)
improvements, but they definitely need to be rebased and partially
rewritten.

-- 
Luca

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

end of thread, other threads:[~2020-07-06 20:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-02 21:28 [PATCH 1/5] MAINTAINERS: take over IDT VersaClock 5 clock driver Luca Ceresoli
2020-07-02 21:28 ` [PATCH 2/5] clk: vc5: use a dedicated struct to describe the output drivers Luca Ceresoli
2020-07-02 21:28 ` [PATCH 3/5] dt-bindings: clk: versaclock5: convert to yaml Luca Ceresoli
2020-07-02 21:28 ` [PATCH 4/5] dt-bindings: clk: versaclock5: add output drive mode property Luca Ceresoli
2020-07-02 21:28 ` [PATCH 5/5] clk: vc5: optionally configure the output drive mode Luca Ceresoli
2020-07-06 20:03   ` Adam Ford
2020-07-06 20:31     ` Luca Ceresoli

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).