Thread (6 messages) 6 messages, 4 authors, 2019-06-06

Re: [Patch v9] driver/clk/clk-si5338: Add common clock framework driver for si5338

From: york sun <hidden>
Date: 2016-09-02 18:32:14
Also in: linux-clk, lkml

On 09/02/2016 07:04 AM, Rob Herring wrote:
On Fri, Aug 26, 2016 at 02:45:49PM -0700, York Sun wrote:
quoted
From: York Sun <redacted>

SI5338 is a programmable clock generator. It has 4 sets of inputs,
PLL, multisynth and dividers to make 4 outputs. This driver splits
them into multiple clocks to comply with common clock framework.

See Documentation/devicetree/bindings/clock/silabs,si5338.txt for
details.

Signed-off-by: York Sun <redacted>
CC: Mike Turquette <mturquette@baylibre.com>
CC: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
CC: Guenter Roeck <linux@roeck-us.net>
CC: Andrey Filippov <redacted>
CC: Paul Bolle <redacted>
7 versions before you decide to start cc'ing DT list?
7? I only started to CC DT list since version 8. Didn't know I needed 
to. I thought device tree binding is part of driver.
[...]
quoted
diff --git a/Documentation/devicetree/bindings/clock/silabs,si5338.txt b/Documentation/devicetree/bindings/clock/silabs,si5338.txt
new file mode 100644
index 0000000..cc7ae8e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/silabs,si5338.txt
@@ -0,0 +1,192 @@
+Binding for Silicon Labs Si5338 programmable i2c clock generator.
+
+Reference
+[1] Si5338 Data Sheet
+    http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5338.pdf
+
+The Si5338 is a programmable i2c clock generators with up to 4 output
+clocks. It has 4 sets of possible input clocks
+
+IN1/IN2: differential
+IN3: single-ended
+IN4: single-ended
+IN5/IN6: differential
+
+Additionally, IN1/IN2 can be used as XTAL with different setting.
+The clock tree looks like below (without support of zero-delay)
+
+
+      IN1/IN2 IN3         IN4 IN5/IN6
+         |     |           |     |
+   ------|     |           |     |
+   |     |     |           |     |
+   |     \     /           \     /
+   |      \   /             \   /
+   |       \ /               \ /
+ XTAL     REFCLK            FBCLK
+   |       |  \             /   |
+   |       |   \           /    |
+   |       | DIVREFCLK DIVFBCLK |
+   |       |     \       /      |
+   |       |      \     /       |
+   |       |       \   /        |
+   |       |        PLL         |
+   |       |      / | | \       |
+   |       |     /  / \  \      |
+   |       |    /  /   \  \     |
+   |       |   /   |   |   \    |
+   |       |   |   |   |   |    |
+   |       |  MS0 MS1 MS2 MS3   |
+   |       |   |   |   |   |    |
+
+       OUT0  OUT1  OUT2  OUT3
+
+The output clock can choose from any of the above clock as its source, with
+exceptions: MS1 can only be used for OUT1, MS2 can only be used for OUT2, MS3
+can only be used for OUT3.
+
+==I2C device node==
+
+Required properties:
+- compatible: shall be "silabs,si5338".
+- reg: i2c device address, shall be 0x60, 0x61, 0x70, or 0x71
+- #clock-cells: shall be set to 1 for multiple outputs
+- clocks: list of parent clocks in the order of <xtal>, <in1/2>, <in3>, <in4>,
+	 <in5/6>.
+	Note, xtal and in1/2 are mutually exclusive. Only one can be set.
+- clock-names: The name of the clocks in the same order.
+- #address-cells: shall be set to 1.
+- #size-cells: shall be set to 0.
+- silabs,pll-master: If PLL is used, pick one MS (0, 1, 2, or 3) to allow
+	chaning PLL rate. This is arbitrary since MS0/1/2/3 share one PLL.
+	PLL can be calculated backward to satisfy MS. This node is not
+	required if PLL is not used, or if silabs,pll-vco is set.
+
+Optional properties if not set by platform driver:
+- silab,name-prefix: name prefix for si5338
+        If multiple si5338 chips exist, use name-prefix to form unique names.
+	If omitted, i2c bus name will be used as the prefix.
Drop this please. There should not be any need for it.
Which part? The default name, or slab,name-prefix completely?

