ARM: OMAP3+: Add device-tree support for timers
Subsystems (5)
cover ARM: OMAP3+: Add device-tree support for timers
This series adds device-tree support for the timers on OMAP3/4 devices. Once everyone is happy with the implementation I can add support for OMAP2/5 devices too.
Testing:
- I have tested the all the timers (not used by the kernel as sys-timers) on both OMAP3430 Beagle and OMAP4460 Panda with/without device-tree with this series.
- The testing includes
- Configuring, starting a timer and checking the counter value is incrementing.
- Testing timer overflow interrupt when timer expires.
- Using different clock sources to operate the timer with.
- Using DT to provide resource information for IRQ and memory by removing Benoit's intention "HACK" in commit a4f6cdb0 (ARM: OMAP:
omap_device: Add omap_device_[alloc|delete] for DT integration)
Jon Hunter (4):
arm/dts: OMAP: Add timer nodes
ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
ARM: OMAP4: Add timer clock aliases for device-tree
ARM: OMAP: Add DT support for timer driver
.../devicetree/bindings/arm/omap/timer.txt | 34 +++++++ arch/arm/boot/dts/omap3.dtsi | 104 ++++++++++++++++++++ arch/arm/boot/dts/omap4.dtsi | 93 +++++++++++++++++ arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/clock44xx_data.c | 12 +++ arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 40 ++++++++ arch/arm/plat-omap/dmtimer.c | 32 ++++-- 8 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt
Signature · 1 line
1.7.9.5
RFC 1/4 arm/dts: OMAP: Add timer nodes
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.
Add documentation for timer properties specific to OMAP.
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function of_alias_get_id() to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.
--- .../devicetree/bindings/arm/omap/timer.txt | 34 +++++++ arch/arm/boot/dts/omap3.dtsi | 104 ++++++++++++++++++++ arch/arm/boot/dts/omap4.dtsi | 93 +++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txt
Documentation/devicetree/bindings/arm/omap/timer.txt new file +34 -0
@@ -0,0 +1,34 @@ +OMAP Timer controller bindings + +Required properties: +- compatible: + - "ti,omap3-timer" for OMAP3+ controllers +- reg: Contains timer register address range (base address and length) +- interrupts: Contains the interrupt information for the timer. The format is + being dependent on which interrupt controller the OMAP device uses. + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the timer: + "timer<X>", <X> being the 1-based instance number from the HW spec +- ti,timer-alwon: Indicates the timer is in an alway-on power domain. +- ti,timer-pwm: Indicates the timer supports can generate PWM output. +- ti,timer-secure: Indicates the timer is reserved on a secure OMAP device and + therefore cannot be used by the kernel. + +Note: Each timer should have an alias correctly numbered in "aliases" node. The + alias is used to identify the timer instance in the driver. + +Example: + +aliases { + timer12 = &timer12; +}; + +timer12: timer at 48304000 { + compatible = "ti,omap3-timer"; + reg = <0x48304000 0xfff>; + interrupts = <95>; + ti,hwmods = "timer12" + ti,timer-alwon; + ti,timer-secure; +};
arch/arm/boot/dts/omap3.dtsi +104 -0
121 lines not on this page · raw message
arch/arm/boot/dts/omap4.dtsi +93 -0
104 lines not on this page · raw message
Signature · 1 line
1.7.9.5
RFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Rob
Quoted 288 lines
Cc Benoit Cousson <[email protected]>Signed-off-by Jon Hunter <[email protected]>--- .../devicetree/bindings/arm/omap/timer.txt | 34 +++++++ arch/arm/boot/dts/omap3.dtsi | 104 ++++++++++++++++++++ arch/arm/boot/dts/omap4.dtsi | 93 +++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/timer.txtDocumentation/devicetree/bindings/arm/omap/timer.txt new file +34
-0@@ -0,0 +1,34 @@ +OMAP Timer controller bindings + +Required properties: +- compatible: + - "ti,omap3-timer" for OMAP3+ controllers +- reg: Contains timer register address range (base address and length) +- interrupts: Contains the interrupt information for the timer. The format is + being dependent on which interrupt controller the OMAP device uses. + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the timer: + "timer<X>", <X> being the 1-based instance number from the HW spec +- ti,timer-alwon: Indicates the timer is in an alway-on power domain. +- ti,timer-pwm: Indicates the timer supports can generate PWM output. +- ti,timer-secure: Indicates the timer is reserved on a secure OMAP device and + therefore cannot be used by the kernel. + +Note: Each timer should have an alias correctly numbered in "aliases" node. The + alias is used to identify the timer instance in the driver. + +Example: + +aliases { + timer12 = &timer12; +}; + +timer12: timer at 48304000 { + compatible = "ti,omap3-timer"; + reg = <0x48304000 0xfff>; + interrupts = <95>; + ti,hwmods = "timer12" + ti,timer-alwon; + ti,timer-secure; +};arch/arm/boot/dts/omap3.dtsi +104
-0@@ -12,12 +12,25 @@ / { compatible = "ti,omap3430", "ti,omap3"; + interrupt-parent = <&intc>; aliases { serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; serial3 = &uart4; + timer1 = &timer1; + timer2 = &timer2; + timer3 = &timer3; + timer4 = &timer4; + timer5 = &timer5; + timer6 = &timer6; + timer7 = &timer7; + timer8 = &timer8; + timer9 = &timer9; + timer10 = &timer10; + timer11 = &timer11; + timer12 = &timer12; }; cpus {@@ -220,5 +233,96 @@ compatible = "ti,omap3-wdt"; ti,hwmods = "wd_timer2"; }; + + timer1: timer at 48318000 { + compatible = "ti,omap3-timer"; + reg = <0x48318000 0xfff>; + interrupts = <37>; + ti,hwmods = "timer1"; + ti,timer-alwon; + }; + + timer2: timer at 49032000 { + compatible = "ti,omap3-timer"; + reg = <0x49032000 0xfff>; + interrupts = <38>; + ti,hwmods = "timer2"; + }; + + timer3: timer at 49034000 { + compatible = "ti,omap3-timer"; + reg = <0x49034000 0xfff>; + interrupts = <39>; + ti,hwmods = "timer3"; + }; + + timer4: timer at 49036000 { + compatible = "ti,omap3-timer"; + reg = <0x49036000 0xfff>; + interrupts = <40>; + ti,hwmods = "timer4"; + }; + + timer5: timer at 49038000 { + compatible = "ti,omap3-timer"; + reg = <0x49038000 0xfff>; + interrupts = <41>; + ti,hwmods = "timer5"; + }; + + timer6: timer at 4903a000 { + compatible = "ti,omap3-timer"; + reg = <0x4903a000 0xfff>; + interrupts = <42>; + ti,hwmods = "timer6"; + }; + + timer7: timer at 4903c000 { + compatible = "ti,omap3-timer"; + reg = <0x4903c000 0xfff>; + interrupts = <43>; + ti,hwmods = "timer7"; + }; + + timer8: timer at 4903e000 { + compatible = "ti,omap3-timer"; + reg = <0x4903e000 0xfff>; + interrupts = <44>; + ti,hwmods = "timer8"; + ti,timer-pwm; + }; + + timer9: timer at 49040000 { + compatible = "ti,omap3-timer"; + reg = <0x49040000 0xfff>; + interrupts = <45>; + ti,hwmods = "timer9"; + ti,timer-pwm; + }; + + timer10: timer at 48086000 { + compatible = "ti,omap3-timer"; + reg = <0x48086000 0xfff>; + interrupts = <46>; + ti,hwmods = "timer10"; + ti,timer-pwm; + }; + + timer11: timer at 48088000 { + compatible = "ti,omap3-timer"; + reg = <0x48088000 0xfff>; + interrupts = <47>; + ti,hwmods = "timer11"; + ti,timer-pwm; + }; + + timer12: timer at 48304000 { + compatible = "ti,omap3-timer"; + reg = <0x48304000 0xfff>; + interrupts = <95>; + ti,hwmods = "timer12"; + ti,timer-alwon; + ti,timer-secure; + }; }; };arch/arm/boot/dts/omap4.dtsi +93
-0@@ -25,6 +25,17 @@ serial1 = &uart2; serial2 = &uart3; serial3 = &uart4; + timer1 = &timer1; + timer2 = &timer2; + timer3 = &timer3; + timer4 = &timer4; + timer5 = &timer5; + timer6 = &timer6; + timer7 = &timer7; + timer8 = &timer8; + timer9 = &timer9; + timer10 = &timer10; + timer11 = &timer11; }; cpus {@@ -295,5 +306,87 @@ interrupt-parent = <&gic>; ti,hwmods = "dmic"; }; + + timer1: timer at 4a318000 { + compatible = "ti,omap3-timer"; + reg = <0x4a318000 0x7f>; + interrupts = <0 37 0x4>; + ti,hwmods = "timer1"; + ti,timer-alwon; + }; + + timer2: timer at 48032000 { + compatible = "ti,omap3-timer"; + reg = <0x48032000 0x7f>; + interrupts = <0 38 0x4>; + ti,hwmods = "timer2"; + }; + + timer3: timer at 48034000 { + compatible = "ti,omap3-timer"; + reg = <0x48034000 0x7f>; + interrupts = <0 39 0x4>; + ti,hwmods = "timer3"; + }; + + timer4: timer at 48036000 { + compatible = "ti,omap3-timer"; + reg = <0x48036000 0x7f>; + interrupts = <0 40 0x4>; + ti,hwmods = "timer4"; + }; + + timer5: timer at 49038000 { + compatible = "ti,omap3-timer"; + reg = <0x49038000 0x7f>; + interrupts = <0 41 0x4>; + ti,hwmods = "timer5"; + }; + + timer6: timer at 4903a000 { + compatible = "ti,omap3-timer"; + reg = <0x4903a000 0x7f>; + interrupts = <0 42 0x4>; + ti,hwmods = "timer6"; + }; + + timer7: timer at 4903c000 { + compatible = "ti,omap3-timer"; + reg = <0x4903c000 0x7f>; + interrupts = <0 43 0x4>; + ti,hwmods = "timer7"; + }; + + timer8: timer at 4903e000 { + compatible = "ti,omap3-timer"; + reg = <0x4903e000 0x7f>; + interrupts = <0 44 0x4>; + ti,hwmods = "timer8"; + ti,timer-pwm; + }; + + timer9: timer at 4803e000 { + compatible = "ti,omap3-timer"; + reg = <0x4803e000 0x7f>; + interrupts = <0 45 0x4>; + ti,hwmods = "timer9"; + ti,timer-pwm; + }; + + timer10: timer at 48086000 { + compatible = "ti,omap3-timer"; + reg = <0x48086000 0x7f>; + interrupts = <0 46 0x4>; + ti,hwmods = "timer10"; + ti,timer-pwm; + }; + + timer11: timer at 48088000 { + compatible = "ti,omap3-timer"; + reg = <0x48088000 0x7f>; + interrupts = <0 47 0x4>; + ti,hwmods = "timer11"; + ti,timer-pwm; + }; }; };
A message that is not in the archive (sent off-list or not yet received): [email protected]
Mis?use of aliases
Quoted 3 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed.
This brings up an issue that I've been meaning to comment on.
The use of phandle-valued properties in the aliases node causes real OFW implementations some amount of heartburn. The Open Firmware standard says that the properties in /aliases are string-valued. That's important, because aliases are shorthand for fragments of full device specifiers (pathnames that can include arguments to nodes). Phandles can point to nodes, but can't be relative, and can't encode per-node-component arguments.
For binding a Linux unit number to a device node, I would prefer to decorate the node with a property like "linux,unit#", instead of breaking the standard semantics of /aliases.
Mitch
Mis?use of aliases
Quoted 6 lines · Mitch Bradley
Quoted 3 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed.
This brings up an issue that I've been meaning to comment on.
Quoted 7 lines
The use of phandle-valued properties in the aliases node causes real OFW implementations some amount of heartburn. The Open Firmware standard says that the properties in /aliases are string-valued. That's important, because aliases are shorthand for fragments of full device specifiers (pathnames that can include arguments to nodes). Phandles can point to nodes, but can't be relative, and can't encode per-node-component arguments.
Um, so, properties in /aliases should not have phandle values, flat tree or otherwise. Has this been seen in the wild, or are you being misled by the fact that dtc's reference-to-phandle and reference-to-path syntax is very similar:
prop = <&fred>; Will generate a phandle valued property, but prop = &fred;
Will generate a string (path) valued property.
Quoted 3 lines
For binding a Linux unit number to a device node, I would prefer to decorate the node with a property like "linux,unit#", instead of breaking the standard semantics of /aliases.
I don't see how using aliases for unit numbering (inherently) breaks the semantics of /aliases. If phandle valued properties are being used that is wrong, but it's not necessary for the unit numbering anyway.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Mis?use of aliases
Quoted 15 lines · David Gibson
Quoted 6 lines · Mitch Bradley
Quoted 3 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed.
This brings up an issue that I've been meaning to comment on.
Quoted 7 lines
The use of phandle-valued properties in the aliases node causes real OFW implementations some amount of heartburn. The Open Firmware standard says that the properties in /aliases are string-valued. That's important, because aliases are shorthand for fragments of full device specifiers (pathnames that can include arguments to nodes). Phandles can point to nodes, but can't be relative, and can't encode per-node-component arguments.
Quoted 4 lines
Um, so, properties in /aliases should not have phandle values, flat tree or otherwise. Has this been seen in the wild, or are you being misled by the fact that dtc's reference-to-phandle and reference-to-path syntax is very similar:
Yes, I was indeed being misled. Thanks for the clarification. The "&fred" syntax is present in the .dts files that I have looked at.
Quoted 6 lines
prop = <&fred>; Will generate a phandle valued property, but prop = &fred;Will generate a string (path) valued property.
Quoted 8 lines
Quoted 3 lines
For binding a Linux unit number to a device node, I would prefer to decorate the node with a property like "linux,unit#", instead of breaking the standard semantics of /aliases.
I don't see how using aliases for unit numbering (inherently) breaks the semantics of /aliases. If phandle valued properties are being used that is wrong, but it's not necessary for the unit numbering anyway.
I agree, the use of string-valued /aliases is not a semantic problem. That said, I still think that decorating individual nodes is a better approach, for locality reasons. But, now that my misunderstanding has been cleared up, it's a mild preference instead of "heartburn".
For historical reference: The original use of /aliases was as a component of pathname resolution, which is a "global" function. In that usage model, a given alias does not necessarily refer specifically to exactly one node, so "localizing" an alias inside a node doesn't work.
The new usage for binding to a Linux name could be localized. My general preference is to localize whenever possible. But, again, breaking that rule in this case is not a huge problem.
Thanks again for zeroing in on my mistake.
Mitch
Mis?use of aliases
Quoted 16 lines · Mitch Bradley
Quoted 15 lines · David Gibson
Quoted 13 lines · Mitch Bradley
Quoted 3 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed.
This brings up an issue that I've been meaning to comment on.
The use of phandle-valued properties in the aliases node causes real OFW implementations some amount of heartburn. The Open Firmware standard says that the properties in /aliases are string-valued. That's important, because aliases are shorthand for fragments of full device specifiers (pathnames that can include arguments to nodes). Phandles can point to nodes, but can't be relative, and can't encode per-node-component arguments.
Quoted 7 lines
Quoted 4 lines
Um, so, properties in /aliases should not have phandle values, flat tree or otherwise. Has this been seen in the wild, or are you being misled by the fact that dtc's reference-to-phandle and reference-to-path syntax is very similar:
Yes, I was indeed being misled. Thanks for the clarification. The "&fred" syntax is present in the .dts files that I have looked at.
Right, it's all about the context. &label is always a reference to another node, but in cell context < ... > that's expanded as a phandle, in bare context it's expanded as a path.
Quoted 14 lines
Quoted 5 lines
prop = <&fred>; Will generate a phandle valued property, but prop = &fred;Will generate a string (path) valued property.
Quoted 8 lines
Quoted 3 lines
For binding a Linux unit number to a device node, I would prefer to decorate the node with a property like "linux,unit#", instead of breaking the standard semantics of /aliases.
I don't see how using aliases for unit numbering (inherently) breaks the semantics of /aliases. If phandle valued properties are being used that is wrong, but it's not necessary for the unit numbering anyway.
Quoted 4 lines
I agree, the use of string-valued /aliases is not a semantic problem. That said, I still think that decorating individual nodes is a better approach, for locality reasons. But, now that my misunderstanding has been cleared up, it's a mild preference instead of "heartburn".
So, I think aliases was suggested for this sort of numbering precisely because it _isn't_ local. Particularly when numbering similar devices across unrelated busses, the ordering more or less has to be a global platform convention, and may not be derived from - or even contradict
- local numbering conventions from individual busses or components.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Paul Walmsley
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
In reply to Rob HerringHi
Quoted 6 lines · Rob Herring
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Some GPTIMER blocks have input and output signals that can be routed to external package balls. So it's possible that some application may need to request a specific timer ID, since that timer would be connected to a specific off-chip device.
- Paul
RFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 11 lines · Paul Walmsley
Hi
Quoted 6 lines · Rob Herring
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Quoted 4 lines
Some GPTIMER blocks have input and output signals that can be routed to external package balls. So it's possible that some application may need to request a specific timer ID, since that timer would be connected to a specific off-chip device.
Yes, I understand that. So you should be describing which ones have i/o and what they are connected to. The PWM binding is probably a starting point.
Rob
Quoted 4 lines
- Paul
Paul Walmsley
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
Hi Rob,
thanks for your response.
Quoted 10 lines · Rob Herring
Quoted 9 lines · Paul Walmsley
Quoted 6 lines · Rob Herring
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Quoted 6 lines
Quoted 4 lines
Some GPTIMER blocks have input and output signals that can be routed to external package balls. So it's possible that some application may need to request a specific timer ID, since that timer would be connected to a specific off-chip device.
Yes, I understand that. So you
(just to clarify, these are Jon's patches)
Quoted 1 line
should be describing which ones have i/o and what they are connected to.
Right, agreed.
Quoted 1 line
The PWM binding is probably a starting point.
My point, perhaps unclear, was about the aliases. Do you have a different approach in mind that applications should use, other than requesting a specific timer by ID?
- Paul
Paul Walmsley
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
Hi Rob,
Quoted 3 lines · Paul Walmsley
My point, perhaps unclear, was about the aliases. Do you have a different approach in mind that applications should use, other than requesting a specific timer by ID?
Please disregard this question, I think I'm misunderstanding something from a previous mail...
- Paul
RFC 1/4 arm/dts: OMAP: Add timer nodes
In reply to Rob HerringHi Rob,
Quoted 14 lines · Rob Herring
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.
Quoted 6 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Thanks for the feedback. What you suggest could definitely work for most timers. The only item that I would need to resolve here is the handling of system timers (ie. those used for clockevents and clocksource). These system timers (for OMAP) are reserved during early boot based upon the timer ID today and so this is before the actual main timer driver has been probed and all the attributes of the timers has been read for device-tree.
One thought would be to move the reservation of the system timers out of the kernel and into device-tree itself. Then we query device tree on start-up to see which we should use. I am wondering if this could be a better use of alias? For example, say I want to use timer1 as my clockevent timer and so I could have an alias of ...
alias {
clockevent_timer = &timer1;
}However, I am not sure if this is even correct, because there does not appear to be an API to search the aliases by name and return the phandle, just of_alias_get_id(). Alternatively, I could add another property called "ti,timer-clockevent" that is populated for the timer used as the clockevent timer.
Tony, Tarun,
How would you feel on replacing omap_dmtimer_request_specific(int id) with say omap_dm_timer_request_by_cap(int cap)?
I was thinking of changing the name so that it is clear that the API has changed. The "int cap" passed to the above function would be an OR of the appropriate the capabilities flags we have in dmtimer.h ...
/* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_ALWON 0x40000000 #define OMAP_TIMER_HAS_PWM 0x20000000
...
Cheers
Jon
Tony Lindgren
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 11 lines · Jon Hunter
On 07/13/2012 09:15 PM, Rob Herring wrote:
Tony, Tarun,
How would you feel on replacing
omap_dmtimer_request_specific(int id)with sayomap_dm_timer_request_by_cap(int cap)?I was thinking of changing the name so that it is clear that the API has changed. The "int cap" passed to the above function would be an OR of the appropriate the capabilities flags we have in
dmtimer.h...
Quoted 5 lines
/* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_ALWON 0x40000000 #define OMAP_TIMER_HAS_PWM 0x20000000...
That may break coprocessors where the firmware may expect a hardcoded specific timer.. So at least that should be checked before the change. If the specific timer is still needed for some firmware, it's best to add a separate function for the capabilities.
Also, I believe it's up to the firmware running in secure mode to select the secure timers. So unless there's some way to query which timers are claimed by the secure mode, that too needs to be passed via DT.
Regards,
Tony
RFC 1/4 arm/dts: OMAP: Add timer nodes
Hi Tony,
Quoted 18 lines · Tony Lindgren
Quoted 11 lines · Jon Hunter
On 07/13/2012 09:15 PM, Rob Herring wrote:
Tony, Tarun,
How would you feel on replacing
omap_dmtimer_request_specific(int id)with sayomap_dm_timer_request_by_cap(int cap)?I was thinking of changing the name so that it is clear that the API has changed. The "int cap" passed to the above function would be an OR of the appropriate the capabilities flags we have in
dmtimer.h...Quoted 5 lines
/* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_ALWON 0x40000000 #define OMAP_TIMER_HAS_PWM 0x20000000...
Quoted 4 lines
That may break coprocessors where the firmware may expect a hardcoded specific timer.. So at least that should be checked before the change. If the specific timer is still needed for some firmware, it's best to add a separate function for the capabilities.
I have seen that timers are used by the GPU and Ducati. Maybe I can check with the authors to see if we can get them to request by capability instead. If we can't then I need to figure out a way to resolve the timer ID when using DT. Per Rob's comments using alias is not the intended use. An alternative would be to extract the ID from the hwmod name, but was not sure if that would be appropriate either :-(
Quoted 4 lines
Also, I believe it's up to the firmware running in secure mode to select the secure timers. So unless there's some way to query which timers are claimed by the secure mode, that too needs to be passed via DT.
Yes, that is handled by patch 2/4. If we are on a secure device, then will not register any timers marked with the "ti,timer-secure" property.
Cheers
Jon
RFC 1/4 arm/dts: OMAP: Add timer nodes
In reply to Jon HunterHi Rob,
Quoted 42 lines · Jon Hunter
Hi Rob,
Quoted 14 lines · Rob Herring
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.Quoted 6 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Thanks for the feedback. What you suggest could definitely work for most timers. The only item that I would need to resolve here is the handling of system timers (ie. those used for clockevents and clocksource). These system timers (for OMAP) are reserved during early boot based upon the timer ID today and so this is before the actual main timer driver has been probed and all the attributes of the timers has been read for device-tree.
One thought would be to move the reservation of the system timers out of the kernel and into device-tree itself. Then we query device tree on start-up to see which we should use. I am wondering if this could be a better use of alias? For example, say I want to use timer1 as my clockevent timer and so I could have an alias of ...
alias { clockevent_timer = &timer1; }
Quoted 5 lines
However, I am not sure if this is even correct, because there does not appear to be an API to search the aliases by name and return the phandle, just
of_alias_get_id(). Alternatively, I could add another property called "ti,timer-clockevent" that is populated for the timer used as the clockevent timer.
Do you have any inputs on the above? Does it make sense to reserve timer resources for kernel system timers in device-tree?
Cheers
Jon
RFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 45 lines · Jon Hunter
Hi Rob,
Quoted 42 lines · Jon Hunter
Hi Rob,
Quoted 14 lines · Rob Herring
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.Quoted 6 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Thanks for the feedback. What you suggest could definitely work for most timers. The only item that I would need to resolve here is the handling of system timers (ie. those used for clockevents and clocksource). These system timers (for OMAP) are reserved during early boot based upon the timer ID today and so this is before the actual main timer driver has been probed and all the attributes of the timers has been read for device-tree.
One thought would be to move the reservation of the system timers out of the kernel and into device-tree itself. Then we query device tree on start-up to see which we should use. I am wondering if this could be a better use of alias? For example, say I want to use timer1 as my clockevent timer and so I could have an alias of ...
alias { clockevent_timer = &timer1; }
Quoted 9 lines
Quoted 5 lines
However, I am not sure if this is even correct, because there does not appear to be an API to search the aliases by name and return the phandle, just
of_alias_get_id(). Alternatively, I could add another property called "ti,timer-clockevent" that is populated for the timer used as the clockevent timer.Do you have any inputs on the above? Does it make sense to reserve timer resources for kernel system timers in device-tree?
Hey Jon,
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Thanks,
Vaibhav
Quoted 7 lines
Cheers
Jon
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss at lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss
RFC 1/4 arm/dts: OMAP: Add timer nodes
Hi Vaibhav,
Quoted 58 lines · Vaibhav Hiremath
Quoted 45 lines · Jon Hunter
Hi Rob,
Quoted 42 lines · Jon Hunter
Hi Rob,
Quoted 14 lines · Rob Herring
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.Quoted 6 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Thanks for the feedback. What you suggest could definitely work for most timers. The only item that I would need to resolve here is the handling of system timers (ie. those used for clockevents and clocksource). These system timers (for OMAP) are reserved during early boot based upon the timer ID today and so this is before the actual main timer driver has been probed and all the attributes of the timers has been read for device-tree.
One thought would be to move the reservation of the system timers out of the kernel and into device-tree itself. Then we query device tree on start-up to see which we should use. I am wondering if this could be a better use of alias? For example, say I want to use timer1 as my clockevent timer and so I could have an alias of ...
alias { clockevent_timer = &timer1; }Quoted 9 lines
Quoted 5 lines
However, I am not sure if this is even correct, because there does not appear to be an API to search the aliases by name and return the phandle, just
of_alias_get_id(). Alternatively, I could add another property called "ti,timer-clockevent" that is populated for the timer used as the clockevent timer.Do you have any inputs on the above? Does it make sense to reserve timer resources for kernel system timers in device-tree?
Quoted 5 lines
Hey Jon,
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Sorry I have been out of the office. However, no update on this so far. I need to check with Tony if he has any preference for handling this. I will follow-up with him and keep you posted.
Cheers
Jon
Tony Lindgren
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 9 lines · Jon Hunter
Quoted 4 lines · Vaibhav Hiremath
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Sorry I have been out of the office. However, no update on this so far. I need to check with Tony if he has any preference for handling this. I will follow-up with him and keep you posted.
Jon please repost these without the RFC in the subject line assuming the pending comments have been addressed so people can ack them.
Regards,
Tony
RFC 1/4 arm/dts: OMAP: Add timer nodes
Hi Tony,
Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Jon Hunter
Quoted 4 lines · Vaibhav Hiremath
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Quoted 7 lines
Quoted 3 lines
Sorry I have been out of the office. However, no update on this so far. I need to check with Tony if he has any preference for handling this. I will follow-up with him and keep you posted.
Jon please repost these without the RFC in the subject line assuming the pending comments have been addressed so people can ack them.
I have been working on updating this series to request timer by their capabilities and avoid using a device ID altogether. In the updated series using device IDs to request a timer will still work as it does today, but not when you boot with DT. I have something working now that is booting fine on omap4 with and without DT [1]. However, I need to do more thorough testing of the timers in general, probably next week.
Once I have completed my testing I would like to post for review. However, since posting the original series I have been working on some needed timer fixes/clean-up which I posted this week [2] for review. Ideally I should rebase my DT timer work on my timer fixes series but wanted to see what you thought first.
Cheers
Jon
[1] https://github.com/jonhunter/linux/tree/dev-dt-timer
[2] http://marc.info/?l=linux-omap&m=134687188921835&w=2
Tony Lindgren
maintainerRFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 25 lines · Jon Hunter
Hi Tony,
Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Jon Hunter
Quoted 4 lines · Vaibhav Hiremath
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Quoted 7 lines
Quoted 3 lines
Sorry I have been out of the office. However, no update on this so far. I need to check with Tony if he has any preference for handling this. I will follow-up with him and keep you posted.
Jon please repost these without the RFC in the subject line assuming the pending comments have been addressed so people can ack them.
I have been working on updating this series to request timer by their capabilities and avoid using a device ID altogether. In the updated series using device IDs to request a timer will still work as it does today, but not when you boot with DT. I have something working now that is booting fine on omap4 with and without DT [1]. However, I need to do more thorough testing of the timers in general, probably next week.
Quoted 5 lines
Once I have completed my testing I would like to post for review. However, since posting the original series I have been working on some needed timer fixes/clean-up which I posted this week [2] for review. Ideally I should rebase my DT timer work on my timer fixes series but wanted to see what you thought first.
Yeah those all look good to me. Want to do a git branch against v3.6-rc4 for those once the comments are dealt with so I can pull it in for testing to start with?
Regards,
Tony
Quoted 5 lines
Cheers
Jon[1] https://github.com/jonhunter/linux/tree/dev-dt-timer
[2] http://marc.info/?l=linux-omap&m=134687188921835&w=2
RFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 32 lines · Tony Lindgren
Quoted 25 lines · Jon Hunter
Hi Tony,
Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Jon Hunter
Quoted 4 lines · Vaibhav Hiremath
Did we get conclude on this? I haven't got anything further on this thread, this may block baseport support for the new devices in omap2 family, like AM33xx and OMAP5.
Quoted 7 lines
Quoted 3 lines
Sorry I have been out of the office. However, no update on this so far. I need to check with Tony if he has any preference for handling this. I will follow-up with him and keep you posted.
Jon please repost these without the RFC in the subject line assuming the pending comments have been addressed so people can ack them.
I have been working on updating this series to request timer by their capabilities and avoid using a device ID altogether. In the updated series using device IDs to request a timer will still work as it does today, but not when you boot with DT. I have something working now that is booting fine on omap4 with and without DT [1]. However, I need to do more thorough testing of the timers in general, probably next week.
Quoted 5 lines
Once I have completed my testing I would like to post for review. However, since posting the original series I have been working on some needed timer fixes/clean-up which I posted this week [2] for review. Ideally I should rebase my DT timer work on my timer fixes series but wanted to see what you thought first.
Quoted 3 lines
Yeah those all look good to me. Want to do a git branch against v3.6-rc4 for those once the comments are dealt with so I can pull it in for testing to start with?
The fixes series should already be based on top of 3.6-rc4 but will update based upon comments. The only outstanding comment on those were the implementation of the __omap_dm_timer_populate_errata() function. Not sure if you have any comments. Vaibhav and myself are not completely happy with it. I proposed something else but no feedback on that yet.
Cheers
Jon
RFC 1/4 arm/dts: OMAP: Add timer nodes
In reply to Jon HunterQuoted 45 lines · Jon Hunter
Hi Rob,
Quoted 42 lines · Jon Hunter
Hi Rob,
Quoted 14 lines · Rob Herring
Quoted 5 lines · Jon Hunter
Add the 12 GP timers nodes present in OMAP3.
Add the 11 GP timers nodes present in OMAP4.Add documentation for timer properties specific to OMAP.
Quoted 7 lines
For each timer an alias is being added. The purpose for doing this is because the OMAP dmtimer driver uses an ID to distinguish between the different timer instances. For example, a timer can be requested by its ID. By adding an alias for each timer we can then use the function
of_alias_get_id()to extract the ID for each timer from the alias name. The same method is used for the TTY serial devices. If it is preferred that such an alias is not added and there is a better way to pass an ID from device-tree let me know.Quoted 6 lines
I'm not sure this is really a good use of aliases. UARTs use aliases because it is important that the UART number to tty number is known and fixed. IIUC, as an example you are picking timer1 because it has properties X, Y and Z. If so, then you should describe those h/w properties within the timer nodes so you can pick which timer to use based on it's h/w properties.
Thanks for the feedback. What you suggest could definitely work for most timers. The only item that I would need to resolve here is the handling of system timers (ie. those used for clockevents and clocksource). These system timers (for OMAP) are reserved during early boot based upon the timer ID today and so this is before the actual main timer driver has been probed and all the attributes of the timers has been read for device-tree.
One thought would be to move the reservation of the system timers out of the kernel and into device-tree itself. Then we query device tree on start-up to see which we should use. I am wondering if this could be a better use of alias? For example, say I want to use timer1 as my clockevent timer and so I could have an alias of ...
alias { clockevent_timer = &timer1; }
Quoted 8 lines
Quoted 5 lines
However, I am not sure if this is even correct, because there does not appear to be an API to search the aliases by name and return the phandle, just
of_alias_get_id(). Alternatively, I could add another property called "ti,timer-clockevent" that is populated for the timer used as the clockevent timer.Do you have any inputs on the above? Does it make sense to reserve timer resources for kernel system timers in device-tree?
This issue is not unique to omap. So if we do specify clockevent and clocksource in dts, then it should be in a common way. I think using "linux,clockevent" either as an alias name or property within the timer node would work. I don't have a strong preference, but I tend to lean toward an alias. Primarily this is because we are already using aliases for similar purposes.
However, I still think this could be done by looking at properties. There's not really any reason you can't check properties at timer init stage. The FDT has already been un-flattened. What are the features or lack of features you care about to determine which timer to use?
Rob
RFC 1/4 arm/dts: OMAP: Add timer nodes
Quoted 1 line · Rob Herring
On 07/23/2012 10:24 AM, Jon Hunter wrote:
[snip]
Quoted 10 lines
Quoted 2 lines
Do you have any inputs on the above? Does it make sense to reserve timer resources for kernel system timers in device-tree?
This issue is not unique to omap. So if we do specify clockevent and clocksource in dts, then it should be in a common way. I think using "linux,clockevent" either as an alias name or property within the timer node would work. I don't have a strong preference, but I tend to lean toward an alias. Primarily this is because we are already using aliases for similar purposes.
Quoted 4 lines
However, I still think this could be done by looking at properties. There's not really any reason you can't check properties at timer init stage. The FDT has already been un-flattened. What are the features or lack of features you care about to determine which timer to use?
I agree. Currently, I am looking into implementing something that will use timer properties to select the system timers for the kernel and not require us to select them in the device-tree. Once I have something working I will send out for review.
Cheers
Jon
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
In reply to Jon HunterOMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the prom_add_property() function to dynamically add a property was a recommended approach suggested by Rob Herring [1].
I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)
arch/arm/mach-omap2/board-generic.c +1 -0
@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }
arch/arm/mach-omap2/common.h +1 -0
@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
arch/arm/mach-omap2/timer.c +36 -0
@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h>
@@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the +* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{ +struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; + +/* If we are a secure device, remove any secure timer nodes */ +if ((omap_type () !=OMAP2_DEVICE_TYPE_GP )) { +for_each_matching_node (np, omap3_timer_match) { +if (of_get_property (np,"ti,timer-secure" ,NULL )) +prom_add_property (np, &timer_disabled); + } + } +} +/** * omap2_override_clocksource - clocksource override with user configuration *
Signature · 1 line
1.7.9.5
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
Quoted 91 lines · Jon Hunter
OMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the
prom_add_property()function to dynamically add a property was a recommended approach suggested by Rob Herring [1].I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
Signed-off-by Jon Hunter <[email protected]>--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)arch/arm/mach-omap2/board-generic.c +1
-0@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }arch/arm/mach-omap2/common.h +1
-0@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ arch/arm/mach-omap2/timer.c +17
-0@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h> @@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the
arch/arm/mach-omap2/timer.c static int __init omap2_dm_timer_init(void) · line 511
Quoted 10 lines
arch/arm/mach-omap2/timer.c +10
-0+* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{ +struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; +
Sorry for responding so late, but why only omap34xx check here? Isn't this applicable to all omap & non-omap devices?
Thanks,
Vaibhav
Quoted 13 lines
arch/arm/mach-omap2/timer.c +9
-0+/* If we are a secure device, remove any secure timer nodes */ +if ((omap_type () !=OMAP2_DEVICE_TYPE_GP )) { +for_each_matching_node (np, omap3_timer_match) { +if (of_get_property (np,"ti,timer-secure" ,NULL )) +prom_add_property (np, &timer_disabled); + } + } +} +/** * omap2_override_clocksource - clocksource override with user configuration *
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
Quoted 99 lines · Vaibhav Hiremath
Quoted 96 lines · Jon Hunter
OMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the
prom_add_property()function to dynamically add a property was a recommended approach suggested by Rob Herring [1].I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
Signed-off-by Jon Hunter <[email protected]>--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)arch/arm/mach-omap2/board-generic.c +1
-0@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }arch/arm/mach-omap2/common.h +1
-0@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ arch/arm/mach-omap2/timer.c +22
-0@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h> @@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the +* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{
Quoted 8 lines
arch/arm/mach-omap2/timer.c static int __init omap2_dm_timer_init(void) · line 511
Quoted 5 lines
arch/arm/mach-omap2/timer.c +5
-0+struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; +Sorry for responding so late, but why only omap34xx check here? Isn't this applicable to all omap & non-omap devices?
It is only applicable to omap3 devices as far as omap is concerned.
By non-omap, you are referring to the AMxxx stuff?
Do AMxxx devices even support security (ie. secure boot and have secure peripherals)? If not then this will work for AMxxx devices too.
Let me know if the changelog is not clear why this is needed for an omap3 device.
Jon
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
Quoted 110 lines · Jon
Quoted 99 lines · Vaibhav Hiremath
Quoted 96 lines · Jon Hunter
OMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the
prom_add_property()function to dynamically add a property was a recommended approach suggested by Rob Herring [1].I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
Signed-off-by Jon Hunter <[email protected]>--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)arch/arm/mach-omap2/board-generic.c +1
-0@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }arch/arm/mach-omap2/common.h +1
-0@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ arch/arm/mach-omap2/timer.c +22
-0@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h> @@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the +* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{Quoted 8 lines
arch/arm/mach-omap2/timer.c static int __init omap2_dm_timer_init(void) · line 511
Quoted 5 lines
arch/arm/mach-omap2/timer.c +5
-0+struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; +Sorry for responding so late, but why only omap34xx check here? Isn't this applicable to all omap & non-omap devices?
Quoted 7 lines
It is only applicable to omap3 devices as far as omap is concerned.
By non-omap, you are referring to the AMxxx stuff?
Do AMxxx devices even support security (ie. secure boot and have secure peripherals)? If not then this will work for AMxxx devices too.
Yes it does.
AM33xx has 8 timers and Timer-0 is a secure timer. As in case of OMAP3, we do not even register timer-0 to kernel.
Quoted 3 lines
Let me know if the changelog is not clear why this is needed for an omap3 device.
The changelog description is clear, but it is not only restricted to OMAP3.
Thanks,
Vaibhav
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
Quoted 115 lines · Vaibhav
Quoted 114 lines · Jon
Quoted 99 lines · Vaibhav Hiremath
Quoted 96 lines · Jon Hunter
OMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the
prom_add_property()function to dynamically add a property was a recommended approach suggested by Rob Herring [1].I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
Signed-off-by Jon Hunter <[email protected]>--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)arch/arm/mach-omap2/board-generic.c +1
-0@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }arch/arm/mach-omap2/common.h +1
-0@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ arch/arm/mach-omap2/timer.c +22
-0@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h> @@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the +* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{Quoted 8 lines
arch/arm/mach-omap2/timer.c static int __init omap2_dm_timer_init(void) · line 511
Quoted 5 lines
arch/arm/mach-omap2/timer.c +5
-0+struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; +Sorry for responding so late, but why only omap34xx check here? Isn't this applicable to all omap & non-omap devices?
It is only applicable to omap3 devices as far as omap is concerned.
By non-omap, you are referring to the AMxxx stuff?
Quoted 8 lines
Quoted 3 lines
Do AMxxx devices even support security (ie. secure boot and have secure peripherals)? If not then this will work for AMxxx devices too.
Yes it does.
AM33xx has 8 timers and Timer-0 is a secure timer. As in case of OMAP3, we do not even register timer-0 to kernel.
Ok, however, please note that the omap3 timer 12 is a special case, because on a non-secure device it is available for general purpose use and only reserved for secure use on a secure device.
For omap4/5 timer 12 is always a secure timer and so we never register it for any device (secure or non-secure) by using the "ti,timer-secure" property in DT.
So, for AM33xx, is timer0 always reserved for secure used on non-secure and secure devices? If so, then timer0 just needs to add the "ti,timer-secure" property in device-tree file and it will not be registered and no change is needed in the above code.
Quoted 5 lines
Quoted 3 lines
Let me know if the changelog is not clear why this is needed for an omap3 device.
The changelog description is clear, but it is not only restricted to OMAP3.
Not exactly, per the above it depends on whether the timer is always secure for all device types or not.
Cheers
Jon
RFC 2/4 ARM: OMAP3: Dynamically disable secure timer nodes for secure devices
Quoted 130 lines · Jon
Quoted 115 lines · Vaibhav
Quoted 114 lines · Jon
Quoted 99 lines · Vaibhav Hiremath
Quoted 96 lines · Jon Hunter
OMAP3 devices may or may not have security features enabled. Security enabled devices are known as high-secure (HS) and devices without security are known as general purpose (GP).
For OMAP3 devices there are 12 general purpose timers available. On secure devices the 12th timer is reserved for secure usage and so cannot be used by the kernel, where as for a GP device it is available. We can detect the OMAP device type, secure or GP, at runtime via an on-chip register. Today, when not using DT, we do not register the 12th timer as a linux device if the device is secure.
When using device tree, device tree is going to register all the timer devices it finds in the device tree blob. To prevent device tree from registering 12th timer on a secure OMAP3 device we can add a status property to the timer binding with the value "disabled" at boot time. Note that timer 12 on a OMAP3 device has a property "ti,timer-secure" to indicate that it will not be available on a secure device and so for secure OMAP3 devices, we search for timers with this property and then disable them. Using the
prom_add_property()function to dynamically add a property was a recommended approach suggested by Rob Herring [1].I have tested this on an OMAP3 GP device and faking it to pretend to be a secure device to ensure that any timers marked with "ti,timer-secure" are not registered on boot. I have also made sure that all timers are registered as expected on a GP device by default.
[1] http://comments.gmane.org/gmane.linux.ports.arm.omap/79203
Signed-off-by Jon Hunter <[email protected]>--- arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/timer.c | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+)arch/arm/mach-omap2/board-generic.c +1
-0@@ -40,6 +40,7 @@ static struct of_device_id omap_dt_match_table[] __initdata = {static void __init omap_generic_init (void ) {omap_sdrc_init (NULL ,NULL ); +omap_dmtimer_init ();of_platform_populate (NULL , omap_dt_match_table,NULL ,NULL ); }arch/arm/mach-omap2/common.h +1
-0@@ -326,6 +326,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1);struct omap2_hsmmc_info ;extern int omap4_twl6030_hsmmc_init (struct omap2_hsmmc_info *controllers); +extern void omap_dmtimer_init (void );#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ arch/arm/mach-omap2/timer.c +22
-0@@ -36,6 +36,7 @@#include <linux/clocksource.h> #include <linux/clockchips.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/mach/time.h> #include <plat/dmtimer.h> @@ -482,6 +483,41 @@ static int __init omap2_dm_timer_init(void) }arch_initcall (omap2_dm_timer_init); +static struct property timer_disabled = { + .name ="status" , + .length =sizeof ("disabled" ), + .value ="disabled" , +}; + +static struct of_device_id omap3_timer_match[]__initdata = { + { .compatible ="ti,omap3-timer" , }, + { } +}; + +/** +* omap_dmtimer_init - initialisation function when device tree is used +* +* For secure OMAP3 devices, timers with device type "timer-secure" cannot +* be used by the kernel as they are reserved. Therefore, to prevent the +* kernel registering these devices remove them dynamically from the device +* tree on boot. +*/ +void __init omap_dmtimer_init (void ) +{Quoted 8 lines
arch/arm/mach-omap2/timer.c static int __init omap2_dm_timer_init(void) · line 511
Quoted 5 lines
arch/arm/mach-omap2/timer.c +5
-0+struct device_node *np; + +if (!cpu_is_omap34xx ()) +return ; +Sorry for responding so late, but why only omap34xx check here? Isn't this applicable to all omap & non-omap devices?
It is only applicable to omap3 devices as far as omap is concerned.
By non-omap, you are referring to the AMxxx stuff?
Quoted 8 lines
Quoted 3 lines
Do AMxxx devices even support security (ie. secure boot and have secure peripherals)? If not then this will work for AMxxx devices too.
Yes it does.
AM33xx has 8 timers and Timer-0 is a secure timer. As in case of OMAP3, we do not even register timer-0 to kernel.
Ok, however, please note that the omap3 timer 12 is a special case, because on a non-secure device it is available for general purpose use and only reserved for secure use on a secure device.
Quoted 9 lines
For omap4/5 timer 12 is always a secure timer and so we never register it for any device (secure or non-secure) by using the "ti,timer-secure" property in DT.
So, for AM33xx, is timer0 always reserved for secure used on non-secure and secure devices? If so, then timer0 just needs to add the "ti,timer-secure" property in device-tree file and it will not be registered and no change is needed in the above code.
I think you may be right here, AM33XX secure timer is similar to omap4, so Just "ti,timer-secure" property should be enough.
Thanks,
Vaibhav
RFC 3/4 ARM: OMAP4: Add timer clock aliases for device-tree
In reply to Jon HunterFor OMAP4, the dmtimers are located in the Wake-up, ABE and Peripheral (PER) power domains. Hence, when the dmtimer is configured to use the "timer_sys_ck" as its functional clock the actual clock used is different depending on whether the clock is in the Wake-up, ABE or PER domain. So when we look-up the dmtimer's "timer_sys_ck" we need to specify the timer device name as well as clock alias to find the right clock.
Currently, the device names for the timers have the format "omap_timer.X" where X is the timer instance number. When using to device tree, the format of the device name created by device-tree is different and has the format "<reg-address>.<device-name>" (this is assuming that the device-tree "reg" property is specified). This causes the look-up for the OMAP4 "timer_sys_ck" to fail. To fix this add new timer clock alias for using device-tree.
Please note that adding a 2nd set of clock aliases for the same clocks to only temporary until device-tree migration is complete. Then we can remove the legacy aliases. Hence, I have marked the legacy aliases with a "TODO" to remove them.
--- arch/arm/mach-omap2/clock44xx_data.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/arm/mach-omap2/clock44xx_data.c +12 -0
@@ -3314,6 +3314,7 @@ static struct omap_clk omap44xx_clks[] = {CLK ("usbhs_omap" ,"usbtll_fck" , &dummy_ck,CK_443X ),CLK ("omap_wdt" ,"ick" , &dummy_ck,CK_443X ),CLK (NULL ,"timer_32k_ck" , &sys_32k_ck,CK_443X ), +/* TODO: Remove "omap_timer.X" aliases once DT migration is complete */ CLK ("omap_timer.1" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ),CLK ("omap_timer.2" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), CLK("omap_timer.3", "timer_sys_ck", &sys_clkin_ck, CK_443X),
@@ -3325,6 +3326,17 @@ static struct omap_clk omap44xx_clks[] = {CLK ("omap_timer.6" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ),CLK ("omap_timer.7" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ),CLK ("omap_timer.8" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ), +CLK ("4a318000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("48032000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("48034000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("48036000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("4803e000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("48086000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("48088000.timer" ,"timer_sys_ck" , &sys_clkin_ck,CK_443X ), +CLK ("49038000.timer" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ), +CLK ("4903a000.timer" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ), +CLK ("4903c000.timer" ,"timer_sys_ck" , &syc_clk_div_ck,CK_443X ), + CLK("4903e000.timer", "timer_sys_ck", &syc_clk_div_ck, CK_443X), };int __init omap4xxx_clk_init (void )
Signature · 1 line
1.7.9.5
RFC 4/4 ARM: OMAP: Add DT support for timer driver
In reply to Jon HunterIn order to add device-tree support to the timer driver the following changes were made ...
1. If DT blob is present, then let HWMOD create the timer devices dynamically.
2. When device-tree is present the "id" field in the platform_device structure (pdev->id) is initialised to -1 and the timer instance is looked-up using the device tree alias mechanism. Therefore, avoid using "pdev-id" in the driver and use "timer->id" which will be initialised correctly regardless of whether device tree is present.
3. When device-tree is present the platform_data structure will be NULL and so check for this.
4. The OMAP timer device tree binding optional parameters ...
a. ti,timer-alwon --> Timer is in an always-on power domain b. ti,timer-pwn --> Timer can generate a PWM output
Search for the above parameters and set the appropriate timer attribute flags.
--- arch/arm/mach-omap2/timer.c | 4 ++++ arch/arm/plat-omap/dmtimer.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-)
arch/arm/mach-omap2/timer.c +4 -0
@@ -473,6 +473,10 @@ static int __init omap2_dm_timer_init(void) {int ret; +/* If dtb is there, the devices will be created dynamically */ +if (of_have_populated_dt ()) +return -ENODEV ; + ret =omap_hwmod_for_each_by_class ("timer" , omap_timer_init,NULL );if (unlikely (ret)) {pr_err ("%s: device registration failed.\n" , __func__);
arch/arm/plat-omap/dmtimer.c +26 -6
@@ -40,6 +40,8 @@#include <linux/device.h> #include <linux/err.h> #include <linux/pm_runtime.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <plat/dmtimer.h> #include <plat/omap-pm.h>
@@ -123,7 +125,7 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)static void omap_dm_timer_reset (struct omap_dm_timer *timer) {omap_dm_timer_enable (timer); -if (timer->pdev->id !=1 ) { +if (timer->id !=1 ) {omap_dm_timer_write_reg (timer,OMAP_TIMER_IF_CTRL_REG ,0x06 );omap_dm_timer_wait_for_reset (timer); }
@@ -214,7 +216,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)spin_lock_irqsave (&dm_timer_lock, flags);list_for_each_entry (t, &omap_timer_list, node) { -if (t->pdev->id == id && !t->reserved) { +if (t->id == id && !t->reserved) { timer = t; timer->reserved =1 ;break ;
@@ -414,7 +416,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)* use the clock framework to set the parent clock. To be removed * once OMAP1 migrated to using clock framework for dmtimers */ -if (pdata->set_timer_src) +if (pdata && pdata->set_timer_src)return pdata->set_timer_src (timer->pdev, source); fclk =clk_get (&timer->pdev->dev,"fck" );
@@ -695,7 +697,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;struct dmtimer_platform_data *pdata = pdev->dev.platform_data; -if (!pdata) { +if (!pdata && !dev->of_node) {dev_err (dev,"%s: no platform data.\n" , __func__);return -ENODEV ; }
@@ -724,11 +726,21 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)return -ENOMEM ; } - timer->id = pdev->id; +if (dev->of_node) { + timer->id =of_alias_get_id (dev->of_node,"timer" ); + +if (of_find_property (dev->of_node,"ti,timer-alwon" ,NULL )) + timer->capability |=OMAP_TIMER_ALWON ; +if (of_find_property (dev->of_node,"ti,timer-pwm" ,NULL )) + timer->capability |=OMAP_TIMER_HAS_PWM ; + }else { + timer->id = pdev->id; + timer->capability = pdata->timer_capability; + } + timer->irq = irq->start; timer->reserved =omap_dm_timer_reserved_systimer (timer->id); timer->pdev = pdev; - timer->capability = pdata->timer_capability;/* Skip pm_runtime_enable for OMAP1 */ if (!(timer->capability &OMAP_TIMER_NEEDS_RESET )) {
@@ -778,11 +790,19 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)return ret; } +static const struct of_device_id omap_timer_match[] = { + { .compatible ="ti,omap3-timer" , }, + { .compatible ="ti,omap2-timer" , }, + {}, +}; +MODULE_DEVICE_TABLE (of, omap_timer_match); +static struct platform_driver omap_dm_timer_driver = { .probe = omap_dm_timer_probe, .remove =__devexit_p (omap_dm_timer_remove), .driver = { .name ="omap_timer" , + .of_match_table =of_match_ptr (omap_timer_match), }, };
Signature · 1 line
1.7.9.5
Paul Walmsley
maintainerRFC 4/4 ARM: OMAP: Add DT support for timer driver
Hi
Quoted 1 line · Jon Hunter
1. If DT blob is present, then let HWMOD create the timer devices dynamically.
This probably should read "is _not_ present", yes?
- Paul
RFC 4/4 ARM: OMAP: Add DT support for timer driver
Quoted 7 lines · Paul Walmsley
Hi
Quoted 1 line · Jon Hunter
1. If DT blob is present, then let HWMOD create the timer devices dynamically.
This probably should read "is _not_ present", yes?
Yes, you are right. What a balls-up ...
Thanks
Jon