From: Sebastian Hesselbarth <hidden> Date: 2012-07-12 07:15:14
As Rob's clock binding support patch is now up on clk-next, I'd like to
draw attention on this patch again.
--
This patch adds support for using clock gates (clk-gate) from DT based
on Rob Herrings DT clk binding support for 3.6.
It adds a helper function to clk-gate to allocate all resources required by
a set of individual clock gates, i.e. register base address and lock. Each
clock gate is described as a child of the clock-gating-control in DT and
also created by the helper function.
Signed-off-by: Sebastian Hesselbarth <redacted>
Cc: Grant Likely <redacted>
Cc: Rob Herring <redacted>
Cc: Rob Landley <redacted>
Cc: Mike Turquette <redacted>
Cc: devicetree-discuss at lists.ozlabs.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
.../bindings/clock/clock-gating-control.txt | 80 +++++++++++++++++++
drivers/clk/clk-gate.c | 84 ++++++++++++++++++++
include/linux/clk-provider.h | 2 +
3 files changed, 166 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/clock-gating-control.txt
@@ -0,0 +1,80 @@+Binding for simple clock gating control based on clock gate register with one+bit per clock gate. This is a clock consumer and also a clock provider for a+set of gated clocks that are described as children of this node. Each clock gate+is described by a bit number and polarity to control the gate.++This binding uses the common clock binding[1].++[1] Documentation/devicetree/bindings/clock/clock-bindings.txt++==Clock gating control==++Required properties:+- compatible : shall be "clock-gating-control".+- reg : should contain the register physical address and length for+ the clock gating control.+- clocks : shared parent clock for all gated clocks.+- #clock-cells : from common clock binding; shall be set to 0.+- #address-cells : number of cells required to describe a clock gate;+ should be <2>.+- #size-cells : should be zero.++Each individual clock gate bit is described as a child of the+corresponding gating control register with the following properties.++Required child properties:+- reg : should contain the individual bit and polarity to control+ the clock gate. A polarity of 0 means that by setting the+ bit to 1 the clock passes through the clock gate while+ setting the bit to 0 disables the clock. Any other value+ for polarity inverts the meaning of the control bit.++Optional child properties:+- clocks : overrides the shared parent clock for this clock gate+ by the clock passed in this property.+- clock-output-names : from common clock binding; allows to set+ a specific name for the gated clock output.++==Example==++ /* fixed root clock */+ osc: oscillator {+ compatible = "fixed-clock";+ #clock-cells = <0>;+ clock-frequency = <166666667>;+ };++ /* sata peripheral clock */+ sata_clk: ext-oscillator {+ compatible = "fixed-clock";+ #clock-cells = <0>;+ clock-frequency = <25000000>;+ };++ /* register-based clock gating control */+ gating-control at f10d0038 {+ compatible = "clock-gating-control";+ reg = <0xf10d0038 0x4>;+ clocks = <&osc>;+ #clock-cells = <0>;+ #address-cells = <2>;+ #size-cells = <0>;++ /* USB0 clock gate on register bit 0 with inverted polarity */+ cg_usb0: clockgate at 0 {+ reg = <0 1>; /* register bit 0, inverted polarity */+ };++ /* PCIe0 clock gate on register bit 1 with normal polarity+ * and named output clock */+ cg_pcie0: clockgate at 1 {+ reg = <1 0>; /* register bit 1, normal polarity */+ clock-output-names = "pcie0_clk";+ };++ /* SATA clock gate with different parent clock */+ cg_sata: clockgate at 3 {+ reg = <3 0>; /* register bit 3, normal polarity */+ clocks = <&sata_clk>;+ };+ };
@@ -148,3 +151,84 @@ struct clk *clk_register_gate(struct device *dev, const char *name,returnclk;}++#ifdef CONFIG_OF+/**+*of_clock_gating_control_setup()-Setupfunctionforclockgatecontrol+*Thisisahelperforusingclk-gatefromOFdevicetree.Itallocates+*acommonlockforabaseregisterandcreatestheindividualclk-gates.+*/+void__initof_clock_gating_control_setup(structdevice_node*np)+{+structdevice_node*child;+constchar*pclk_name;+void__iomem*base;+spinlock_t*lockp;+unsignedintrnum;+u64addr;++pclk_name=of_clk_get_parent_name(np,0);+if(!pclk_name){+pr_debug("%s: unable to get parent clock for %s\n",+__func__,np->full_name);+return;+}++lockp=kzalloc(sizeof(spinlock_t),GFP_KERNEL);+if(!lockp){+pr_debug("%s: unable to allocate spinlock for %s\n",+__func__,np->full_name);+return;+}++spin_lock_init(lockp);+base=of_iomap(np,0);+rnum=sizeof(resource_size_t)*8;+addr=of_translate_address(np,of_get_property(np,"reg",NULL));++pr_debug("create clock gate control %s\n",np->full_name);++for_each_child_of_node(np,child){+structclk*cg;+constchar*cg_name;+constchar*cg_pclk_name;+u32propval[2];+unsignedintrbit;++if(of_property_read_u32_array(child,"reg",propval,2)){+pr_debug("%s: wrong #reg on %s\n",+__func__,child->full_name);+continue;+}++rbit=propval[0];+if(rbit>=rnum){+pr_debug("%s: bit position of %s exceeds resources\n",+__func__,child->full_name);+continue;+}++cg_pclk_name=of_clk_get_parent_name(child,0);+if(!pclk_name)+cg_pclk_name=pclk_name;++if(of_property_read_string(child,"clock-output-names",+&cg_name)){+unsignedintnlen=4+16+strlen(child->name);+char*name=kzalloc(nlen+1,GFP_KERNEL);+if(!name)+continue;+snprintf(name,nlen,"%u@%llx.%s",rbit,+(unsignedlonglong)addr,child->name);+cg_name=name;+}++pr_debug(" create clock gate: %s\n",cg_name);++cg=clk_register_gate(NULL,cg_name,cg_pclk_name,0,+base,rbit,propval[1],lockp);+if(cg)+of_clk_add_provider(child,of_clk_src_simple_get,cg);+}+}+#endif
--
1.7.10
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Attached Message Part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120712/397fe449/attachment.ksh>
From: Rob Herring <hidden> Date: 2012-07-12 12:14:09
On 07/12/2012 02:15 AM, Sebastian Hesselbarth wrote:
quoted hunk
As Rob's clock binding support patch is now up on clk-next, I'd like to
draw attention on this patch again.
--
This patch adds support for using clock gates (clk-gate) from DT based
on Rob Herrings DT clk binding support for 3.6.
It adds a helper function to clk-gate to allocate all resources required by
a set of individual clock gates, i.e. register base address and lock. Each
clock gate is described as a child of the clock-gating-control in DT and
also created by the helper function.
Signed-off-by: Sebastian Hesselbarth <redacted>
Cc: Grant Likely <redacted>
Cc: Rob Herring <redacted>
Cc: Rob Landley <redacted>
Cc: Mike Turquette <redacted>
Cc: devicetree-discuss at lists.ozlabs.org
Cc: linux-doc at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
.../bindings/clock/clock-gating-control.txt | 80
+++++++++++++++++++
drivers/clk/clk-gate.c | 84
++++++++++++++++++++
include/linux/clk-provider.h | 2 +
3 files changed, 166 insertions(+)
create mode 100644
Documentation/devicetree/bindings/clock/clock-gating-control.txt
diff --git
a/Documentation/devicetree/bindings/clock/clock-gating-control.txt
b/Documentation/devicetree/bindings/clock/clock-gating-control.txt
new file mode 100644
index 0000000..05f5728
@@ -0,0 +1,80 @@+Binding for simple clock gating control based on clock gate register
with one
+bit per clock gate. This is a clock consumer and also a clock provider
for a
+set of gated clocks that are described as children of this node. Each
clock gate
+is described by a bit number and polarity to control the gate.
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+==Clock gating control==
+
+Required properties:
+- compatible : shall be "clock-gating-control".
+- reg : should contain the register physical address and length for
+ the clock gating control.
+- clocks : shared parent clock for all gated clocks.
+- #clock-cells : from common clock binding; shall be set to 0.
+- #address-cells : number of cells required to describe a clock gate;
+ should be <2>.
+- #size-cells : should be zero.
+
+Each individual clock gate bit is described as a child of the
+corresponding gating control register with the following properties.
+
+Required child properties:
+- reg : should contain the individual bit and polarity to control
+ the clock gate. A polarity of 0 means that by setting the
+ bit to 1 the clock passes through the clock gate while
+ setting the bit to 0 disables the clock. Any other value
+ for polarity inverts the meaning of the control bit.
This is a bit of overloading reg to specify the polarity.
+
+Optional child properties:
+- clocks : overrides the shared parent clock for this clock gate
+ by the clock passed in this property.
+- clock-output-names : from common clock binding; allows to set
+ a specific name for the gated clock output.
+
+==Example==
+
+ /* fixed root clock */
+ osc: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <166666667>;
+ };
+
+ /* sata peripheral clock */
+ sata_clk: ext-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ /* register-based clock gating control */
+ gating-control at f10d0038 {
+ compatible = "clock-gating-control";
+ reg = <0xf10d0038 0x4>;
+ clocks = <&osc>;
+ #clock-cells = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /* USB0 clock gate on register bit 0 with inverted polarity */
+ cg_usb0: clockgate at 0 {
+ reg = <0 1>; /* register bit 0, inverted polarity */
+ };
+
+ /* PCIe0 clock gate on register bit 1 with normal polarity
+ * and named output clock */
+ cg_pcie0: clockgate at 1 {
+ reg = <1 0>; /* register bit 1, normal polarity */
+ clock-output-names = "pcie0_clk";
+ };
+
+ /* SATA clock gate with different parent clock */
+ cg_sata: clockgate at 3 {
+ reg = <3 0>; /* register bit 3, normal polarity */
+ clocks = <&sata_clk>;
+ };
I'm not sure I like the node per bit. What about a bit mask for valid
bits and polarities. Then add a clock cell to specify the bit or index.
i.MX has 2-bit enable fields for its leaf clocks, so how and if you
would support that is something to think about.
Rob
From: Sebastian Hesselbarh <hidden> Date: 2012-07-12 13:08:35
On 07/12/2012 02:14 PM, Rob Herring wrote:
quoted
+Required child properties:
+- reg : should contain the individual bit and polarity to control
+ the clock gate. A polarity of 0 means that by setting the
+ bit to 1 the clock passes through the clock gate while
+ setting the bit to 0 disables the clock. Any other value
+ for polarity inverts the meaning of the control bit.
This is a bit of overloading reg to specify the polarity.
Well, yes it is overloading but still matches reg somehow, as the
extra information is required to access the resource. But I agree,
expecially wrt more-than-one-bit clk-gate (see below).
quoted
+ /* SATA clock gate with different parent clock */
+ cg_sata: clockgate at 3 {
+ reg =<3 0>; /* register bit 3, normal polarity */
+ clocks =<&sata_clk>;
+ };
I'm not sure I like the node per bit. What about a bit mask for valid
bits and polarities. Then add a clock cell to specify the bit or index.
i.MX has 2-bit enable fields for its leaf clocks, so how and if you
would support that is something to think about.
Yeah, I thought of "what if the clk_gate needs to be enabled with more
than 1 bit" already. But this is a short-comming of the current clk-gate
implementation.
Just to get it right, i.MX requires to set more than one bit to change
the state of the gate for one leaf clock?
If this is true, that would require a change of the generic clk-gate
anyway.
I had a look at pinctrl-bindings.txt maybe this is the way to go for
clock gating control, too. That would require clk-gate to handle an
'active' and 'gated' state and leave it to a clock gate control to
actually set the required bits in any registers. This would allow
other special implementations of clock gating controllers to reuse
clk-gate DT description. Additionally, there could be a
simple-clock-gating-control that can set states by reg address and
for each controlled gate a mask, enable value, and disable value.
Sebastian
From: Rob Herring <hidden> Date: 2012-07-13 03:20:03
On 07/12/2012 08:08 AM, Sebastian Hesselbarh wrote:
On 07/12/2012 02:14 PM, Rob Herring wrote:
quoted
quoted
+Required child properties:
+- reg : should contain the individual bit and polarity to control
+ the clock gate. A polarity of 0 means that by setting the
+ bit to 1 the clock passes through the clock gate while
+ setting the bit to 0 disables the clock. Any other value
+ for polarity inverts the meaning of the control bit.
This is a bit of overloading reg to specify the polarity.
Well, yes it is overloading but still matches reg somehow, as the
extra information is required to access the resource. But I agree,
expecially wrt more-than-one-bit clk-gate (see below).
You can define your own property names.
quoted
quoted
+ /* SATA clock gate with different parent clock */
+ cg_sata: clockgate at 3 {
+ reg =<3 0>; /* register bit 3, normal polarity */
+ clocks =<&sata_clk>;
+ };
I'm not sure I like the node per bit. What about a bit mask for valid
bits and polarities. Then add a clock cell to specify the bit or index.
i.MX has 2-bit enable fields for its leaf clocks, so how and if you
would support that is something to think about.
Yeah, I thought of "what if the clk_gate needs to be enabled with more
than 1 bit" already. But this is a short-comming of the current clk-gate
implementation.
What's implemented in Linux should not define the binding. The binding
should describe the hardware.
Just to get it right, i.MX requires to set more than one bit to change
the state of the gate for one leaf clock?
It's basically ON, OFF, and "ON in run/OFF in wfi".
Perhaps the iMX case is unique enough we don't try to make it use a
common binding.
If this is true, that would require a change of the generic clk-gate
anyway.
True, but not your problem to implement. A binding doesn't necessarily
mean there is a full Linux implementation. We just don't want to create
something only to find others need something completely different.
Rob
I had a look at pinctrl-bindings.txt maybe this is the way to go for
clock gating control, too. That would require clk-gate to handle an
'active' and 'gated' state and leave it to a clock gate control to
actually set the required bits in any registers. This would allow
other special implementations of clock gating controllers to reuse
clk-gate DT description. Additionally, there could be a
simple-clock-gating-control that can set states by reg address and
for each controlled gate a mask, enable value, and disable value.
Sebastian
From: Sebastian Hesselbarh <hidden> Date: 2012-07-13 09:42:31
On 07/13/2012 05:19 AM, Rob Herring wrote:
What's implemented in Linux should not define the binding. The binding
should describe the hardware.
[...]
True, but not your problem to implement. A binding doesn't necessarily
mean there is a full Linux implementation. We just don't want to create
something only to find others need something completely different.
Ok, what about a DT describing the following for a simple register-based
clock gating controller and the corresponding gated-clock independent of
the controller. I am sure there are a bunch of SoCs out there that
control their clock gates by writing some bits to a register. If that
DT description matches your expectations, I ll prepare patches with
documentation and implementation for common clock framework.
Sebastian
--
/* Simple clock gating controller based on bitmasks and register */
cgc: clock-gating-control at f1000000 {
compatible = "clock-gating-control-register";
reg = <0xf1000000 0x4>;
/* Clock gating control with one bit at bit position 0
enable with (1<<0), disable with (0<<0) */
cgctrl_usb0: cgc_usb0 {
clock-gating-control,shift = <0>;
clock-gating-control,mask = <1>;
clock-gating-control,enable = <1>;
clock-gating-control,disable = <0>;
};
/* Clock gating control with two bits at bit position 1-2
enable with (2<<1), disable with (0<<1) */
cgctrl_sata: cgc_sata {
clock-gating-control,shift = <1>;
clock-gating-control,mask = <3>;
clock-gating-control,enable = <2>;
clock-gating-control,disable = <0>;
};
};
/* Generic clock gate description that can be used with
any clock gating controller */
cg_usb0: clockgate at 0 {
compatible = "gated-clock";
#clock-cells = <0>;
clocks = <&osc>;
clock-gate-control = <&cgctrl_usb0>;
};
From: Rob Herring <hidden> Date: 2012-07-14 05:00:08
On 07/13/2012 04:42 AM, Sebastian Hesselbarh wrote:
On 07/13/2012 05:19 AM, Rob Herring wrote:
quoted
What's implemented in Linux should not define the binding. The binding
should describe the hardware.
[...]
True, but not your problem to implement. A binding doesn't necessarily
mean there is a full Linux implementation. We just don't want to create
something only to find others need something completely different.
Ok, what about a DT describing the following for a simple register-based
clock gating controller and the corresponding gated-clock independent of
the controller. I am sure there are a bunch of SoCs out there that
control their clock gates by writing some bits to a register. If that
DT description matches your expectations, I ll prepare patches with
documentation and implementation for common clock framework.
Clock gates are just 1 part. There's muxes, dividers, plls, etc. I'm not
convinced that it makes sense to define clocks at this level. For
complex chips, I think just defining the chips clock controller module
as a single node with lots of clock outputs. The primary need is to
describe board specific changes not SOC level clock tree. Much of it is
static and generally only a few clocks may change config board to board.
Sebastian
--
/* Simple clock gating controller based on bitmasks and register */
cgc: clock-gating-control at f1000000 {
compatible = "clock-gating-control-register";
reg = <0xf1000000 0x4>;
/* Clock gating control with one bit at bit position 0
enable with (1<<0), disable with (0<<0) */
cgctrl_usb0: cgc_usb0 {
clock-gating-control,shift = <0>;
clock-gating-control,mask = <1>;
clock-gating-control,enable = <1>;
clock-gating-control,disable = <0>;
};
/* Clock gating control with two bits at bit position 1-2
enable with (2<<1), disable with (0<<1) */
cgctrl_sata: cgc_sata {
clock-gating-control,shift = <1>;
clock-gating-control,mask = <3>;
clock-gating-control,enable = <2>;
clock-gating-control,disable = <0>;
};
};
/* Generic clock gate description that can be used with
any clock gating controller */
cg_usb0: clockgate at 0 {
compatible = "gated-clock";
#clock-cells = <0>;
clocks = <&osc>;
clock-gate-control = <&cgctrl_usb0>;
};
From: Rob Landley <hidden> Date: 2012-07-16 03:41:15
I believe clock anything is Thomas Gleixner, just making sure he's seen
it...
Rob
On 07/13/2012 04:42 AM, Sebastian Hesselbarh wrote:
On 07/13/2012 05:19 AM, Rob Herring wrote:
quoted
What's implemented in Linux should not define the binding. The binding
should describe the hardware.
[...]
True, but not your problem to implement. A binding doesn't necessarily
mean there is a full Linux implementation. We just don't want to create
something only to find others need something completely different.
Ok, what about a DT describing the following for a simple register-based
clock gating controller and the corresponding gated-clock independent of
the controller. I am sure there are a bunch of SoCs out there that
control their clock gates by writing some bits to a register. If that
DT description matches your expectations, I ll prepare patches with
documentation and implementation for common clock framework.
Sebastian
--
/* Simple clock gating controller based on bitmasks and register */
cgc: clock-gating-control at f1000000 {
compatible = "clock-gating-control-register";
reg = <0xf1000000 0x4>;
/* Clock gating control with one bit at bit position 0
enable with (1<<0), disable with (0<<0) */
cgctrl_usb0: cgc_usb0 {
clock-gating-control,shift = <0>;
clock-gating-control,mask = <1>;
clock-gating-control,enable = <1>;
clock-gating-control,disable = <0>;
};
/* Clock gating control with two bits at bit position 1-2
enable with (2<<1), disable with (0<<1) */
cgctrl_sata: cgc_sata {
clock-gating-control,shift = <1>;
clock-gating-control,mask = <3>;
clock-gating-control,enable = <2>;
clock-gating-control,disable = <0>;
};
};
/* Generic clock gate description that can be used with
any clock gating controller */
cg_usb0: clockgate at 0 {
compatible = "gated-clock";
#clock-cells = <0>;
clocks = <&osc>;
clock-gate-control = <&cgctrl_usb0>;
};
--
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation. Pick one.