When multiple si5338 chips exist, we need to name the clocks 
differently, don't we?
quoted
+- silab,ref-source: source of refclk, valid value is defined as
+	#define SI5338_REF_SRC_CLKIN12          0
+	#define SI5338_REF_SRC_CLKIN3           1
+	#define SI5338_REF_SRC_XTAL             4
+- silab,fb-source:  source of fbclk, valid value is defined as
+	#define SI5338_FB_SRC_CLKIN4            2
+	#define SI5338_FB_SRC_CLKIN56           3
+	#define SI5338_FB_SRC_NOCLK             5
+- silabs,pll-source: source of pll, valid value is defined as
+	#define SI5338_PFD_IN_REF_REFCLK           0
+	#define SI5338_PFD_IN_REF_FBCLK            1
+	#define SI5338_PFD_IN_REF_DIVREFCLK        2
+	#define SI5338_PFD_IN_REF_DIVFBCLK         3
+	#define SI5338_PFD_IN_REF_XOCLK            4
+	#define SI5338_PFD_IN_REF_NOCLK            5
+- silabs,pll-vco: Specify VCO frequency for optimal ratios for all outputs.
+	If specified, silabs,pll-master is ignored.
+
+==Child nodes==
+
+Each of the clock outputs can be configured individually by
+using a child node to the I2C device node. If a child node for a clock
+output is not set, platform driver has to set up.
+
+Required child node properties:
+- name: name for the child node
+        It has to be unique. The name prefix is ignored.
+	If using platform data and the name is not specificed,
+        clkout0/1/2/3 will be used with name prefix.
+- reg: number of clock output.
+
+Optional child node properties:
+- silabs,drive-config: the configuration of output driver
+  The valid value list is long. Please refer to soruce code.
May be long, but needs to be documented here. I don't follow why you are
using strings for the values here.
Using string so it is readable. The acceptable values are

3V3_CMOS_A+
3V3_CMOS_A-
3V3_CMOS_B+
3V3_CMOS_B-
3V3_CMOS_A+B+
3V3_CMOS_A-B+
3V3_CMOS_A+B-
3V3_CMOS_A-B-

2V5_CMOS_A+
2V5_CMOS_A-
2V5_CMOS_B+
2V5_CMOS_B-
2V5_CMOS_A+B+
2V5_CMOS_A-B+
2V5_CMOS_A+B-
2V5_CMOS_A-B-

1V8_CMOS_A+
1V8_CMOS_A-
1V8_CMOS_B+
1V8_CMOS_B-
1V8_CMOS_A+B+
1V8_CMOS_A-B+
1V8_CMOS_A+B-
1V8_CMOS_A-B-

1V5_HSTL_A+
1V5_HSTL_A-
1V5_HSTL_B+
1V5_HSTL_B-
1V5_HSTL_A+B+
1V5_HSTL_A-B+
1V5_HSTL_A+B-
1V5_HSTL_A-B-

3V3_SSTL_A+
3V3_SSTL_A-
3V3_SSTL_B+
3V3_SSTL_B-
3V3_SSTL_A+B+
3V3_SSTL_A-B+
3V3_SSTL_A+B-
3V3_SSTL_A-B-

2V5_SSTL_A+
2V5_SSTL_A-
2V5_SSTL_B+
2V5_SSTL_B-
2V5_SSTL_A+B+
2V5_SSTL_A-B+
2V5_SSTL_A+B-
2V5_SSTL_A-B-

1V8_SSTL_A+
1V8_SSTL_A-
1V8_SSTL_B+
1V8_SSTL_B-
1V8_SSTL_A+B+
1V8_SSTL_A-B+
1V8_SSTL_A+B-
1V8_SSTL_A-B-

3V3_LVPECL
2V5_LVPECL
3V3_LVDS
2V5_LVDS
1V8_LVDS

Will add here in next version.
quoted
+- silabs,clock-source: source clock of the output divider
+	#define SI5338_OUT_MUX_FBCLK            0
+	#define SI5338_OUT_MUX_REFCLK           1
+	#deinfe SI5338_OUT_MUX_DIVFBCLK         2
+	#deinfe SI5338_OUT_MUX_DIVREFCLK        3
+	#deinfe SI5338_OUT_MUX_XOCLK            4
+	#deinfe SI5338_OUT_MUX_MS0              5
+	#deinfe SI5338_OUT_MUX_MSN              6 /* MS0/1/2/3 */
+	#deinfe SI5338_OUT_MUX_NOCLK            7
+- silabs,disable-state : clock output disable state, shall be
+	#define SI5338_OUT_DIS_HIZ              0
+	#define SI5338_OUT_DIS_LOW              1
+	#define SI5338_OUT_DIS_HI               2
+	#define SI5338_OUT_DIS_ALWAYS_ON        3
+- enabled: the output is enabled by default
+	The existence of this node enables the output when the driver is loaded
+	otherwise the clock is only enabled when used
Drop this. Either platform code should claim this and enable the clock
or use the critical clocks binding.
The idea is to specify if the clock(s) should be enabled upon loading 
the driver.  I am not familiar with critical clocks binding. Can you 
point me to its document/code? Not seeing it in kernel tree.
quoted
+
+==Example==
+
+/* 25MHz reference crystal */
+ref25: ref25M {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <25000000>;
+};
+clkin56: ref100M {
+	compatible = "fixed-clock";
+	#clock-cells = <0>;
+	clock-frequency = <100000000>;
+};
+i2c-master-node {
+	si5338: clock-generator@70 {
+		compatible = "silabs,si5338";
+		reg = <0x70>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#clock-cells = <1>;
+
+		/* connect xtal to 25MHz, in5/in6 to 100MHz */
+		clocks = <&ref25>, <0>, <0>, <0>, <&clkin56>;
+		clock-names = "xtal", "in12", "in3", "in4", "in56";
+
+		/* connect xtal as source of refclk */
+		silab,ref-source = <SI5338_REF_SRC_XTAL>;
+
+		/* connect in5/in6 as source of fbclk */
+		silab,fb-source = <SI5338_FB_SRC_CLKIN56>;
+
+		/* connect divrefclk as source of pll */
+		silab,pll-source = <SI5338_PFD_IN_REF_DIVREFCLK>;
+
+		/* Choose one MS for pll master */
+		silabs,pll-master = <0>;
+
+		/* Specify pll-vco frequency. pll-master is ignored. */
+		silabs,pll-vco = <2450000000>;
+
+		/* output */
+		clkout0 {
reg property means you need a unit address.
The reg has the address of each output, i.e. 0, 1, 2, 3. What's wrong here?
quoted
+			reg = <0>;
+			silabs,drive-config = "1V8_LVDS";
+			silabs,clock-source = <SI5338_OUT_MUX_MS0>;
+			silabs,disable-state = <SI5338_OUT_DIS_HIZ>;
+			clock-frequency = <125000000>;
+		};
+		clkout1 {
+			reg = <1>;
+			silabs,drive-config = "1V8_LVDS";
+			silabs,clock-source = <SI5338_OUT_MUX_MSN>;
+			silabs,disable-state = <SI5338_OUT_DIS_HIZ>;
+			clock-frequency = <125000000>;
+		};
+		clkout2 {
+			reg = <2>;
+			silabs,drive-config = "1V8_LVDS";
+			silabs,clock-source = <SI5338_OUT_MUX_MSN>;
+			silabs,disable-state = <SI5338_OUT_DIS_HIZ>;
+			clock-frequency = <125000000>;
+		};
+		clkout3 {
+			reg = <3>;
+			silabs,drive-config = "1V8_LVDS";
+			silabs,clock-source = <SI5338_OUT_MUX_MSN>;
+			silabs,disable-state = <SI5338_OUT_DIS_HIZ>;
+			clock-frequency = <125000000>;
+		};
+
+	};
+};
I see no more comment below. Are you OK with the rest of the patch?

York

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help