ARM: OMAP: core/hwmod: first set of fixes for 3.5-rc
Subsystems (7)
Paul Walmsley
maintainerv2 cover ARM: OMAP: core/hwmod: first set of fixes for 3.5-rc
Hi,
Here is an initial set of fixes for power management and OMAP core infrastructure for 3.5-rc. Most of these patches address boot warnings and power management problems on OMAP4, although a few of them address more general issues.
Thanks to (in alphabetical order) Beno?t Cousson, Tero Kristo, Kevin Hilman, Vaibhav Hiremath, and Tony Lindgren for help with this series.
Compile-test information is below. The patches been boot-tested on OMAP3530 ES3.0 BeagleBoard and OMAP4430 ES2.0 PandaBoard. Suspend and idle are broken on both of these platforms right now. Unfortunately my board farm is down at the moment, so I'm unable to do further testing on other boards. Boot logs, such as they are, are available from:
These patches are available via git from git://git.pwsan.com/linux-2.6
in the branch 'omap_fixes_a_3.5rc'.
This second version contains several changes:
- Rebased on v3.5-rc2.
- A new patch has been added to change the 32k sync timer SIDLEMODE flags ("ARM: OMAP4: hwmod data: fix 32k sync timer idle modes").
- A bug has been fixed ("ARM: OMAP2+: hwmod code/data: fix 32K sync timer").
- setup_preprogram code for the AESS and FSUSB IP blocks has been moved to include/linux/platform_data at Tony's request ("ARM: OMAP4+: AESS: enable internal auto-gating during initial setup" and "ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)")
- Paul
---
object size (delta in bytes from v3.5-rc2 (cfaf025112d3856637ff34a767ef785ef5cf2ca9)):
text data bss total kernel
0 0 0 0 5912osk_testconfig/vmlinux
+64 +96 0 +160 n800_multi_omap2xxx/vmlinux
+96 +96 0 +192 n800_testconfig/vmlinux
0 0 0 0 omap1510_defconfig/vmlinux
0 0 0 0 omap1_defconfig/vmlinux
+304 +320 0 +624 omap2_4_testconfig/vmlinux
+304 +448 0 +752 omap2plus_defconfig/vmlinux
+240 +384 0 +624 omap2plus_no_pm/vmlinux
+4404 +312 0 +4716 omap3_4_testconfig/vmlinux
+100 +56 0 +156 omap3_testconfig/vmlinux
+308 +280 0 +588 omap4_testconfig/vmlinuxDjamil Elaidi (1):
ARM: OMAP4+: hwmod: fix issue causing IPs not going back to Smart-Standby
Paul Walmsley (10):
ARM: OMAP2+: hwmod code/data: fix 32K sync timer
ARM: OMAP4: hwmod data: fix 32k sync timer idle modes
ARM: OMAP2+: hwmod: add setup_preprogram hook
ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init
ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
ARM: OMAP4: hwmod data: add SL2IF hardreset line
ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
ARM: OMAP2+: CM: increase the module disable timeout
ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
Todd Poynor (1):
ARM: OMAP: PM: Lock clocks list while generating summary
arch/arm/mach-omap2/clock44xx_data.c | 5 + arch/arm/mach-omap2/cm.h | 11 +++ arch/arm/mach-omap2/cminst44xx.c | 4 - arch/arm/mach-omap2/omap_hwmod.c | 43 +++++++++-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 30 +++++++ arch/arm/plat-omap/clock.c | 2 arch/arm/plat-omap/include/plat/omap_hwmod.h | 24 ++++++ include/linux/platform_data/aess.h | 76 +++++++++++++++++++ include/linux/platform_data/fsusb.h | 105 ++++++++++++++++++++++++++ 10 files changed, 288 insertions(+), 14 deletions(-) create mode 100644 include/linux/platform_data/aess.h create mode 100644 include/linux/platform_data/fsusb.h
Paul Walmsley
maintainerPATCH v2 1/12 ARM: OMAP: PM: Lock clocks list while generating summary
From: Todd Poynor <[email protected]>
Commit a53025724052b2b1edbc982a4a248784638f563d (OMAP: Add debugfs node to show the summary of all clocks) introduced clock summary, however, we are interested in seeing snapshot of the clock state, not in dynamically changing clock configurations as the data provided by clock summary will then be useless for debugging configuration issues. So, hold the common lock when dumping the clock summary.
--- arch/arm/plat-omap/clock.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/plat-omap/clock.c +2 -0
@@ -461,6 +461,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused)struct clk *c;struct clk *pa; +mutex_lock (&clocks_mutex);seq_printf (s,"%-30s %-30s %-10s %s\n" ,"clock-name" ,"parent-name" ,"rate" ,"use-count" );
@@ -469,6 +470,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void *unused)seq_printf (s,"%-30s %-30s %-10lu %d\n" , c->name, pa ? pa->name :"none" , c->rate, c->usecount); } +mutex_unlock (&clocks_mutex);return 0 ; }
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
In reply to Paul WalmsleyKevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c ("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states.
The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the CORE_L3 and CORE_CM clockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states.
It turns out that there is no need to take the 32k sync timer out of idle. The IP block itself probably does not have any native idle handling at all, due to its simplicity. Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the CORE_L3 clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.
This workaround is implemented by defining a new hwmod flag, HWMOD_ALWAYS_FORCE_SIDLE, that places the IP block into target force-idle mode even when enabled. The 32k sync timer hwmods are marked with this flag for OMAP3 and OMAP4 SoCs. (On OMAP2xxx, no OCP header existed on the 32k sync timer.)
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
Another possible fix would have been to modify the pm34xx.c code to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.
This patch is effectively a workaround for a hardware problem. A better hardware approach would have been to implement a smart-idle target idle mode for this IP block. The smart-idle mode in this case would behave identically to the force-idle mode. We consider the force-idle and no-idle target idle mode settings to be intended for debugging and automatic idle management bug workarounds only[4].
This patch is a collaboration between Kevin Hilman <[email protected]> and Paul Walmsley <[email protected]>.
Thanks to Vaibhav Hiremath <[email protected]> for providing comments on an earlier version of this patch. Thanks to Tero Kristo <[email protected]> for identifying a bug in an earlier version of this patch. Thanks to Beno?t Cousson <[email protected]> for identifying a bug in an earlier version of this patch and for implementation comments.
References:
1. Table 16-96 "REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU (SWPU223U), available from:
http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip
2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU (SWPU223U)
3. ibid.
4. Section 3.1.1.1.2 "Module-Level Clock Management" of the OMAP4430 TRM Rev. vAA (SWPU231AA).
--- arch/arm/mach-omap2/omap_hwmod.c | 17 +++++++++++------ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 +- arch/arm/plat-omap/include/plat/omap_hwmod.h | 9 +++++++++ 4 files changed, 22 insertions(+), 8 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +11 -6
@@ -1124,10 +1124,12 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap* _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * -* If module is marked as SWSUP_SIDLE, force the module out of slave -* idle; otherwise, configure it for smart-idle. If module is marked -* as SWSUP_MSUSPEND, force the module out of master standby; -* otherwise, configure it for smart-standby. No return value. +* Ensure that the OCP_SYSCONFIG register for the IP block represented +* by @oh is set to indicate to the PRCM that the IP block is active. +* Usually this means placing the module into smart-idle mode and +* smart-standby, but if there is a bug in the automatic idle handling +* for the IP block, it may need to be placed into the force-idle or +* no-idle variants of these modes. No return value. */ static void _enable_sysc (struct omap_hwmod *oh) {
@@ -1141,8 +1143,11 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; +if (oh->flags &HWMOD_ALWAYS_FORCE_SIDLE ) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? +HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +1 -1
@@ -2018,7 +2018,7 @@ static struct omap_hwmod omap3xxx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap3xxx_counter_hwmod_class, .clkdm_name = "wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_ALWAYS_FORCE_SIDLE | HWMOD_SWSUP_SIDLE, .main_clk = "wkup_32k_fck", .prcm = { .omap2 = {
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +1 -1
@@ -408,7 +408,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap44xx_counter_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_ALWAYS_FORCE_SIDLE | HWMOD_SWSUP_SIDLE, .main_clk = "sys_32k_ck", .prcm = { .omap4 = {
arch/arm/plat-omap/include/plat/omap_hwmod.h +9 -0
@@ -409,6 +409,14 @@ struct omap_hwmod_omap4_prcm {* in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers +* HWMOD_ALWAYS_FORCE_SIDLE: Always program this module's SIDLEMODE to +* force-idle mode, even when enabled. This is needed for IP blocks +* which do not support smart idle, which do not have a software +* controllable functional or interface clock, and which the PRCM +* will not assert SIdleReq until the kernel is not currently +* running on the chip (e.g., the MPU is in idle). For such modules, +* fine-grained PM runtime-based idle control is simply a waste of +* CPU cycles. */ #define HWMOD_SWSUP_SIDLE (1 << 0)#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -419,6 +427,7 @@ struct omap_hwmod_omap4_prcm {#define HWMOD_NO_IDLEST (1 << 6)#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)#define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_ALWAYS_FORCE_SIDLE (1 << 9)/* * omap_hwmod._int_flags definitions
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi Paul,
Quoted 1 line · Paul Walmsley
Kuvin discovered that commit
c8d82ff68fb6873691536cf33021977efbf5593c
I guess you meant Kevin?
Quoted 12 lines
("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states.
The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the
CORE_L3andCORE_CMclockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states.
Quoted 3 lines
It turns out that there is no need to take the 32k sync timer out of idle.
The IP block itself pbobably does not have any native idle
typo
Quoted 1 line
handling at all, due to its simplicity.
I don't think this description is really accurate, due to the usual confusing definition of IDLE for the PRCM standpoint :-) The counter_32k will follow PRCM requirement toward SIdleReq/SIdleAck. It has to be "idle" for PRCM standpoint to allow the transition of the L4_WKUP to inactive (SIdleAck=IDLE). And it will be functional as soon as the L4_WKUP domain is active.
The fact that the smartidle mode is missing does not change anything in the way the PRCM handle the protocol. It is just an issue at IP level.
In that case force-idle = smart-idle, just because this module does not have anything to do to delay the SIdleAck upon SIdleReq request. The IP is probably connecting the SIdleAck to the SIdleReq signal. Please note that there are a bunch of IPs that are doing that even if they do support the smartidle mode.
Quoted 6 lines
Furthermore, the PRCM will
never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while theCORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.
Do you mean force-idle? Because accessing a module in no-idle is always possible.
Quoted 5 lines
This workaround is implemented by defining a new hwmod flag,
HWMOD_ALWAYS_FORCE_SIDLE, that places the IP block into target force-idle mode even when enabled. The 32k sync timer hwmods are marked with this flag for OMAP3 and OMAP4 SoCs. (On OMAP2xxx, no OCP header existed on the 32k sync timer.)
I still don't see the need for this flag. It looks to me that we are adding a redundant information and thus make things more complex than it should.
.idlemodes = (SIDLE_FORCE | SIDLE_NO),
It the real root cause of the problem. There is no need to re-encode that using an extra flag. Especially at hwmod level where the issue is at sysconfig level.
I did not really get the reason why you changed your mind on that point.
As soon as there is no SIDLE_SMART mode, what choice do we have but using the SIDLE_FORCE?
BTW, I even think the HWMOD_SWSUP_SIDLE hwmod flag is useless now. It was needed before probably because the idlemodes were wrongly populated.
In fact the hwmod flags is really there to *flag* some real HW bug we cannot figure out otherwise, but in that case, the sysc.idlemodes already contains all the information we need to set the proper mode during enable/disable.
Duplicating the information is always a source of confusion and might lead to nasty bugs due to the increase of complexity.
Quoted 8 lines
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
I don't think that part is really relevant anymore.
Quoted 4 lines
Another possible fix would have been to modify the
pm34xx.ccode to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.
Neither that one I guess. As soon as we consider force-idle to be equivalent to smart-idle, nothing more is needed.
Quoted 84 lines
This patch is effectively a workaround for a hardware problem. A better hardware approach would have been to implement a smart-idle target idle mode for this IP block. The smart-idle mode in this case would behave identically to the force-idle mode. We consider the force-idle and no-idle target idle mode settings to be intended for debugging and automatic idle management bug workarounds only[4].
This patch is a collaboration between Kevin Hilman <[email protected]> and Paul Walmsley <[email protected]>.
Thanks to Vaibhav Hiremath <[email protected]> for providing comments on an earlier version of this patch. Thanks to Tero Kristo <[email protected]> for identifying a bug in an earlier version of this patch. Thanks to Beno?t Cousson <[email protected]> for identifying a bug in an earlier version of this patch and for implementation comments.
References:
1. Table 16-96 "
REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU(SWPU223U), available from: http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU
(SWPU223U)3. ibid.
4. Section 3.1.1.1.2 "Module-Level Clock Management" of the OMAP4430
TRM Rev. vAA (SWPU231AA).Cc Tony Lindgren <[email protected]>Cc Vaibhav Hiremath <[email protected]>Cc Beno?t Cousson <[email protected]>Cc Tero Kristo <[email protected]>Tested-by Kevin Hilman <[email protected]>Signed-off-by Kevin Hilman <[email protected]>Signed-off-by Paul Walmsley <[email protected]>--- arch/arm/mach-omap2/omap_hwmod.c | 17 +++++++++++------ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 +- arch/arm/plat-omap/include/plat/omap_hwmod.h | 9 +++++++++ 4 files changed, 22 insertions(+), 8 deletions(-)arch/arm/mach-omap2/omap_hwmod.c +11
-6@@ -1124,10 +1124,12 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap* _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * -* If module is marked as SWSUP_SIDLE, force the module out of slave -* idle; otherwise, configure it for smart-idle. If module is marked -* as SWSUP_MSUSPEND, force the module out of master standby; -* otherwise, configure it for smart-standby. No return value. +* Ensure that the OCP_SYSCONFIG register for the IP block represented +* by @oh is set to indicate to the PRCM that the IP block is active. +* Usually this means placing the module into smart-idle mode and +* smart-standby, but if there is a bug in the automatic idle handling +* for the IP block, it may need to be placed into the force-idle or +* no-idle variants of these modes. No return value. */ static void _enable_sysc (struct omap_hwmod *oh) {@@ -1141,8 +1143,11 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; +if (oh->flags &HWMOD_ALWAYS_FORCE_SIDLE ) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? +HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +0
-0
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c static struct omap_hwmod omap3xxx_counter_32k_hwmod = { · line 2021
Quoted 5 lines
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +1
-1@@ -2018,7 +2018,7 @@ static struct omap_hwmod omap3xxx_counter_32k_hwmod = { .name = "counter_32k", .class = &omap3xxx_counter_hwmod_class, .clkdm_name = "wkup_clkdm", - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_ALWAYS_FORCE_SIDLE | HWMOD_SWSUP_SIDLE,
I guess we might be able to get rid of both in theory.
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi
Quoted 4 lines · Benoit
Quoted 1 line · Paul Walmsley
Kuvin discovered that commit
c8d82ff68fb6873691536cf33021977efbf5593cI guess you meant Kevin?
...
Quoted 3 lines
Quoted 1 line
The IP block itself pbobably does not have any native idle
typo
Thanks for noticing these, but they are not in what was sent out by the list server:
http://www.spinics.net/lists/linux-omap/msg71503.html
Some software/hardware issue on your end, maybe?
Quoted 9 lines
Quoted 1 line
handling at all, due to its simplicity.
I don't think this description is really accurate, due to the usual confusing definition of IDLE for the PRCM standpoint :-)
Thecounter_32kwill follow PRCM requirement toward SIdleReq/SIdleAck. It has to be "idle" for PRCM standpoint to allow the transition of theL4_WKUPto inactive (SIdleAck=IDLE). And it will be functional as soon as theL4_WKUPdomain is active.
Quoted 8 lines
The fact that the smartidle mode is missing does not change anything in the way the PRCM handle the protocol. It is just an issue at IP level.
In that case force-idle = smart-idle, just because this module does not have anything to do to delay the SIdleAck upon SIdleReq request. The IP is probably connecting the SIdleAck to the SIdleReq signal.
Please note that there are a bunch of IPs that are doing that even if they do support the smartidle mode.
Right, that's exactly my point -- perhaps made in an unclear way.
My point was that the 32k counter IP block doesn't do anything with the incoming IdleReq signal to determine whether or not to assert IdleAck back to the PRCM. But rather than implementing smart-idle mode to handle this, like the other IP blocks do, the only two modes implemented were the debugging modes, force-idle and no-idle.
So depending on one's point of view, this patch is either:
1. a hardware bug workaround, because the hardware should have a smart-idle mode that acts the same way as the force-idle mode, just like the other IP blocks do; or
2. a software workaround, because we don't have a 32k counter device driver that implements runtime PM around counter reads.
Of course #2 would be rather pointless and the patch description tries to convey this too.
Quoted 8 lines
Quoted 5 lines
Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the
CORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.Do you mean force-idle? Because accessing a module in no-idle is always possible.
Thanks, that's indeed a description bug.
Quoted 11 lines
Quoted 5 lines
This workaround is implemented by defining a new hwmod flag,
HWMOD_ALWAYS_FORCE_SIDLE, that places the IP block into target force-idle mode even when enabled. The 32k sync timer hwmods are marked with this flag for OMAP3 and OMAP4 SoCs. (On OMAP2xxx, no OCP header existed on the 32k sync timer.)I still don't see the need for this flag. It looks to me that we are adding a redundant information and thus make things more complex than it should.
.idlemodes = (
SIDLE_FORCE|SIDLE_NO),
Quoted 8 lines
It the real root cause of the problem. There is no need to re-encode that using an extra flag. Especially at hwmod level where the issue is at sysconfig level.
I did not really get the reason why you changed your mind on that point.
As soon as there is no
SIDLE_SMARTmode, what choice do we have but using theSIDLE_FORCE?
SIDLE_NO is the option that makes more sense to me.
Consider an IP block with SIDLE_NO and SIDLE_FORCE but without SIDLE_SMART. When an initiator will access it, the default setting should be SIDLE_NO, for the reason that you identified above: "because accessing a module in no-idle is always possible." On the other hand, we don't know when it's safe to access a module in SIDLE_FORCE unless we have additional information as to how the IP block handles the SIdleReq signal internally, and the characteristics of the clock domain in which it's integrated. For example, as mentioned earlier in the discussion on this patch, the AM335x documentation states "By definition, initiator may generate read/write transaction as long as it is out of IDLE state."
Quoted 9 lines
BTW, I even think the
HWMOD_SWSUP_SIDLEhwmod flag is useless now. It was needed before probably because the idlemodes were wrongly populated.In fact the hwmod flags is really there to *flag* some real HW bug we cannot figure out otherwise, but in that case, the sysc.idlemodes already contains all the information we need to set the proper mode during enable/disable.
Duplicating the information is always a source of confusion and might lead to nasty bugs due to the increase of complexity.
You may be misunderstanding the meaning of the HWMOD_SWSUP_SIDLE flag. It was added to work around IP blocks that had broken smart-idle. These modules definitely do exist; see for example the OMAP3 wdt2, usbhsotg, and usb_host_hs hwmods as some examples.
It might be reasonable to remove the HWMOD_SWSUP_SIDLE flag from the 32k counter and just test again for HWMOD_ALWAYS_FORCE_SIDLE in the module disable. I'll take a look at this.
Quoted 10 lines
Quoted 8 lines
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
I don't think that part is really relevant anymore.
Why?
Quoted 7 lines
Quoted 4 lines
Another possible fix would have been to modify the
pm34xx.ccode to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.Neither that one I guess. As soon as we consider force-idle to be equivalent to smart-idle, nothing more is needed.
But they are definitely not equivalent.
- Paul
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 13 lines · Paul Walmsley
Hi
Quoted 4 lines · Benoit
Quoted 1 line · Paul Walmsley
Kuvin discovered that commit
c8d82ff68fb6873691536cf33021977efbf5593cI guess you meant Kevin?
...
Quoted 2 lines
Quoted 1 line
The IP block itself pbobably does not have any native idle
Quoted 8 lines
Quoted 1 line
typo
Thanks for noticing these, but they are not in what was sent out by the list server:
http://www.spinics.net/lists/linux-omap/msg71503.html
Some software/hardware issue on your end, maybe?
Hehe, funny, first time outlook server is editing email automatically... That's probably a new feature.
Quoted 27 lines
Quoted 10 lines
Quoted 2 lines
handling at all, due to its simplicity.
I don't think this description is really accurate, due to the usual confusing definition of IDLE for the PRCM standpoint :-)
Thecounter_32kwill follow PRCM requirement toward SIdleReq/SIdleAck. It has to be "idle" for PRCM standpoint to allow the transition of theL4_WKUPto inactive (SIdleAck=IDLE). And it will be functional as soon as theL4_WKUPdomain is active.Quoted 8 lines
The fact that the smartidle mode is missing does not change anything in the way the PRCM handle the protocol. It is just an issue at IP level.
In that case force-idle = smart-idle, just because this module does not have anything to do to delay the SIdleAck upon SIdleReq request. The IP is probably connecting the SIdleAck to the SIdleReq signal.
Please note that there are a bunch of IPs that are doing that even if they do support the smartidle mode.Right, that's exactly my point -- perhaps made in an unclear way.
My point was that the 32k counter IP block doesn't do anything with the incoming IdleReq signal to determine whether or not to assert IdleAck back to the PRCM. But rather than implementing smart-idle mode to handle this, like the other IP blocks do, the only two modes implemented were the debugging modes, force-idle and no-idle.
Quoted 5 lines
So depending on one's point of view, this patch is either:
1. a hardware bug workaround, because the hardware should have a smart-idle mode that acts the same way as the force-idle mode, just like the other IP blocks do; or
Well it is not even a real HW bug. That's more a recommendation that was not followed than a real HW bug. It is not the only one BTW, hence the number of flags we have in hwmod already :-)
A HW bug will be more for an IP that is supposed to have smart-idle but it does work properly and thus has to be disabled. In that case the mode is clearly not documented, so I'm not calling that an HW bug.
Quoted 12 lines
2. a software workaround, because we don't have a 32k counter device driver that implements runtime PM around counter reads.
Of course #2 would be rather pointless and the patch description tries to convey this too.
Quoted 6 lines
Quoted 5 lines
Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the
CORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.
Quoted 4 lines
Quoted 2 lines
Do you mean force-idle? Because accessing a module in no-idle is always possible.
Thanks, that's indeed a description bug.
I'm not sure to follow you? My point was it should be: "So we can safely leave the 32k sync timer in force-idle mode, even while we continue to access it."
This is what the WA is doing.
Quoted 22 lines
Quoted 11 lines
Quoted 5 lines
This workaround is implemented by defining a new hwmod flag,
HWMOD_ALWAYS_FORCE_SIDLE, that places the IP block into target force-idle mode even when enabled. The 32k sync timer hwmods are marked with this flag for OMAP3 and OMAP4 SoCs. (On OMAP2xxx, no OCP header existed on the 32k sync timer.)I still don't see the need for this flag. It looks to me that we are adding a redundant information and thus make things more complex than it should.
.idlemodes = (
SIDLE_FORCE|SIDLE_NO),Quoted 8 lines
It the real root cause of the problem. There is no need to re-encode that using an extra flag. Especially at hwmod level where the issue is at sysconfig level.
I did not really get the reason why you changed your mind on that point.
As soon as there is no
SIDLE_SMARTmode, what choice do we have but using theSIDLE_FORCE?
SIDLE_NOis the option that makes more sense to me.
Quoted 7 lines
Consider an IP block with
SIDLE_NOandSIDLE_FORCEbut withoutSIDLE_SMART. When an initiator will access it, the default setting should beSIDLE_NO, for the reason that you identified above: "because accessing a module in no-idle is always possible." On the other hand, we don't know when it's safe to access a module inSIDLE_FORCEunless we have additional information as to how the IP block handles the SIdleReq signal internally, and the characteristics of the clock domain in which it's integrated.
Nope, that's not really accurate. The SIDLE mode is just the local configuration for the IP behavior during clock domain transition to idle. It does not have any influence on the re-activation of the clock. In that case, both force-idle and smart-idle will behave the same. Only the transition to *idle* is supposed to be different between these two modes, hence the name.
What is missing here is the modulemode and the clock domain control:
counter_32k modulemode description:
"Module is managed automatically by HW according to clock domain transition. A clock domain sleep transition put module into idle. A wakeup domain transition put it back into function.
If CLKTRCTRL=3, any OCP access to module is always granted. Module clocks may be gated according to the clock domain state."
This is the modulemode and clkdm static dependency / dynamic on OMAP3/4 that will guaranty that the OCP clock will be enabled upon any access to this L4_WKUP clock domain IPs. This has nothing to do with the SIDLE mode.
So SIDLE_FORCE is the right solution to still allow the proper clockdomain transition. It will behave exactly like a SIDLE_SMART. And that's probably why they did not implement the smart-idle for that IP.
Quoted 4 lines
For
example, as mentioned earlier in the discussion on this patch, the AM335x documentation states "By definition, initiator may generate read/write transaction as long as it is out of IDLE state."
I saw that sentence, but what is this supposed to mean?
Moreover if AM335X require some specific trick, we should add some flags for that, and not force the usage of a flag that is mostly irrelevant for OMAP3 and 4 just because AM might need it.
Quoted 7 lines
Quoted 7 lines
BTW, I even think the
HWMOD_SWSUP_SIDLEhwmod flag is useless now. It was needed before probably because the idlemodes were wrongly populated.In fact the hwmod flags is really there to *flag* some real HW bug we cannot figure out otherwise, but in that case, the sysc.idlemodes already contains all the information we need to set the proper mode during enable/disable.
Quoted 7 lines
Quoted 2 lines
Duplicating the information is always a source of confusion and might lead to nasty bugs due to the increase of complexity.
You may be misunderstanding the meaning of the
HWMOD_SWSUP_SIDLEflag. It was added to work around IP blocks that had broken smart-idle. These modules definitely do exist; see for example the OMAP3 wdt2, usbhsotg, andusb_host_hshwmods as some examples.
I know, I was mostly referring to the HWMOD_ALWAYS_FORCE_SIDLE. My point about HWMOD_SWSUP_SIDLE is: it is useless for that IP, not in general.
Quoted 3 lines
It might be reasonable to remove the
HWMOD_SWSUP_SIDLEflag from the 32k counter and just test again forHWMOD_ALWAYS_FORCE_SIDLEin the module disable. I'll take a look at this.
Both should be removed as explained before. There is clearly no need for HWMOD_ALWAYS_FORCE_SIDLE.
We are already explicitly listing the limitation through the idlemodes attribute. Only SIDLE_FORCE and SIDLE_NO are supported, so we already know that SIDLE_FORCE is the proper way to fix that limitation for the current OMAPs.
Since there is no other IP with such limitation, we know as well that there will be no side effect.
If, in the future, some more IPs will have that limitation and will not work as expected, it will mean that some other HW bugs will be there, and only these ones will have to be flagged.
But my point is let's keep it simple and not try to anticipate future bugs. This flag is not require today, let's not add it.
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
Quoted 3 lines
Quoted 1 line
I don't think that part is really relevant anymore.
Why?
I'm not sure anymore now :-)
I guess it was because I thought this is mostly a HW issue, and it was detected because HWMOD_SWSUP_SIDLE was set previously. Without that, this IP will behave like a GPTIMER.
Quoted 9 lines
Quoted 7 lines
Quoted 4 lines
Another possible fix would have been to modify the
pm34xx.ccode to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.Neither that one I guess. As soon as we consider force-idle to be equivalent to smart-idle, nothing more is needed.
But they are definitely not equivalent.
Indeed, but in that case, yes, and this is what really matter.
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 2 lines · Benoit
Quoted 1 line · Paul Walmsley
On Thu, 14 Jun 2012, Cousson, Benoit wrote:
(attribution lost)
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the
CORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Do you mean force-idle? Because accessing a module in no-idle is always possible.
Thanks, that's indeed a description bug.
I'm not sure to follow you? My point was it should be: "So we can safely leave the 32k sync timer in force-idle mode, even while we continue to access it." This is what the WA is doing.
I am expressing appreciation to you for pointing out something incorrect in the patch description, which has been fixed in the current version of the patch.
Quoted 10 lines
Quoted 9 lines
SIDLE_NOis the option that makes more sense to me.Consider an IP block with
SIDLE_NOandSIDLE_FORCEbut withoutSIDLE_SMART. When an initiator will access it, the default setting should beSIDLE_NO, for the reason that you identified above: "because accessing a module in no-idle is always possible." On the other hand, we don't know when it's safe to access a module inSIDLE_FORCEunless we have additional information as to how the IP block handles the SIdleReq signal internally, and the characteristics of the clock domain in which it's integrated.
...
Quoted 3 lines
This is the modulemode and clkdm static dependency / dynamic on OMAP3/4 that will guaranty that the OCP clock will be enabled upon any access to this
L4_WKUPclock domain IPs. This has nothing to do with the SIDLE mode.
I want to implement a behavior that does not implicitly assume that an IP block without smart-idle will only exist inside clockdomains which are guaranteed to be active when the kernel is running. That might be true for current WBU chips, but it seems unwise to make that assumption in general.
Quoted 16 lines
Quoted 3 lines
It might be reasonable to remove the
HWMOD_SWSUP_SIDLEflag from the 32k counter and just test again forHWMOD_ALWAYS_FORCE_SIDLEin the module disable. I'll take a look at this.Both should be removed as explained before. There is clearly no need for
HWMOD_ALWAYS_FORCE_SIDLE.We are already explicitly listing the limitation through the idlemodes attribute. Only
SIDLE_FORCEandSIDLE_NOare supported, so we already know thatSIDLE_FORCEis the proper way to fix that limitation for the current OMAPs. Since there is no other IP with such limitation, we know as well that there will be no side effect. If, in the future, some more IPs will have that limitation and will not work as expected, it will mean that some other HW bugs will be there, and only these ones will have to be flagged.
Quoted 2 lines
But my point is let's keep it simple and not try to anticipate future bugs. This flag is not require today, let's not add it.
Which of these two behaviors do you feel is more "future-proof," in general:
1. Implementing a target idle policy that could break if a hardware designer were to skip adding a target smart-idle mode to a module in a clockdomain that might go idle while the kernel was active?
2. Implementing a target idle policy that is guaranteed to allow initiator accesses to succeed by definition?
considering that the implementation cost of either approach is identical?
- Paul
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi Paul,
Quoted 18 lines · Paul Walmsley
Quoted 2 lines · Benoit
Quoted 1 line · Paul Walmsley
On Thu, 14 Jun 2012, Cousson, Benoit wrote:
(attribution lost)
Quoted 11 lines
Quoted 10 lines
Quoted 8 lines
Quoted 5 lines
Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the
CORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-no-idle mode, even while we continue to access it.Do you mean force-idle? Because accessing a module in no-idle is always possible.
Thanks, that's indeed a description bug.
Quoted 7 lines
Quoted 3 lines
I'm not sure to follow you? My point was it should be: "So we can safely leave the 32k sync timer in force-idle mode, even while we continue to access it." This is what the WA is doing.
I am expressing appreciation to you for pointing out something incorrect in the patch description, which has been fixed in the current version of the patch.
OK, thanks for the clarification, I was confused by the sentence :-(.
Quoted 15 lines
Quoted 8 lines
Quoted 8 lines
SIDLE_NOis the option that makes more sense to me.>>> Consider an IP block withSIDLE_NOandSIDLE_FORCEbut withoutSIDLE_SMART. When an initiator will access it, the default setting should beSIDLE_NO, for the reason that you identified above: "because accessing a module in no-idle is always possible." On the other hand, we don't know when it's safe to access a module inSIDLE_FORCEunless we have additional information as to how the IP block handles the SIdleReq signal internally, and the characteristics of the clock domain in which it's integrated....
Quoted 3 lines
This is the modulemode and clkdm static dependency / dynamic on OMAP3/4 that will guaranty that the OCP clock will be enabled upon any access to this
L4_WKUPclock domain IPs. This has nothing to do with the SIDLE mode.
Quoted 5 lines
I want to implement a behavior that does not implicitly assume that an IP block without smart-idle will only exist inside clockdomains which are guaranteed to be active when the kernel is running. That might be true for current WBU chips, but it seems unwise to make that assumption in general.
1- The fact that the IP does not support smart-idle does not change anything regarding the clock domain behavior.
2- So far the assumption is true for all the existing OMAP devices. Let's not anticipate something that will potentially never ever happen.
Quoted 19 lines
Quoted 16 lines
Quoted 3 lines
It might be reasonable to remove the
HWMOD_SWSUP_SIDLEflag from the 32k counter and just test again forHWMOD_ALWAYS_FORCE_SIDLEin the module disable. I'll take a look at this.Both should be removed as explained before. There is clearly no need for
HWMOD_ALWAYS_FORCE_SIDLE.We are already explicitly listing the limitation through the idlemodes attribute. Only
SIDLE_FORCEandSIDLE_NOare supported, so we already know thatSIDLE_FORCEis the proper way to fix that limitation for the current OMAPs. Since there is no other IP with such limitation, we know as well that there will be no side effect. If, in the future, some more IPs will have that limitation and will not work as expected, it will mean that some other HW bugs will be there, and only these ones will have to be flagged.Quoted 2 lines
But my point is let's keep it simple and not try to anticipate future bugs. This flag is not require today, let's not add it.
Quoted 6 lines
Which of these two behaviors do you feel is more "future-proof," in general:
1. Implementing a target idle policy that could break if a hardware designer were to skip adding a target smart-idle mode to a module in a clockdomain that might go idle while the kernel was active?
That's not fully accurate. Even with smart-idle implemented in this module, it will still go to idle automatically without any clock domain dependency properly handled.
The goal of this fix is to adapt the SIDLE management for such module, it will not solve the overall idle management that is anyway handled at clock domain level whatever the SIDLE implementation.
Quoted 2 lines
2. Implementing a target idle policy that is guaranteed to allow initiator accesses to succeed by definition?
It will not, as explained before. This is the clock domain settings that will make the whole thing working properly.
Quoted 1 line
considering that the implementation cost of either approach is identical?
My point is simple, we should not add any new custom flag when all the information to detect such exception are already there in the current data and represent accurately what the HW is doing.
So far every IPs that do not support SIDLE_SMART can/should use SIDLE_FORCE instead.
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi Beno?t,
Quoted 3 lines · Benoit
My point is simple, we should not add any new custom flag when all the information to detect such exception are already there in the current data and represent accurately what the HW is doing.
This seems like the crux of the issue. We don't have sufficient information to detect this exception in our current data, in my view. The software additionally must know when it can rely on a clockdomain remaining active when the MPU is active.
Ideally the hardcoded clockdomain sleep dependencies would be encoded, and we could test the intersection of those and the software-programmable clockdomain sleep dependencies. But such a change seems too complex for the -rc cycle. So the updated patch below uses a clockdomain data flag for this instead.
- Paul
From: Paul Walmsley <[email protected]>
Date: Wed, 4 Jul 2012 05:22:53 -0600
Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer
Kevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c ("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states.
The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the CORE_L3 and CORE_CM clockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states.
It turns out that there is no need to take the 32k sync timer out of idle. The IP block itself probably does not have any native idle handling at all, due to its simplicity. Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the CORE_L3 clockdomain is active. So we can safely leave the 32k sync timer in target-force-idle mode, even while we continue to access it.
This workaround is implemented by defining a new clockdomain flag, CLKDM_ACTIVE_WITH_MPU, that indicates that the clockdomain is guaranteed to be active whenever the MPU is inactive. If an IP block's main functional clock exists inside this clockdomain, and the IP block does not support smart-idle modes, then the hwmod code will place the IP block into target force-idle mode even when enabled. The WKUP clockdomains on OMAP3/4 are marked with this flag. (On OMAP2xxx,
no OCP header existed on the 32k sync timer.) Other clockdomains also
should be marked with this flag, but those changes are deferred until a later merge window, to create a minimal fix.
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
Another possible fix would have been to modify the pm34xx.c code to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.
This patch is a collaboration between Kevin Hilman <[email protected]> and Paul Walmsley <[email protected]>.
Thanks to Vaibhav Hiremath <[email protected]> for providing comments on an earlier version of this patch. Thanks to Tero Kristo <[email protected]> for identifying a bug in an earlier version of this patch. Thanks to Beno?t Cousson <[email protected]> for identifying some bugs in an earlier version of this patch and for implementation comments.
References:
1. Table 16-96 "REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU (SWPU223U), available from:
http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip
2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU (SWPU223U)
3. ibid.
--- arch/arm/mach-omap2/clockdomain.h | 4 +++ arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 1 + arch/arm/mach-omap2/clockdomains44xx_data.c | 4 +-- arch/arm/mach-omap2/omap_hwmod.c | 32 ++++++++++++++++------ 4 files changed, 31 insertions(+), 10 deletions(-)
arch/arm/mach-omap2/clockdomain.h +4 -0
@@ -31,12 +31,16 @@* * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) +* CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is +* active whenever the MPU is active. True for interconnects and +* the WKUP clockdomains. */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0)#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)#define CLKDM_CAN_ENABLE_AUTO (1 << 2)#define CLKDM_CAN_DISABLE_AUTO (1 << 3)#define CLKDM_NO_AUTODEPS (1 << 4) +#define CLKDM_ACTIVE_WITH_MPU (1 << 5)#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +1 -0
@@ -88,4 +88,5 @@ struct clockdomain wkup_common_clkdm = { .name = "wkup_clkdm", .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, + .flags = CLKDM_ACTIVE_WITH_MPU, };
arch/arm/mach-omap2/clockdomains44xx_data.c +2 -2
@@ -1,7 +1,7 @@/* * OMAP4 Clock domains framework * -* Copyright (C) 2009-2011 Texas Instruments, Inc. +* Copyright (C) 2009-2012 Texas Instruments, Inc. * Copyright (C) 2009-2011 Nokia Corporation * * Abhijit Pagare ([email protected])
@@ -381,7 +381,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, };static struct clockdomain emu_sys_44xx_clkdm = {
arch/arm/mach-omap2/omap_hwmod.c +24 -8
@@ -1124,15 +1124,18 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap* _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * -* If module is marked as SWSUP_SIDLE, force the module out of slave -* idle; otherwise, configure it for smart-idle. If module is marked -* as SWSUP_MSUSPEND, force the module out of master standby; -* otherwise, configure it for smart-standby. No return value. +* Ensure that the OCP_SYSCONFIG register for the IP block represented +* by @oh is set to indicate to the PRCM that the IP block is active. +* Usually this means placing the module into smart-idle mode and +* smart-standby, but if there is a bug in the automatic idle handling +* for the IP block, it may need to be placed into the force-idle or +* no-idle variants of these modes. No return value. */ static void _enable_sysc (struct omap_hwmod *oh) {u8 idlemode, sf;u32 v; +bool clkdm_act;if (!oh->class->sysc)return ;
@@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags &CLKDM_ACTIVE_WITH_MPU ) || + (oh->_clk->clkdm && + oh->_clk->clkdm->flags &CLKDM_ACTIVE_WITH_MPU )); +if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART |SIDLE_SMART_WKUP ))) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? +HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
@@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_FORCE :HWMOD_IDLEMODE_SMART ; +/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ +if (oh->flags &HWMOD_SWSUP_SIDLE || + !(oh->class->sysc->idlemodes & + (SIDLE_SMART |SIDLE_SMART_WKUP ))) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode =HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
Signature · 1 line
1.7.10
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 2 lines · Paul Walmsley
So the updated patch below uses a clockdomain data flag for this instead.
Here's a version that's a little cleaner. No functional changes.
- Paul
From: Paul Walmsley <[email protected]>
Date: Wed, 4 Jul 2012 05:22:53 -0600
Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer
Kevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c ("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states.
The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the CORE_L3 and CORE_CM clockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states.
It turns out that there is no need to take the 32k sync timer out of idle. The IP block itself probably does not have any native idle handling at all, due to its simplicity. Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the CORE_L3 clockdomain is active. So we can safely leave the 32k sync timer in target-force-idle mode, even while we continue to access it.
This workaround is implemented by defining a new clockdomain flag, CLKDM_ACTIVE_WITH_MPU, that indicates that the clockdomain is guaranteed to be active whenever the MPU is inactive. If an IP block's main functional clock exists inside this clockdomain, and the IP block does not support smart-idle modes, then the hwmod code will place the IP block into target force-idle mode even when enabled. The WKUP clockdomains on OMAP3/4 are marked with this flag. (On OMAP2xxx,
no OCP header existed on the 32k sync timer.) Other clockdomains also
should be marked with this flag, but those changes are deferred until a later merge window, to create a minimal fix.
Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
Another possible fix would have been to modify the pm34xx.c code to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.
This patch is a collaboration between Kevin Hilman <[email protected]> and Paul Walmsley <[email protected]>.
Thanks to Vaibhav Hiremath <[email protected]> for providing comments on an earlier version of this patch. Thanks to Tero Kristo <[email protected]> for identifying a bug in an earlier version of this patch. Thanks to Beno?t Cousson <[email protected]> for identifying some bugs in an earlier version of this patch and for implementation comments.
References:
1. Table 16-96 "REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU (SWPU223U), available from:
http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip
2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU (SWPU223U)
3. ibid.
--- arch/arm/mach-omap2/clockdomain.h | 4 +++ arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 1 + arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +- arch/arm/mach-omap2/omap_hwmod.c | 32 ++++++++++++++++------ 4 files changed, 30 insertions(+), 9 deletions(-)
arch/arm/mach-omap2/clockdomain.h +4 -0
@@ -31,12 +31,16 @@* * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) +* CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is +* active whenever the MPU is active. True for interconnects and +* the WKUP clockdomains. */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0)#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)#define CLKDM_CAN_ENABLE_AUTO (1 << 2)#define CLKDM_CAN_DISABLE_AUTO (1 << 3)#define CLKDM_NO_AUTODEPS (1 << 4) +#define CLKDM_ACTIVE_WITH_MPU (1 << 5)#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +1 -0
@@ -88,4 +88,5 @@ struct clockdomain wkup_common_clkdm = { .name = "wkup_clkdm", .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, + .flags = CLKDM_ACTIVE_WITH_MPU, };
arch/arm/mach-omap2/clockdomains44xx_data.c +1 -1
@@ -381,7 +381,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, };static struct clockdomain emu_sys_44xx_clkdm = {
arch/arm/mach-omap2/omap_hwmod.c +24 -8
@@ -1124,15 +1124,18 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap* _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * -* If module is marked as SWSUP_SIDLE, force the module out of slave -* idle; otherwise, configure it for smart-idle. If module is marked -* as SWSUP_MSUSPEND, force the module out of master standby; -* otherwise, configure it for smart-standby. No return value. +* Ensure that the OCP_SYSCONFIG register for the IP block represented +* by @oh is set to indicate to the PRCM that the IP block is active. +* Usually this means placing the module into smart-idle mode and +* smart-standby, but if there is a bug in the automatic idle handling +* for the IP block, it may need to be placed into the force-idle or +* no-idle variants of these modes. No return value. */ static void _enable_sysc (struct omap_hwmod *oh) {u8 idlemode, sf;u32 v; +bool clkdm_act;if (!oh->class->sysc)return ;
@@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags &CLKDM_ACTIVE_WITH_MPU ) || + (oh->_clk->clkdm && + oh->_clk->clkdm->flags &CLKDM_ACTIVE_WITH_MPU )); +if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART |SIDLE_SMART_WKUP ))) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? +HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
@@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_FORCE :HWMOD_IDLEMODE_SMART ; +/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ +if (oh->flags &HWMOD_SWSUP_SIDLE || + !(oh->class->sysc->idlemodes & + (SIDLE_SMART |SIDLE_SMART_WKUP ))) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode =HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
Signature · 1 line
1.7.10
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 79 lines · Paul Walmsley
Quoted 2 lines · Paul Walmsley
So the updated patch below uses a clockdomain data flag for this instead.
Here's a version that's a little cleaner. No functional changes.
- Paul
From: Paul Walmsley <[email protected]>
Date: Wed, 4 Jul 2012 05:22:53 -0600
Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timerKevin discovered that commit
c8d82ff68fb6873691536cf33021977efbf5593c("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states.The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the
CORE_L3andCORE_CMclockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states.It turns out that there is no need to take the 32k sync timer out of idle. The IP block itself probably does not have any native idle handling at all, due to its simplicity. Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the
CORE_L3clockdomain is active. So we can safely leave the 32k sync timer in target-force-idle mode, even while we continue to access it.This workaround is implemented by defining a new clockdomain flag,
CLKDM_ACTIVE_WITH_MPU, that indicates that the clockdomain is guaranteed to be active whenever the MPU is inactive. If an IP block's main functional clock exists inside this clockdomain, and the IP block does not support smart-idle modes, then the hwmod code will place the IP block into target force-idle mode even when enabled. The WKUP clockdomains on OMAP3/4 are marked with this flag. (On OMAP2xxx,
no OCP header existed on the 32k sync timer.) Other clockdomains also
should be marked with this flag, but those changes are deferred until a later merge window, to create a minimal fix.Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case.
Another possible fix would have been to modify the
pm34xx.ccode to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code.This patch is a collaboration between Kevin Hilman <[email protected]> and Paul Walmsley <[email protected]>.
Thanks to Vaibhav Hiremath <[email protected]> for providing comments on an earlier version of this patch. Thanks to Tero Kristo <[email protected]> for identifying a bug in an earlier version of this patch. Thanks to Benoît Cousson <[email protected]> for identifying some bugs in an earlier version of this patch and for implementation comments.
References:
1. Table 16-96 "
REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU (SWPU223U), available from:http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU (SWPU223U)
Quoted 8 lines
3. ibid.
Cc Tony Lindgren <[email protected]>Cc Vaibhav Hiremath <[email protected]>Cc Benoît Cousson <[email protected]>Cc Tero Kristo <[email protected]>Cc Kevin Hilman <[email protected]>Signed-off-by Paul Walmsley <[email protected]>
I confirm this version is now allowing CORE to hit retention during suspend.
Benoit, I hope this is OK with you. We need a fix for this in v3.5 since this is last core bug preventing CORE retention in v3.5.
Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 4 lines · Kevin Hilman
Tested-by Kevin Hilman <[email protected]>I confirm this version is now allowing CORE to hit retention during suspend.
Thanks, want me to add your S-o-b also?
- Paul
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
In reply to Kevin HilmanHi Kevin,
On 07/04/2012 04:27 PM, Kevin Hilman wrote:
[...]
Quoted 7 lines
Tested-by Kevin Hilman <[email protected]>I confirm this version is now allowing CORE to hit retention during suspend.
Benoit, I hope this is OK with you. We need a fix for this in v3.5 since this is last core bug preventing CORE retention in v3.5.
On OMAP4 as well? I've just tried with the hwmod fix for AESS and USB and still cannot reach RET.
Am I missing some other patches for OMAP4?
Regards,
Benoit
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 11 lines · Benoit Cousson
Hi Kevin,
On 07/04/2012 04:27 PM, Kevin Hilman wrote:
[...]
Quoted 5 lines
Tested-by Kevin Hilman <[email protected]>I confirm this version is now allowing CORE to hit retention during suspend.
Quoted 7 lines
Quoted 2 lines
Benoit, I hope this is OK with you. We need a fix for this in v3.5 since this is last core bug preventing CORE retention in v3.5.
On OMAP4 as well? I've just tried with the hwmod fix for AESS and USB and still cannot reach RET.
Am I missing some other patches for OMAP4?
You need also fixes for sl2if and mcpdm in addition to above.
-Tero
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 15 lines · Tero Kristo
Quoted 14 lines · Benoit Cousson
Hi Kevin,
On 07/04/2012 04:27 PM, Kevin Hilman wrote:
[...]
Quoted 7 lines
Tested-by Kevin Hilman <[email protected]>I confirm this version is now allowing CORE to hit retention during suspend.
Benoit, I hope this is OK with you. We need a fix for this in v3.5 since this is last core bug preventing CORE retention in v3.5.
Quoted 6 lines
Quoted 4 lines
On OMAP4 as well? I've just tried with the hwmod fix for AESS and USB and still cannot reach RET.
Am I missing some other patches for OMAP4?
You need also fixes for sl2if and mcpdm in addition to above.
Are they in some lo branch already?
Benoit
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 11 lines · Benoit Cousson
Quoted 8 lines · Tero Kristo
Quoted 5 lines · Benoit Cousson
On OMAP4 as well? I've just tried with the hwmod fix for AESS and USB and still cannot reach RET.
Am I missing some other patches for OMAP4?
You need also fixes for sl2if and mcpdm in addition to above.
Are they in some lo branch already?
The old version of these patches are in the 'sl2if_mcpdm_reset_fix_3.5rc` branch of git://git.pwsan.com/linux-2.6 - they haven't yet been updated and tested per Beno?t's comments. If someone else wants to take that over for 3.5-rc, by all means please do.
- Paul
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
In reply to Paul WalmsleyHi Paul,
Quoted 6 lines · Paul Walmsley
Quoted 2 lines · Paul Walmsley
So the updated patch below uses a clockdomain data flag for this instead.
Here's a version that's a little cleaner. No functional changes.
[...]
arch/arm/mach-omap2/omap_hwmod.c static void _enable_sysc(struct omap_hwmod *oh) · line 1149
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-2@@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || + (oh->_clk->clkdm &&
This is crashing on OMAP4 due to a NULL oh->_clk that can happen on some hwmod.
+ (oh->_clk && oh->_clk->clkdm &&
Is fixing the issue.
Regards,
Benoit
Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +7
-0+ oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU)); +if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART |SIDLE_SMART_WKUP ))) + idlemode =HWMOD_IDLEMODE_FORCE ; +else + idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? +HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ;_set_slave_idlemode (oh, idlemode, &v); }
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi Beno?t
Quoted 15 lines · Benoit Cousson
arch/arm/mach-omap2/omap_hwmod.c static void _enable_sysc(struct omap_hwmod *oh) · line 1149
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-2@@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || + (oh->_clk->clkdm &&This is crashing on OMAP4 due to a NULL
oh->_clkthat can happen on some hwmod.(quoted diff) +1
-0+ (oh->_clk && oh->_clk->clkdm &&
Quoted 1 line
Is fixing the issue.
Thanks, just made the change and pushed the patch up togit://git.pwsan.com/linux-2.6 in the branch 'omap_fixes_c_3.5rc'
- Paul
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Quoted 17 lines · Paul Walmsley
Hi Benoît
Quoted 13 lines · Benoit Cousson
arch/arm/mach-omap2/omap_hwmod.c static void _enable_sysc(struct omap_hwmod *oh) · line 1149
Quoted 9 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-2@@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_NO :HWMOD_IDLEMODE_SMART ; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || + (oh->_clk->clkdm &&This is crashing on OMAP4 due to a NULL
oh->_clkthat can happen on some hwmod.
Quoted 6 lines
Quoted 3 lines
(quoted diff) +1
-0+ (oh->_clk && oh->_clk->clkdm &&Is fixing the issue.
Thanks, just made the change and pushed the patch up to
git://git.pwsan.com/linux-2.6in the branch 'omap_fixes_c_3.5rc'
OK, to ensure this fix gets into v3.5-rc, I'm taking the version from this branch and queuing up as a PM fix Tony.
Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
In reply to Paul WalmsleyHi Paul,
Quoted 4 lines · Paul Walmsley
Hi Beno?t,
On Fri, 15 Jun 2012, Cousson, Benoit wrote:
Quoted 8 lines
Quoted 3 lines
My point is simple, we should not add any new custom flag when all the information to detect such exception are already there in the current data and represent accurately what the HW is doing.
This seems like the crux of the issue. We don't have sufficient information to detect this exception in our current data, in my view. The software additionally must know when it can rely on a clockdomain remaining active when the MPU is active.
Yes, indeed, but that will be accurate mostly for OMAP3.
On OMAP4, *in theory* the dynamic dependency should always ensure that a clock domain will be accessible upon any initiator requests. In that case the notion of a domain active when the MPU is active become a little bit less accurate.
Except when we have to force the static dep because of HW bugs workaround. In that case, we are in the same situation than OMAP3.
Quoted 5 lines
Ideally the hardcoded clockdomain sleep dependencies would be encoded, and we could test the intersection of those and the software-programmable clockdomain sleep dependencies. But such a change seems too complex for the -rc cycle. So the updated patch below uses a clockdomain data flag for this instead.
Yep, I do agree that encoding that kind of information will require more thought and much more code.
I have the feeling that some information about the IP idle behavior should help figuring out that module like counter_32k, GPIO or mailbox can be handled without real SW control.
This intermediate approach is thus good for the moment.
Quoted 3 lines
From: Paul Walmsley <[email protected]>
Date: Wed, 4 Jul 2012 05:22:53 -0600
Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer
[...]
arch/arm/mach-omap2/omap_hwmod.c static void _idle_sysc(struct omap_hwmod *oh) · line 1222
Quoted 7 lines
arch/arm/mach-omap2/omap_hwmod.c +1
-2@@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_FORCE :HWMOD_IDLEMODE_SMART ; +/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
What do you mean here?
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 2/12 ARM: OMAP2+: hwmod code/data: fix 32K sync timer
Hi Beno?t
Quoted 9 lines · Benoit Cousson
Quoted 3 lines
From: Paul Walmsley <[email protected]>
Date: Wed, 4 Jul 2012 05:22:53 -0600
Subject: [PATCH] ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer[...]
Quoted 3 lines
(quoted diff) +0
-0@@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags;
Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod.c static void _idle_sysc(struct omap_hwmod *oh) · line 1222
Quoted 4 lines
arch/arm/mach-omap2/omap_hwmod.c +1
-2if (sf &SYSC_HAS_SIDLEMODE ) { - idlemode = (oh->flags &HWMOD_SWSUP_SIDLE ) ? -HWMOD_IDLEMODE_FORCE :HWMOD_IDLEMODE_SMART ; +/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ What do you mean here?
We're not programming IP block target idle modes to smart idle + wakeup on OMAP4. We're only programming them to smart idle :-(
- Paul
Paul Walmsley
maintainerPATCH v2 3/12 ARM: OMAP4+: hwmod: fix issue causing IPs not going back to Smart-Standby
In reply to Paul WalmsleyFrom: Djamil Elaidi <[email protected]>
If an IP is configured in Smart-Standby-Wakeup, when disabling wakeup feature the IP will not go back to Smart-Standby, but will remain in Smart-Standby-Wakeup.
--- arch/arm/mach-omap2/omap_hwmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-omap2/omap_hwmod.c +1 -1
@@ -530,7 +530,7 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)if (oh->class->sysc->idlemodes &SIDLE_SMART_WKUP )_set_slave_idlemode (oh,HWMOD_IDLEMODE_SMART , v);if (oh->class->sysc->idlemodes &MSTANDBY_SMART_WKUP ) -_set_master_standbymode (oh,HWMOD_IDLEMODE_SMART_WKUP , v); +_set_master_standbymode (oh,HWMOD_IDLEMODE_SMART , v);/* XXX test pwrdm_get_wken for this hwmod's subsystem */
Paul Walmsley
maintainerPATCH v2 4/12 ARM: OMAP4: hwmod data: fix 32k sync timer idle modes
In reply to Paul WalmsleyThe 32k sync timer IP block target idle modes are incorrect in the hwmod data are incorrect. The IP block does not support any smart-idle modes. Update the data to reflect the correct modes.
This problem was initially identified and a diff fragment posted to the lists by Beno?t Cousson <[email protected]>.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +1 -2
@@ -393,8 +393,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO), .sysc_fields = &omap_hwmod_sysc_type1, };
PATCH v2 4/12 ARM: OMAP4: hwmod data: fix 32k sync timer idle modes
Quoted 2 lines · Paul Walmsley
The 32k sync timer IP block target idle modes are incorrect in the hwmod data are incorrect.
Nit: Is there too many "incorrect" in this sentence?
Quoted 5 lines
The IP block does not support any
smart-idle modes. Update the data to reflect the correct modes.This problem was initially identified and a diff fragment posted to the lists by Beno?t Cousson <[email protected]>.
Thanks for taking care of that patch.
Benoit
Quoted 24 lines
Signed-off-by Paul Walmsley <[email protected]>Cc Beno?t Cousson <[email protected]>Cc Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)arch/arm/mach-omap2/omap_hwmod_44xx_data.c +1
-2@@ -393,8 +393,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO), .sysc_fields = &omap_hwmod_sysc_type1, };
Paul Walmsley
maintainerPATCH v2 4/12 ARM: OMAP4: hwmod data: fix 32k sync timer idle modes
Quoted 5 lines · Benoit
Quoted 2 lines · Paul Walmsley
The 32k sync timer IP block target idle modes are incorrect in the hwmod data are incorrect.
Nit: Is there too many "incorrect" in this sentence?
Thanks; patch updated.
- Paul
Paul Walmsley
maintainerPATCH v2 5/12 ARM: OMAP2+: hwmod: add setup_preprogram hook
In reply to Paul WalmsleyAfter reset, some IP blocks cannot indicate to the PRCM that they are inactive until they are configured. Some examples on OMAP4 include the AESS and FSUSB IP blocks.
To fix this cleanly, this patch adds another optional function pointer, setup_preprogram, to the IP block's hwmod data. The function that is pointed to is called by the hwmod code immediately after the IP block is reset.
--- arch/arm/mach-omap2/omap_hwmod.c | 21 ++++++++++++++++++++- arch/arm/plat-omap/include/plat/omap_hwmod.h | 9 +++++++++ 2 files changed, 29 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/omap_hwmod.c +20 -1
@@ -2108,6 +2108,23 @@ static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) }/** +* _setup_preprogram - Pre-program an IP block during the _setup() process +* @oh: struct omap_hwmod * +* +* Some IP blocks (such as AESS) require some additional programming +* after reset before they can enter idle. If a function pointer to +* do so is present in the hwmod data, then call it and pass along the +* return value; otherwise, return 0. +*/ +static int __init _setup_preprogram (struct omap_hwmod *oh) +{ +if (!oh->class->setup_preprogram) +return 0 ; + +return oh->class->setup_preprogram (oh); +} + +/** * _setup_reset - reset an IP block during the setup process * @oh: struct omap_hwmod * *
@@ -2229,8 +2246,10 @@ static int __init _setup(struct omap_hwmod *oh, void *data)_setup_iclk_autoidle (oh); -if (!_setup_reset (oh)) +if (!_setup_reset (oh)) { +_setup_preprogram (oh);_setup_postsetup (oh); + }return 0 ; }
arch/arm/plat-omap/include/plat/omap_hwmod.h +9 -0
@@ -467,6 +467,7 @@ struct omap_hwmod_omap4_prcm {* @rev: revision of the IP class * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown * @reset: ptr to fn to be executed in place of the standard hwmod reset fn +* @setup_preprogram: ptr to fn to be executed after the reset in _setup() * * Represent the class of a OMAP hardware "modules" (e.g. timer, * smartreflex, gpio, uart...)
@@ -483,6 +484,13 @@ struct omap_hwmod_omap4_prcm {* executed in place of the standard hwmod _reset() code in * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have * unusual reset sequences - usually processor IP blocks like the IVA. +* +* @setup_preprogram is called between the calls to _setup_reset() and +* _setup_postsetup(). It is intended to be used for IP blocks that +* require some initial configuration during their first +* initialization. (For example, the AESS IP block on OMAP4+ cannot +* enter idle until its internal autogating bit is set.) Most IP blocks +* will not need this. */ struct omap_hwmod_class {const char *name;
@@ -490,6 +498,7 @@ struct omap_hwmod_class {u32 rev;int (*pre_shutdown)(struct omap_hwmod *oh);int (*reset)(struct omap_hwmod *oh); +int (*setup_preprogram)(struct omap_hwmod *oh); };/**
Paul Walmsley
maintainerPATCH v2 6/12 ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init
In reply to Paul WalmsleyAdd HWMOD_EXT_OPT_MAIN_CLK flag to indicate that this IP block is dependent on an off-chip functional clock that is not guaranteed to be present during initialization. IP blocks marked with this flag are left in the INITIALIZED state during kernel init.
This is a workaround for a hardware problem. It should be possible to guarantee that at least one clock source will be present and active for any IP block's main functional clock. This ensures that the hwmod code can enable and reset the IP block. Resetting the IP block during kernel init prevents any bogus bootloader, ROM code, or previous OS configuration from affecting the kernel. Hopefully a clock multiplexer can be added on future SoCs.
N.B., at some point in the future, it should be possible to query the clock framework for this type of information. Then this flag should no longer be needed.
--- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 9 insertions(+)
arch/arm/mach-omap2/omap_hwmod.c +3 -0
@@ -2140,6 +2140,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)if (oh->_state != _HWMOD_STATE_INITIALIZED)return -EINVAL ; +if (oh->flags &HWMOD_EXT_OPT_MAIN_CLK ) +return -EPERM ; +if (oh->rst_lines_cnt ==0 ) { r =_enable (oh);if (r) {
arch/arm/plat-omap/include/plat/omap_hwmod.h +6 -0
@@ -417,6 +417,11 @@ struct omap_hwmod_omap4_prcm {* running on the chip (e.g., the MPU is in idle). For such modules, * fine-grained PM runtime-based idle control is simply a waste of * CPU cycles. +* HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for +* this IP block comes from an off-chip source and is not always +* enabled. This prevents the hwmod code from being able to +* enable and reset the IP block early. XXX Eventually it should +* be possible to query the clock framework for this information. */ #define HWMOD_SWSUP_SIDLE (1 << 0)#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -428,6 +433,7 @@ struct omap_hwmod_omap4_prcm {#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)#define HWMOD_16BIT_REG (1 << 8)#define HWMOD_ALWAYS_FORCE_SIDLE (1 << 9) +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 10)/* * omap_hwmod._int_flags definitions
Paul Walmsley
maintainerPATCH v2 7/12 ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
In reply to Paul WalmsleyEnable the AESS auto-gating control bit during AESS hwmod setup. This fixes the following boot warning on OMAP4:
omap_hwmod: aess: _wait_target_disable failed
Without this patch, the AESS IP block does not indicate to the PRCM that it is idle after it is reset. This prevents some types of SoC power management until something sets the auto-gating control bit.
This second version of this patch moves the control functions to include/linux/platform_data/aess.h at Tony's request:
http://www.spinics.net/lists/arm-kernel/msg178329.html
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 + include/linux/platform_data/aess.h | 76 ++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 include/linux/platform_data/aess.h
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +3 -0
@@ -20,6 +20,8 @@#include <linux/io.h> +#include <linux/platform_data/aess.h> +#include <plat/omap_hwmod.h> #include <plat/cpu.h> #include <plat/i2c.h>
@@ -313,6 +315,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {static struct omap_hwmod_class omap44xx_aess_hwmod_class = { .name ="aess" , .sysc = &omap44xx_aess_sysc, + .setup_preprogram = hwmod_aess_preprogram, };/* aess */
include/linux/platform_data/aess.h new file +76 -0
76 lines not on this page · raw message
Tony Lindgren
maintainerPATCH v2 7/12 ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
Hi,
Few comments below on making the platform_data work better along with other archs.
Quoted 2 lines · Paul Walmsley
Enable the AESS auto-gating control bit during AESS hwmod setup. This fixes the following boot warning on OMAP4:
...
include/linux/platform_data/aess.h
Quoted 2 lines
include/linux/platform_data/aess.h new file +0
-0
This should be include/linux/platform_data/omap-aess.h or similar as there are other aess controllers too.
include/linux/platform_data/aess.h line 36
Quoted 9 lines
include/linux/platform_data/aess.h new file +9
-0+/* +* AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP +* block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's +* base address +*/ +#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c + +/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */ +#define AESS_AUTO_GATING_ENABLE_SHIFT 0
Also these should be OMAP_AESS_AUTOGATING etc, or even better, XYZ_AESS_AUTOGATING where XYZ is the type of the AESS controller.
Quoted 5 lines
include/linux/platform_data/aess.h new file +5
-0+/** +* aess_enable_autogating - enable AESS internal autogating +* @oh: struct omap_hwmod * +* +* Enable internal autogating on the AESS. This allows the AESS to
include/linux/platform_data/aess.h line 52
Quoted 10 lines
include/linux/platform_data/aess.h new file +10
-0+* indicate that it is idle to the OMAP PRCM. Returns 0. +*/ +static void aess_enable_autogating (void __iomem *base) +{ +u32 v; + +/* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */ + v =1 <<AESS_AUTO_GATING_ENABLE_SHIFT ; +writel (v, base +AESS_AUTO_GATING_ENABLE_OFFSET ); +}
This should be static inline function as it's in the header, and again something like omap_aess_enable_autogating.
Quoted 11 lines
include/linux/platform_data/aess.h new file +11
-0+/** +* hwmod_aess_preprogram - enable AESS internal autogating (called by hwmod) +* @oh: struct omap_hwmod * +* +* The AESS will not IdleAck to the PRCM until its internal autogating +* is enabled. Since internal autogating is disabled by default after +* AESS reset, we must enable autogating after the hwmod code resets +* the AESS. Returns 0. +*/ +static int __maybe_unused hwmod_aess_preprogram (struct omap_hwmod *oh) +{
include/linux/platform_data/aess.h line 74
Quoted 10 lines
include/linux/platform_data/aess.h new file +10
-0+void __iomem *va; + + va =omap_hwmod_get_mpu_rt_va (oh); +if (!va) +return -EINVAL ; + +aess_enable_autogating (va); + +return 0 ; +}
Then this function should not be in this header, instead it should be a static function somewhere in the omap hwmod code in some .c file. That's because this header should only have omap aess specific driver code, no hwmod code should be needed here.
Regards,
Tony
Paul Walmsley
maintainerPATCH v2 7/12 ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
Hi
(revised patch below)
Quoted 7 lines · Tony Lindgren
include/linux/platform_data/aess.h
Quoted 2 lines · Paul Walmsley
include/linux/platform_data/aess.h new file +0
-0This should be
include/linux/platform_data/omap-aess.hor similar as there are other aess controllers too.
Hmm, I guess there could be other SoCs that include this IP block; probably there is nothing OMAP-specific about it. So I moved this file to include/sound/aess.h. What do you think?
Quoted 4 lines
Quoted 4 lines
+/*
+ *AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
+ * block'sAESS_AUTO_GATING_ENABLE__1register from the IP block's
+ * base address
Quoted 8 lines
include/linux/platform_data/aess.h
Quoted 5 lines
+ */
include/linux/platform_data/aess.h new file +4
-0+#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c + +/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */ +#define AESS_AUTO_GATING_ENABLE_SHIFT 0Also these should be
OMAP_AESS_AUTOGATINGetc, or even better,XYZ_AESS_AUTOGATINGwhere XYZ is the type of the AESS controller.
Hmm, do you think this is really needed? The other files in include/sound don't have SOUND_ or AUDIO_ prefixe.
Quoted 2 lines
This should be static inline function as it's in the header, and again something like
omap_aess_enable_autogating.
I made it static inline, but didn't rename this one by the same rationale above.
Quoted 18 lines
Quoted 18 lines
include/linux/platform_data/aess.h new file +18
-0+/** +* hwmod_aess_preprogram - enable AESS internal autogating (called by hwmod) +* @oh: struct omap_hwmod * +* +* The AESS will not IdleAck to the PRCM until its internal autogating +* is enabled. Since internal autogating is disabled by default after +* AESS reset, we must enable autogating after the hwmod code resets +* the AESS. Returns 0. +*/ +static int __maybe_unused hwmod_aess_preprogram (struct omap_hwmod *oh) +{ +void __iomem *va; + + va =omap_hwmod_get_mpu_rt_va (oh); +if (!va) +return -EINVAL ; + +aess_enable_autogating (va);
Quoted 8 lines
include/linux/platform_data/aess.h
Quoted 3 lines
include/linux/platform_data/aess.h new file +3
-0+ +return 0 ; +}Then this function should not be in this header, instead it should be a static function somewhere in the omap hwmod code in some .c file. That's because this header should only have omap aess specific driver code, no hwmod code should be needed here.
Moved this to arch/arm/mach-omap2/omap_hwmod_reset.c and prefixed it with "omap_".
Are you okay with this approach?
- Paul
From: Paul Walmsley <[email protected]>
Date: Thu, 14 Jun 2012 03:35:13 -0600
Subject: [PATCH] ARM: OMAP4+: AESS: enable internal auto-gating during
initial setup
Enable the AESS auto-gating control bit during AESS hwmod setup. This fixes the following boot warning on OMAP4:
omap_hwmod: aess: _wait_target_disable failed
Without this patch, the AESS IP block does not indicate to the PRCM that it is idle after it is reset. This prevents some types of SoC power management until something sets the auto-gating control bit.
This second version of this patch moves the control functions to include/linux/platform_data/aess.h at Tony's request:
http://www.spinics.net/lists/arm-kernel/msg178329.html
--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_reset.c | 52 +++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++ include/sound/aess.h | 53 ++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/omap_hwmod_reset.c create mode 100644 include/sound/aess.h
arch/arm/mach-omap2/Makefile +1 -1
@@ -7,7 +7,7 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap-2-3-common = irq.o sdrc.o -hwmod-common = omap_hwmod.o \ +hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o clock-common = clock.o clock_common_data.o \ clkt_dpll.o clkt_clksel.o
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +1 -0
@@ -313,6 +313,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {static struct omap_hwmod_class omap44xx_aess_hwmod_class = { .name ="aess" , .sysc = &omap44xx_aess_sysc, + .setup_preprogram = omap_hwmod_aess_preprogram, };/* aess */
arch/arm/mach-omap2/omap_hwmod_reset.c new file +52 -0
52 lines not on this page · raw message
arch/arm/plat-omap/include/plat/omap_hwmod.h +5 -0
@@ -662,6 +662,11 @@ extern int omap2430_hwmod_init(void);extern int omap3xxx_hwmod_init (void );extern int omap44xx_hwmod_init (void ); +/* Custom reset & preprogram stub prototypes - from omap_hwmod_reset.c */ + +extern int omap_hwmod_aess_preprogram (struct omap_hwmod *oh); + +extern int __init omap_hwmod_register_links (struct omap_hwmod_ocp_if **ois);#endif
include/sound/aess.h new file +53 -0
53 lines not on this page · raw message
Signature · 1 line
1.7.10
Tony Lindgren
maintainerPATCH v2 7/12 ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
Quoted 14 lines · Paul Walmsley
Hi
(revised patch below)
Quoted 7 lines · Tony Lindgren
include/linux/platform_data/aess.h
Quoted 2 lines · Paul Walmsley
include/linux/platform_data/aess.h new file +0
-0This should be
include/linux/platform_data/omap-aess.hor similar as there are other aess controllers too.
Quoted 3 lines
Hmm, I guess there could be other SoCs that include this IP block; probably there is nothing OMAP-specific about it. So I moved this file to
include/sound/aess.h. What do you think?
Sounds good to me.
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
+/*
+ *AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
+ * block'sAESS_AUTO_GATING_ENABLE__1register from the IP block's
+ * base addressQuoted 8 lines
include/linux/platform_data/aess.h
Quoted 5 lines
+ */
include/linux/platform_data/aess.h new file +4
-0+#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c + +/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */ +#define AESS_AUTO_GATING_ENABLE_SHIFT 0Also these should be
OMAP_AESS_AUTOGATINGetc, or even better,XYZ_AESS_AUTOGATINGwhere XYZ is the type of the AESS controller.
Quoted 2 lines
Hmm, do you think this is really needed? The other files in
include/sounddon't haveSOUND_orAUDIO_prefixe.
No you're right, those parts should follow what the driver is doing.
Quoted 5 lines
Quoted 2 lines
This should be static inline function as it's in the header, and again something like
omap_aess_enable_autogating.I made it static inline, but didn't rename this one by the same rationale above.
OK
Quoted 27 lines
Quoted 18 lines
Quoted 18 lines
include/linux/platform_data/aess.h new file +18
-0+/** +* hwmod_aess_preprogram - enable AESS internal autogating (called by hwmod) +* @oh: struct omap_hwmod * +* +* The AESS will not IdleAck to the PRCM until its internal autogating +* is enabled. Since internal autogating is disabled by default after +* AESS reset, we must enable autogating after the hwmod code resets +* the AESS. Returns 0. +*/ +static int __maybe_unused hwmod_aess_preprogram (struct omap_hwmod *oh) +{ +void __iomem *va; + + va =omap_hwmod_get_mpu_rt_va (oh); +if (!va) +return -EINVAL ; + +aess_enable_autogating (va);Quoted 8 lines
include/linux/platform_data/aess.h
Quoted 3 lines
include/linux/platform_data/aess.h new file +3
-0+ +return 0 ; +}Then this function should not be in this header, instead it should be a static function somewhere in the omap hwmod code in some .c file. That's because this header should only have omap aess specific driver code, no hwmod code should be needed here.
Quoted 4 lines
Moved this to
arch/arm/mach-omap2/omap_hwmod_reset.cand prefixed it with "omap_".Are you okay with this approach?
Yup looks good to me, thanks! We should probably get an ack from the ASoC people for the header changes.
Regards,
Tony
Quoted 195 lines
- Paul
From: Paul Walmsley <[email protected]>
Date: Thu, 14 Jun 2012 03:35:13 -0600
Subject: [PATCH] ARM: OMAP4+: AESS: enable internal auto-gating during
initial setupEnable the AESS auto-gating control bit during AESS hwmod setup. This fixes the following boot warning on OMAP4:
omap_hwmod: aess:_wait_target_disablefailedWithout this patch, the AESS IP block does not indicate to the PRCM that it is idle after it is reset. This prevents some types of SoC power management until something sets the auto-gating control bit.
This second version of this patch moves the control functions to
include/linux/platform_data/aess.hat Tony's request:http://www.spinics.net/lists/arm-kernel/msg178329.htmlSigned-off-by Paul Walmsley <[email protected]>Cc Beno?t Cousson <[email protected]>Cc P?ter Ujfalusi <[email protected]>Cc Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_reset.c | 52 +++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++ include/sound/aess.h | 53 ++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/omap_hwmod_reset.c create mode 100644 include/sound/aess.harch/arm/mach-omap2/Makefile +1
-1@@ -7,7 +7,7 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap-2-3-common = irq.o sdrc.o -hwmod-common = omap_hwmod.o \ +hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o clock-common = clock.o clock_common_data.o \ clkt_dpll.o clkt_clksel.oarch/arm/mach-omap2/omap_hwmod_44xx_data.c +1
-0@@ -313,6 +313,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {static struct omap_hwmod_class omap44xx_aess_hwmod_class = { .name ="aess" , .sysc = &omap44xx_aess_sysc, + .setup_preprogram = omap_hwmod_aess_preprogram, };/* aess */ arch/arm/mach-omap2/omap_hwmod_reset.c new file +52
-0@@ -0,0 +1,52 @@ +/* +* OMAP IP block custom reset and preprogramming stubs +* +* Copyright (C) 2012 Texas Instruments, Inc. +* Paul Walmsley +* +* A small number of IP blocks need custom reset and preprogramming +* functions. The stubs in this file provide a standard way for the +* hwmod code to call these functions, which are to be located under +* drivers/. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation version 2. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ +#include <linux/kernel.h> + +#include <plat/omap_hwmod.h> + +#include <sound/aess.h> + +/** +* omap_hwmod_aess_preprogram - enable AESS internal autogating +* @oh: struct omap_hwmod * +* +* The AESS will not IdleAck to the PRCM until its internal autogating +* is enabled. Since internal autogating is disabled by default after +* AESS reset, we must enable autogating after the hwmod code resets +* the AESS. Returns 0. +*/ +int omap_hwmod_aess_preprogram (struct omap_hwmod *oh) +{ +void __iomem *va; + + va =omap_hwmod_get_mpu_rt_va (oh); +if (!va) +return -EINVAL ; + +aess_enable_autogating (va); + +return 0 ; +}arch/arm/plat-omap/include/plat/omap_hwmod.h +5
-0@@ -662,6 +662,11 @@ extern int omap2430_hwmod_init(void);extern int omap3xxx_hwmod_init (void );extern int omap44xx_hwmod_init (void ); +/* Custom reset & preprogram stub prototypes - from omap_hwmod_reset.c */ + +extern int omap_hwmod_aess_preprogram (struct omap_hwmod *oh); + +extern int __init omap_hwmod_register_links (struct omap_hwmod_ocp_if **ois);#endif include/sound/aess.h new file +53
-0@@ -0,0 +1,53 @@ +/* +* AESS IP block reset +* +* Copyright (C) 2012 Texas Instruments, Inc. +* Paul Walmsley +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation version 2. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ +#ifndef __SOUND_AESS_H__ +#define __SOUND_AESS_H__ + +#include <linux/kernel.h> +#include <linux/io.h> + +/* +* AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP +* block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's +* base address +*/ +#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c + +/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */ +#define AESS_AUTO_GATING_ENABLE_SHIFT 0 + +/** +* aess_enable_autogating - enable AESS internal autogating +* @oh: struct omap_hwmod * +* +* Enable internal autogating on the AESS. This allows the AESS to +* indicate that it is idle to the OMAP PRCM. Returns 0. +*/ +static inline void aess_enable_autogating (void __iomem *base) +{ +u32 v; + +/* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */ + v =1 <<AESS_AUTO_GATING_ENABLE_SHIFT ; +writel (v, base +AESS_AUTO_GATING_ENABLE_OFFSET ); +} + +#endif /* __SOUND_AESS_H__ */ Signature · 1 line
1.7.10
Paul Walmsley
maintainerPATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
In reply to Paul WalmsleyOn boot, the sl2if module can't be enabled. The following message is logged:
omap_hwmod: sl2if: cannot be enabled for reset (3)
This is probably because the SL2IF is still being held in hardreset. The SL2IF's hardreset line is shared with one of the IVAHD's hardreset lines; see for example Table 3-536 "RM_IVAHD_RSTCTRL" in the OMAP4430 TRM Rev. AA (SWPU231AA). To work around this, add the SL2IF's hardreset line to the hwmod data. This is correct from a hardware perspective and also will prevent the hwmod from attempting to enable the SL2IF during reset. The driver for this IP block will need to handle its integration until the appropriate way to handle the IVAHD integration can be elucidated.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +7 -0
@@ -2597,15 +2597,22 @@ static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = { .name = "sl2if", }; +static struct omap_hwmod_rst_info omap44xx_sl2if_resets[] = { + { .name ="logic" , .rst_shift =2 }, +}; +/* sl2if */ static struct omap_hwmod omap44xx_sl2if_hwmod = { .name ="sl2if" , .class = &omap44xx_sl2if_hwmod_class, .clkdm_name ="ivahd_clkdm" , + .rst_lines = omap44xx_sl2if_resets, + .rst_lines_cnt =ARRAY_SIZE (omap44xx_sl2if_resets), .prcm = { .omap4 = { .clkctrl_offs =OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET , .context_offs =OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET , + .rstctrl_offs =OMAP4_RM_IVAHD_RSTCTRL_OFFSET , .modulemode =MODULEMODE_HWCTRL , }, },
PATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
Hi Paul,
Quoted 5 lines · Paul Walmsley
On boot, the sl2if module can't be enabled. The following message is logged:
omap_hwmod: sl2if: cannot be enabled for reset (3)
Quoted 9 lines
This is probably because the SL2IF is still being held in hardreset. The SL2IF's hardreset line is shared with one of the IVAHD's hardreset lines; see for example Table 3-536 "
RM_IVAHD_RSTCTRL" in the OMAP4430 TRM Rev. AA (SWPU231AA). To work around this, add the SL2IF's hardreset line to the hwmod data. This is correct from a hardware perspective and also will prevent the hwmod from attempting to enable the SL2IF during reset. The driver for this IP block will need to handle its integration until the appropriate way to handle the IVAHD integration can be elucidated.
I don't think we should allow that at hwmod level. This line is already handled by the IVAHD hwmod. We will then have some potential issue since nothing will prevent the concurrent access.
Moreover that IP is only used by the IVAHD and thus should be handled by the same driver. The SL2 being inside the IVA subsystem, it should be reset when the IVA will be reset and thus does not require an individual control.
I guess, we should just mark the dependency with some external power resource to avoid the fmwk to try to enable that automatically.
It is similar to DSS sub IPs and to some extend McPDM for my point of view.
Maybe we should rename HWMOD_EXT_OPT_MAIN_CLK with something more generic like HWMOD_EXT_POWER_DEP to highlight the dependency with an external resource. It can be a external clock or another module.
Regards,
Benoit
Quoted 40 lines
Signed-off-by Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 7 +++++++ 1 file changed, 7 insertions(+)arch/arm/mach-omap2/omap_hwmod_44xx_data.c +7
-1@@ -2597,15 +2597,22 @@ static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = { .name = "sl2if", }; +static struct omap_hwmod_rst_info omap44xx_sl2if_resets[] = { + { .name ="logic" , .rst_shift =2 }, +}; +/* sl2if */ static struct omap_hwmod omap44xx_sl2if_hwmod = { .name ="sl2if" , .class = &omap44xx_sl2if_hwmod_class, .clkdm_name ="ivahd_clkdm" , + .rst_lines = omap44xx_sl2if_resets, + .rst_lines_cnt =ARRAY_SIZE (omap44xx_sl2if_resets), .prcm = { .omap4 = { .clkctrl_offs =OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET , .context_offs =OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET , + .rstctrl_offs =OMAP4_RM_IVAHD_RSTCTRL_OFFSET , .modulemode =MODULEMODE_HWCTRL , }, }, --To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
Hi
Quoted 6 lines · Benoit
I don't think we should allow that at hwmod level. This line is already handled by the IVAHD hwmod. We will then have some potential issue since nothing will prevent the concurrent access.
Moreover that IP is only used by the IVAHD and thus should be handled by the same driver. The SL2 being inside the IVA subsystem, it should be reset when the IVA will be reset and thus does not require an individual control.
If a hardreset line will affect an IP block, then the line should be listed as one of the IP block's hardreset lines. Otherwise, the hwmod data will not accurately reflect the hardware -- the ultimate goal.
Quoted 2 lines
I guess, we should just mark the dependency with some external power resource to avoid the fmwk to try to enable that automatically.
Right now, the presence of a hardreset line will effectively cause the hwmod code to ignore the IP block from a reset and enable point of view. So the IP block won't be enabled automatically right now anyway, since we still don't have a clear sense of how to handle those.
Quoted 1 line
It is similar to DSS sub IPs and to some extend McPDM for my point of view.
These seem like different cases to me.
The DSS has no hardreset and the sub-IPs have their own softreset bits. As far as I know, the main reason why we can't have individual reset functions for the DSS sub-IPs is because we don't have hierarchical IP block enable/disable implemented in the hwmod code, not any real hardware constraint.
McPDM has a functional clock dependency on an external (non-SoC) device that's only controllable via I2C. And, the McPDM can block the ABE clockdomain from going idle. That's just wacky.
So those cases seem quite different to me. One is a software issue. And the other is an off-chip (non-OMAP) dependency, unlike the SL2IF/IVAHD issue in which all the needed resources are still on-chip.
Quoted 3 lines
Maybe we should rename
HWMOD_EXT_OPT_MAIN_CLKwith something more generic likeHWMOD_EXT_POWER_DEPto highlight the dependency with an external resource. It can be a external clock or another module.
Yes, I agree that it would be convenient to have some flag, either on the hwmod or the hardreset line, to indicate that some of the reset lines are shared.
- Paul
PATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
Quoted 11 lines · Paul Walmsley
Hi
Quoted 6 lines · Benoit
I don't think we should allow that at hwmod level. This line is already handled by the IVAHD hwmod. We will then have some potential issue since nothing will prevent the concurrent access.
Moreover that IP is only used by the IVAHD and thus should be handled by the same driver. The SL2 being inside the IVA subsystem, it should be reset when the IVA will be reset and thus does not require an individual control.
Quoted 2 lines
If a hardreset line will affect an IP block, then the line should be listed as one of the IP block's hardreset lines.
No, not necessarily. That signal is already added in the IVA hwmod that is the subsystem that does contain the SL2. The fact that the HW signal is propagated inside the SS is an implementation detail. In fact the hardreset of every SS is always propagated inside the SS IPs.
What is adding some confusion here is just because the SL2 does have a modulemode for some weird legacy reason and thus a hwmod.
Quoted 2 lines
Otherwise, the hwmod
data will not accurately reflect the hardware -- the ultimate goal.
Not really, describing the relevant HW for the SW usage is the goal. Otherwise we will end up with the full RTL inside the kernel.
So, here the point is just that SL2 is inside the IVAHD and thus will be reset when the IVAHD will be reset.
That does not mean the reset line should be controlled by the SL2 hwmod as well. This is in that case a duplication of a already existing line that is already controlled by the parent subsystem.
It seems obvious to me that in that case, only the parent should have the control. Otherwise, you will end up in a situation where a (potential) SL2 driver will reset the whole subsystem and all its siblings if it does try to reset the SL2.
Quoted 7 lines
Quoted 2 lines
I guess, we should just mark the dependency with some external power resource to avoid the fmwk to try to enable that automatically.
Right now, the presence of a hardreset line will effectively cause the hwmod code to ignore the IP block from a reset and enable point of view. So the IP block won't be enabled automatically right now anyway, since we still don't have a clear sense of how to handle those.
Yep, but for that I'd rather add a flag than a information that is a duplication of the parent data.
Quoted 9 lines
Quoted 1 line
It is similar to DSS sub IPs and to some extend McPDM for my point of view.
These seem like different cases to me.
The DSS has no hardreset and the sub-IPs have their own softreset bits. As far as I know, the main reason why we can't have individual reset functions for the DSS sub-IPs is because we don't have hierarchical IP block enable/disable implemented in the hwmod code, not any real hardware constraint.
The point with DSS is that you cannot enable the DISPC hwmod if the DSS (parent) is not enable.
-> Clock/Power dependency
Quoted 3 lines
McPDM has a functional clock dependency on an external (non-SoC) device that's only controllable via I2C. And, the McPDM can block the ABE clockdomain from going idle. That's just wacky.
The point with McPDM is that you cannot enable the McPDM if the external clock is not enabled.
-> Clock dependency
Quoted 3 lines
So those cases seem quite different to me. One is a software issue. And the other is an off-chip (non-OMAP) dependency, unlike the SL2IF/IVAHD issue in which all the needed resources are still on-chip.
The IVAHD reset must be de-asserted to enable the SL2. -> Parent reset dependency
The point I'm trying to make is that some IPs do have dependency with other IPs / devices in the system. It can be clock/reset or power.
Some of them could be indeed handled by hwmod fmwk, but since some other will require a management at Linux device level, and because LDM does already have a proper way to handle parent/child relationship, there is no point adding extra complexity in hwmod fmwk.
By using a single flag we can just prevent the hwmod fmwk to try to enable these IPs at boot time, because we already know it will fail due to missing dependencies.
Quoted 7 lines
Quoted 3 lines
Maybe we should rename
HWMOD_EXT_OPT_MAIN_CLKwith something more generic likeHWMOD_EXT_POWER_DEPto highlight the dependency with an external resource. It can be a external clock or another module.Yes, I agree that it would be convenient to have some flag, either on the hwmod or the hardreset line, to indicate that some of the reset lines are shared.
I guess such flag will be mostly irrelevant. What will we do with that?
We just want to avoid enabling an IP that cannot be enabled without enabling some other IPs before.
We do not want the hwmod fmwk to do that, we want to defer that do the Linux device level.
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
Quoted 2 lines · Benoit
Yep, but for that I'd rather add a flag than a information that is a duplication of the parent data.
Great, send a patch.
- Paul
PATCH v2 8/12 ARM: OMAP4: hwmod data: add SL2IF hardreset line
Quoted 6 lines · Paul Walmsley
Quoted 2 lines · Benoit
Yep, but for that I'd rather add a flag than a information that is a duplication of the parent data.
Great, send a patch.
Cool.
Well, in fact the HWMOD_EXT_OPT_MAIN_CLK patch is already good enough assuming we make it a little bit more generic.
Here is your patch sightly updated manually to make it more generic. The data will have to add some relevant comment on top of the flag to cleary indicate the reason of that dependency.
Regards,
Benoit
---
ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init
Add HWMOD_HAS_EXT_DEP flag to indicate that this IP block is dependent on an external resource that is not guaranteed to be present during initialization. Typical resources are: External clock from a off-chip device (Audio codec), clocks from a parent subsystem or another IP, reset line from a parent subsystem. IP blocks marked with this flag are left in the INITIALIZED state during kernel init.
[b-cousson at ti.com: Change the changelog and the flag name to make it more generic]
Cc: Beno?t Cousson <[email protected]>
--- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 9 insertions(+)
arch/arm/mach-omap2/omap_hwmod.c +3 -0
@@ -2140,6 +2140,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)if (oh->_state != _HWMOD_STATE_INITIALIZED)return -EINVAL ; +if (oh->flags &HWMOD_HAS_EXT_DEP ) +return -EPERM ; +if (oh->rst_lines_cnt ==0 ) { r =_enable (oh);if (r) {
arch/arm/plat-omap/include/plat/omap_hwmod.h +7 -0
@@ -417,6 +417,11 @@ struct omap_hwmod_omap4_prcm {* running on the chip (e.g., the MPU is in idle). For such modules, * fine-grained PM runtime-based idle control is simply a waste of * CPU cycles. +* HWMOD_HAS_EXT_DEP: This IP block is dependent on an external +* resource that is not guaranteed to be present during initialization. +* Typical resources are: External clock from a off-chip device +* (Audio codec), clocks from a parent subsystem, reset line from a +* parent subsystem. +* This prevents the hwmod code from being able to enable +* and reset the IP block early. */
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -428,6 +433,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8)
#define HWMOD_ALWAYS_FORCE_SIDLE (1 << 9)
+#define HWMOD_HAS_EXT_DEP (1 << 10)
/*
* omap_hwmod._int_flags definitions
Paul Walmsley
maintainerPATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
In reply to Paul WalmsleyAdd a custom setup_preprogram function for the usb_host_fs/fsusb IP block, and connect it to the OMAP4 FSUSB block.
This is the first of two fixes required to get rid of the boot warning:
omap_hwmod: usb_host_fs: _wait_target_disable failed
and to allow the module to idle.
It may be necessary to use this reset method for OMAP2xxx SoCs as well; this is left for a future patch.
Based on a patch originally written by Tero Kristo <[email protected]>.
This second version of this patch moves the control functions to include/linux/platform_data/aess.h at Tony's request:
http://www.spinics.net/lists/arm-kernel/msg178329.html
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 + include/linux/platform_data/fsusb.h | 105 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 include/linux/platform_data/fsusb.h
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +2 -0
@@ -21,6 +21,7 @@#include <linux/io.h> #include <linux/platform_data/aess.h> +#include <linux/platform_data/fsusb.h> #include <plat/omap_hwmod.h> #include <plat/cpu.h>
@@ -3314,6 +3315,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_usb_host_fs_sysc = {static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = { .name ="usb_host_fs" , .sysc = &omap44xx_usb_host_fs_sysc, + .setup_preprogram = hwmod_fsusb_preprogram, };/* usb_host_fs */
include/linux/platform_data/fsusb.h new file +105 -0
105 lines not on this page · raw message
Tony Lindgren
maintainerPATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Hi,
Similar comments to the asess patch on this one below.
include/linux/platform_data/fsusb.h
Quoted 2 lines · Paul Walmsley
include/linux/platform_data/fsusb.h new file +0
-0
This would be better as include/linux/platform_data/omap-usb.h.
Quoted 1 line
+#include <
plat/omap_hwmod.h>
This include should not be needed here if the hwmod function is a static function in the some hwmod*.c file.
include/linux/platform_data/fsusb.h line 46
Quoted 5 lines
include/linux/platform_data/fsusb.h new file +5
-0+/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */ +#define HCCOMMANDSTATUS 0x0008 + +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */ +#define HCCOMMANDSTATUS_HCR_MASK (1 << 0)
I think these already have standard defines in some OHCI header? Felipe may be able to comment more on this?
Quoted 10 lines
include/linux/platform_data/fsusb.h new file +10
-0+static int fsusb_reset_host_controller (const char *name,void __iomem *base) +{ +int i; + +writel (HCCOMMANDSTATUS_HCR_MASK , base +HCCOMMANDSTATUS ); + +for (i =0 ; i <MAX_FSUSB_HCR_TIME ; i++) { +if (!(readl (base +HCCOMMANDSTATUS ) &HCCOMMANDSTATUS_HCR_MASK )) +break ; +udelay (1 );
include/linux/platform_data/fsusb.h line 79
Quoted 10 lines
include/linux/platform_data/fsusb.h new file +10
-0+ } + +if (i ==MAX_FSUSB_HCR_TIME ) { +pr_warn ("%s: %s: host controller reset failed (waited %d usec)\n" , + __func__, name,MAX_FSUSB_HCR_TIME ); +return -EBUSY ; + } + +return 0 ; +}
This should be "static inline int fsusb_reset_host_controller" as it's in a header.
include/linux/platform_data/fsusb.h line 103
Quoted 12 lines
include/linux/platform_data/fsusb.h new file +12
-0+static int __maybe_unused hwmod_fsusb_preprogram (struct omap_hwmod *oh) +{ +void __iomem *va; + + va =omap_hwmod_get_mpu_rt_va (oh); +if (!va) +return -EINVAL ; + +fsusb_reset_host_controller (oh->name, va); + +return 0 ; +}
And this too should be a static function in some hwmod*.c file.
Regards,
Tony
PATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Quoted 15 lines · Tony Lindgren
Hi,
Similar comments to the asess patch on this one below.
include/linux/platform_data/fsusb.h
Quoted 2 lines · Paul Walmsley
include/linux/platform_data/fsusb.h new file +0
-0This would be better as
include/linux/platform_data/omap-usb.h.Quoted 1 line
+#include <
plat/omap_hwmod.h>This include should not be needed here if the hwmod function is a static function in the some hwmod*.c file.
Quoted 8 lines
include/linux/platform_data/fsusb.h line 46
Quoted 5 lines
include/linux/platform_data/fsusb.h new file +5
-0+/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */ +#define HCCOMMANDSTATUS 0x0008 + +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */ +#define HCCOMMANDSTATUS_HCR_MASK (1 << 0)I think these already have standard defines in some OHCI header? Felipe may be able to comment more on this?
Well, yeah... but it's defined on drivers/usb/host/ohci.h and it's actually a structure:
| /*
| * This is the structure of the OHCI controller's memory mapped I/O region.
| * You must use readl() and writel() (in <asm/io.h>) to access these fields!!
| * Layout is in section 7 (and appendix B) of the spec.
| */
| struct ohci_regs {
| /* control and status registers (section 7.1) */
| __hc32 revision;
| __hc32 control;
| __hc32 cmdstatus;
| __hc32 intrstatus;
| __hc32 intrenable;
| __hc32 intrdisable;
|
| /* memory pointers (section 7.2) */
| __hc32 hcca;
| __hc32 ed_periodcurrent;
| __hc32 ed_controlhead;
| __hc32 ed_controlcurrent;
| __hc32 ed_bulkhead;
| __hc32 ed_bulkcurrent;
| __hc32 donehead;
|
| /* frame counters (section 7.3) */
| __hc32 fminterval;
| __hc32 fmremaining;
| __hc32 fmnumber;
| __hc32 periodicstart;
| __hc32 lsthresh;
|
| /* Root hub ports (section 7.4) */
| struct ohci_roothub_regs {
| __hc32 a;
| __hc32 b;
| __hc32 status;
| #define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
| __hc32 portstatus [MAX_ROOT_PORTS];
| } roothub;
|
| /* and optional "legacy support" registers (appendix B) at 0x0100 */
|
| } __attribute__ ((aligned(32)));[...]
| /* | * HcCommandStatus (cmdstatus) register masks | */ | #define OHCI_HCR (1 << 0) /* host controller reset */ | #define OHCI_CLF (1 << 1) /* control list filled */ | #define OHCI_BLF (1 << 2) /* bulk list filled */ | #define OHCI_OCR (1 << 3) /* ownership change request */ | #define OHCI_SOC (3 << 16) /* scheduling overrun count */
Quoted 15 lines
Quoted 15 lines
include/linux/platform_data/fsusb.h new file +15
-0+static int fsusb_reset_host_controller (const char *name,void __iomem *base) +{ +int i; + +writel (HCCOMMANDSTATUS_HCR_MASK , base +HCCOMMANDSTATUS ); + +for (i =0 ; i <MAX_FSUSB_HCR_TIME ; i++) { +if (!(readl (base +HCCOMMANDSTATUS ) &HCCOMMANDSTATUS_HCR_MASK )) +break ; +udelay (1 ); + } + +if (i ==MAX_FSUSB_HCR_TIME ) { +pr_warn ("%s: %s: host controller reset failed (waited %d usec)\n" , + __func__, name,MAX_FSUSB_HCR_TIME );
Quoted 8 lines
include/linux/platform_data/fsusb.h line 79
Quoted 5 lines
include/linux/platform_data/fsusb.h new file +5
-0+return -EBUSY ; + } + +return 0 ; +}This should be "static inline int
fsusb_reset_host_controller" as it's in a header.
why is it even in a header ? Only hwmod_fsusb_preprogram() will use it anyway.
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120611/eb35b2f2/attachment.sig>
Tony Lindgren
maintainerPATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Quoted 25 lines · Felipe Balbi
Quoted 15 lines · Tony Lindgren
Hi,
Similar comments to the asess patch on this one below.
include/linux/platform_data/fsusb.h
Quoted 2 lines · Paul Walmsley
include/linux/platform_data/fsusb.h new file +0
-0This would be better as
include/linux/platform_data/omap-usb.h.Quoted 1 line
+#include <
plat/omap_hwmod.h>This include should not be needed here if the hwmod function is a static function in the some hwmod*.c file.
Quoted 8 lines
include/linux/platform_data/fsusb.h line 46
Quoted 5 lines
include/linux/platform_data/fsusb.h new file +5
-0+/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */ +#define HCCOMMANDSTATUS 0x0008 + +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */ +#define HCCOMMANDSTATUS_HCR_MASK (1 << 0)I think these already have standard defines in some OHCI header? Felipe may be able to comment more on this?
Quoted 2 lines
Well, yeah... but it's defined on
drivers/usb/host/ohci.hand it's actually a structure:
OK I guess then the define is OK.
Quoted 5 lines
Quoted 2 lines
This should be "static inline int
fsusb_reset_host_controller" as it's in a header.why is it even in a header ? Only
hwmod_fsusb_preprogram()will use it anyway.
Well ideally it would be something that any OHCI driver can use for it's reset, and whatever bus code can also call to reset and idle for the unused devices that don't have the driver compiled in. Got any better suggestions where to place it? I could be a generic ohci_reset function in some header?
I don't want to have driver specific code under arch/arm/*omap*/* as the bus level code should not need to know anything about the driver specific registers.
Regards,
Tony
PATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Hi,
Quoted 11 lines · Tony Lindgren
Quoted 5 lines
Quoted 2 lines
This should be "static inline int
fsusb_reset_host_controller" as it's in a header.why is it even in a header ? Only
hwmod_fsusb_preprogram()will use it anyway.Well ideally it would be something that any OHCI driver can use for it's reset, and whatever bus code can also call to reset and idle for the unused devices that don't have the driver compiled in. Got any better suggestions where to place it? I could be a generic
ohci_resetfunction in some header?
maybe create <linux/usb/ohci.h> ? Then, while doing that, move register definitions to this new header too... Something like:
$ mv drivers/usb/host/ohci.h include/linux/usb/ $ sed -i 's/\"ohci.h\"/<linux/usb/ohci.h>/g' $(git ls-files)
then add your ohci_reset() function...
Quoted 3 lines
I don't want to have driver specific code under
arch/arm/*omap*/*as the bus level code should not need to know anything about the driver specific registers.
I see.
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120611/87696f28/attachment-0001.sig>
Tony Lindgren
maintainerPATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Quoted 15 lines · Felipe Balbi
Hi,
Quoted 11 lines · Tony Lindgren
Quoted 5 lines
Quoted 2 lines
This should be "static inline int
fsusb_reset_host_controller" as it's in a header.why is it even in a header ? Only
hwmod_fsusb_preprogram()will use it anyway.Well ideally it would be something that any OHCI driver can use for it's reset, and whatever bus code can also call to reset and idle for the unused devices that don't have the driver compiled in. Got any better suggestions where to place it? I could be a generic
ohci_resetfunction in some header?
Quoted 7 lines
maybe create <
linux/usb/ohci.h> ? Then, while doing that, move register definitions to this new header too... Something like:$ mv drivers/usb/host/ohci.h include/linux/usb/ $ sed -i 's/\"ohci.h\"/<linux/usb/ohci.h>/g' $(git ls-files)then add your
ohci_reset()function...
Hmm but then again it's pointless to export the all the ohci registers as that will lead to misuse outside drivers/usb.. Sounds like just defining the reset register is safest option here.
Quoted 5 lines
Quoted 3 lines
I don't want to have driver specific code under
arch/arm/*omap*/*as the bus level code should not need to know anything about the driver specific registers.I see.
Regards,
Tony
PATCH v2 9/12 ARM: OMAP2+: usb_host_fs: add custom setup_preprogram for usb_host_fs (fsusb)
Quoted 19 lines · Tony Lindgren
Quoted 18 lines · Felipe Balbi
Hi,
Quoted 11 lines · Tony Lindgren
Quoted 5 lines
Quoted 2 lines
This should be "static inline int
fsusb_reset_host_controller" as it's in a header.why is it even in a header ? Only
hwmod_fsusb_preprogram()will use it anyway.Well ideally it would be something that any OHCI driver can use for it's reset, and whatever bus code can also call to reset and idle for the unused devices that don't have the driver compiled in. Got any better suggestions where to place it? I could be a generic
ohci_resetfunction in some header?maybe create <
linux/usb/ohci.h> ? Then, while doing that, move register definitions to this new header too... Something like:
Quoted 8 lines
Quoted 4 lines
$ mv drivers/usb/host/ohci.h include/linux/usb/ $ sed -i 's/\"ohci.h\"/<linux/usb/ohci.h>/g' $(git ls-files)then add your
ohci_reset()function...Hmm but then again it's pointless to export the all the ohci registers as that will lead to misuse outside
drivers/usb.. Sounds like just defining the reset register is safest option here.
could be as well, but looks like we need to create <linux/usb/ohci.h> anyway...
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120611/520ef1f8/attachment.sig>
Paul Walmsley
maintainerPATCH v2 10/12 ARM: OMAP2+: CM: increase the module disable timeout
In reply to Paul WalmsleyIncrease the timeout for disabling an IP block to five milliseconds. This is to handle the usb_host_fs idle latency, which takes almost four milliseconds after a host controller reset.
This is the second of two patches needed to resolve the following boot warning:
omap_hwmod: usb_host_fs: _wait_target_disable failed
--- arch/arm/mach-omap2/cm.h | 11 +++++++++++ arch/arm/mach-omap2/cminst44xx.c | 4 ++-- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + 3 files changed, 14 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/cm.h +11 -0
@@ -22,4 +22,15 @@*/ #define MAX_MODULE_READY_TIME 2000 +/* +* MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for +* the PRCM to request that a module enter the inactive state in the +* case of OMAP2 & 3. In the case of OMAP4 this is the max duration +* in microseconds for the module to reach the inactive state from +* a functional state. +* XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during +* kernel init. +*/ +#define MAX_MODULE_DISABLE_TIME 5000 +#endif
arch/arm/mach-omap2/cminst44xx.c +2 -2
@@ -313,9 +313,9 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offomap_test_timeout ((_clkctrl_idlest (part, inst, cdoffs, clkctrl_offs) ==CLKCTRL_IDLEST_DISABLED ), -MAX_MODULE_READY_TIME , i); +MAX_MODULE_DISABLE_TIME , i); -return (i <MAX_MODULE_READY_TIME ) ?0 : -EBUSY ; +return (i <MAX_MODULE_DISABLE_TIME ) ?0 : -EBUSY ; }/**
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +1 -0
@@ -33,6 +33,7 @@#include <plat/mmc.h> #include <plat/dmtimer.h> #include <plat/common.h> +#include <plat/usb.h> #include "omap_hwmod_common_data.h"
Paul Walmsley
maintainerPATCH v2 11/12 ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
In reply to Paul WalmsleyUntil the OMAP4 code is converted to disable the use of the clock framework-based clockdomain enable/disable sequence, any clock used as a hwmod main_clk must have a clockdomain associated with it. This patch populates some clock structure clockdomain names to resolve the following warnings during kernel init:
omap_hwmod: dpll_mpu_m2_ck: missing clockdomain for dpll_mpu_m2_ck.omap_hwmod: trace_clk_div_ck: missing clockdomain for trace_clk_div_ck.omap_hwmod: l3_div_ck: missing clockdomain for l3_div_ck.omap_hwmod: ddrphy_ck: missing clockdomain for ddrphy_ck.
--- arch/arm/mach-omap2/clock44xx_data.c | 5 +++++ 1 file changed, 5 insertions(+)
arch/arm/mach-omap2/clock44xx_data.c +5 -0
@@ -84,6 +84,7 @@ static struct clk slimbus_clk = {static struct clk sys_32k_ck = { .name ="sys_32k_ck" , + .clkdm_name ="prm_clkdm" , .rate =32768 , .ops = &clkops_null, };
@@ -512,6 +513,7 @@ static struct clk ddrphy_ck = { .name = "ddrphy_ck", .parent = &dpll_core_m2_ck, .ops = &clkops_null, + .clkdm_name = "l3_emif_clkdm", .fixed_div = 2, .recalc = &omap_fixed_divisor_recalc, };
@@ -769,6 +771,7 @@ static const struct clksel dpll_mpu_m2_div[] = {static struct clk dpll_mpu_m2_ck = { .name ="dpll_mpu_m2_ck" , .parent = &dpll_mpu_ck, + .clkdm_name ="cm_clkdm" , .clksel = dpll_mpu_m2_div, .clksel_reg =OMAP4430_CM_DIV_M2_DPLL_MPU , .clksel_mask =OMAP4430_DPLL_CLKOUT_DIV_MASK ,
@@ -1149,6 +1152,7 @@ static const struct clksel l3_div_div[] = {static struct clk l3_div_ck = { .name ="l3_div_ck" , .parent = &div_core_ck, + .clkdm_name ="cm_clkdm" , .clksel = l3_div_div, .clksel_reg =OMAP4430_CM_CLKSEL_CORE , .clksel_mask =OMAP4430_CLKSEL_L3_MASK ,
@@ -2824,6 +2828,7 @@ static const struct clksel trace_clk_div_div[] = {static struct clk trace_clk_div_ck = { .name ="trace_clk_div_ck" , .parent = &pmd_trace_clk_mux_ck, + .clkdm_name ="emu_sys_clkdm" , .clksel = trace_clk_div_div, .clksel_reg =OMAP4430_CM_EMU_DEBUGSS_CLKCTRL , .clksel_mask =OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK ,
PATCH v2 11/12 ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
Hi Paul,
Quoted 3 lines · Paul Walmsley
Until the OMAP4 code is converted to disable the use of the clock framework-based clockdomain enable/disable sequence, any clock used as a hwmod
main_clkmust have a clockdomain associated with it.
But why? The clock domain information is already present in every hwmod nodes for OMAP4.
Quoted 21 lines
This
patch populates some clock structure clockdomain names to resolve the following warnings during kernel init:
omap_hwmod:dpll_mpu_m2_ck: missing clockdomain fordpll_mpu_m2_ck.omap_hwmod:trace_clk_div_ck: missing clockdomain fortrace_clk_div_ck.omap_hwmod:l3_div_ck: missing clockdomain forl3_div_ck.omap_hwmod:ddrphy_ck: missing clockdomain forddrphy_ck.Signed-off-by Paul Walmsley <[email protected]>Cc Rajendra Nayak <[email protected]>Cc Beno?t Cousson <[email protected]>--- arch/arm/mach-omap2/clock44xx_data.c | 5 +++++ 1 file changed, 5 insertions(+)arch/arm/mach-omap2/clock44xx_data.c +0
-0
arch/arm/mach-omap2/clock44xx_data.c static struct clk slimbus_clk = { · line 87
Quoted 4 lines
arch/arm/mach-omap2/clock44xx_data.c +1
-0@@ -84,6 +84,7 @@ static struct clk slimbus_clk = {static struct clk sys_32k_ck = { .name ="sys_32k_ck" , + .clkdm_name ="prm_clkdm" ,
In fact, neither prm_clkdm not cm_clkdm are valid clock domain on OMAP4 :-(.
I've just realized that you introduced that for 3.5, but this is wrong. We should not start adding some fake clock domains just because the fmwk is not smart enough to allow a NULL clock domain.
The clkdomain should be optional, at least for clock nodes. There is no need to enforce the presence of the clock domain in the structure. We should remove the warning and test the clkdm attribute before de-referencing it inside the clock core code.
This is the only proper fix for that issue for my point of view.
In a period of data size reduction, adding some fake information does not seems to be the right approach.
Don't you think so?
Regards,
Benoit
PS: I think we should revert 6ba5a69ee92c29c2ffc814dad6ac61c4cd49090c (ARM: OMAP2+: clockdomains: make {prm,cm}_clkdm common) and fix the OMAP4 hwmod data.
Paul Walmsley
maintainerPATCH v2 11/12 ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
Quoted 7 lines · Benoit
In fact, neither
prm_clkdmnotcm_clkdmare valid clock domain on OMAP4 :-(.I've just realized that you introduced that for 3.5, but this is wrong. We should not start adding some fake clock domains just because the fmwk is not smart enough to allow a NULL clock domain.
...
Quoted 2 lines
In a period of data size reduction, adding some fake information does not seems to be the right approach. Don't you think so?
No, I do not.
These clockdomains are clearly documented in both the OMAP4 TRM[1] and the NDA OMAP4 PRCM functional specifications.
I continue to be baffled as to why you assert that they are fake, given how clearly they are documented.
- Paul
1. See for example sections 3.6.6.1 "Overview", Figure 3-58 "CD_L4_PER Overview", Figure 3-59 "CD_L3_INIT Overview", Figure 3-62 "CD_EMU Overview", Figure 3-63 "CD_DSS Overview", Figure 3-74 "CD_L4_ALWON_CORE Overview" in the OMAP4 TRM Rev. AA (SWPU231AA).
PATCH v2 11/12 ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
Quoted 12 lines · Paul Walmsley
Quoted 7 lines · Benoit
In fact, neither
prm_clkdmnotcm_clkdmare valid clock domain on OMAP4 :-(.I've just realized that you introduced that for 3.5, but this is wrong. We should not start adding some fake clock domains just because the fmwk is not smart enough to allow a NULL clock domain.
...
Quoted 7 lines
Quoted 2 lines
In a period of data size reduction, adding some fake information does not seems to be the right approach. Don't you think so?
No, I do not.
These clockdomains are clearly documented in both the OMAP4 TRM[1] and the NDA OMAP4 PRCM functional specifications.
Sorry for the confusion; I was just referring to the prm_clkdm and cm_clkdm.
Quoted 2 lines
I continue to be baffled as to why you assert that they are fake, given how clearly they are documented.
In that case the clock domains are valid, but that does not change the fact that they are useless, at least for the moment.
The PRCM is already taking care of managing properly the domains based on module activity. Adding that to the clocks nodes is not wrong, but does add an information that is a duplication of what the HW is already doing.
That's why we should populate that information only if this is needed, like it was the case for the DPLL, but it should remain optional.
Regards,
Benoit
Paul Walmsley
maintainerPATCH v2 12/12 ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
In reply to Paul WalmsleyResolve this kernel boot message:
omap_hwmod: mcpdm: cannot be enabled for reset (3)
It appears that the McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init.
At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code.
This patch works around the issue by marking the McPDM hwmod record with the HWMOD_EXT_OPT_MAIN_CLK flag. This prevents the hwmod code from touching the device early during boot.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +12 -0
@@ -2091,6 +2091,18 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name ="abe_clkdm" , +/* +* It's suspected that the McPDM requires an off-chip main +* functional clock, controlled via I2C. This IP block is +* currently reset very early during boot, before I2C is +* available, so it doesn't seem that we have any choice in +* the kernel other than to avoid resetting it. XXX This is +* really a hardware issue workaround: every IP block should +* be able to source its main functional clock from either +* on-chip or off-chip sources. McPDM seems to be the only +* current exception. +*/ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck",
PATCH v2 12/12 ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
Quoted 14 lines · Paul Walmsley
Resolve this kernel boot message:
omap_hwmod: mcpdm: cannot be enabled for reset (3)It appears that the McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init.
Quoted 8 lines
At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code.
And I guess, that's a good reason as well to let the driver managing the reset during the probe for such IPs.
Quoted 16 lines
This patch works around the issue by marking the McPDM hwmod record with the
HWMOD_EXT_OPT_MAIN_CLKflag. This prevents the hwmod code from touching the device early during boot.Signed-off-by Paul Walmsley <[email protected]>Cc P?ter Ujfalusi <[email protected]>Cc Beno?t Cousson <[email protected]>--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)arch/arm/mach-omap2/omap_hwmod_44xx_data.c +0
-0
arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2096
Quoted 6 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +3
-0@@ -2091,6 +2091,18 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", +/* +* It's suspected that the McPDM requires an off-chip main +* functional clock, controlled via I2C.
Nit: Is it not suspected, it is a fact. The clock tree clearly indicate that the mcpdm fclk is generated from the pad_clks.
The IP is a custom link for the Audio IC control / data. using the Audio IC as a source clock is standard. Since that IP is done only for that purpose, there is no optional clock path from the PRCM like it is the case for the McASP / McBSP.
arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2103
Quoted 8 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +7
-0This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. XXX This is + * really a hardware issue workaround: every IP block should + * be able to source its main functional clock from either + * on-chip or off-chip sources. McPDM seems to be the only + * current exception.
I do not think this is the right place to put some complaint about the HW :-).
I guess we should just describe the facts.
arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2105
Quoted 2 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +2
-0+*/ + .flags = HWMOD_EXT_OPT_MAIN_CLK,
Could you please update the hints for this IP in the autogen scripts? I added a comment attribute to add a custom comment on top of the flags entry.
The latest branch is "omap5430_for_3.6".
Thanks,
Benoit
Paul Walmsley
maintainerPATCH v2 12/12 ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
Hi,
Quoted 34 lines · Benoit
arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2096
Quoted 12 lines · Paul Walmsley
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +3
-0@@ -2091,6 +2091,18 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", +/* +* It's suspected that the McPDM requires an off-chip main +* functional clock, controlled via I2C. Nit: Is it not suspected, it is a fact. The clock tree clearly indicate that the mcpdm fclk is generated from the
pad_clks.
The IP is a custom link for the Audio IC control / data. using the Audio IC as a source clock is standard. Since that IP is done only for that purpose, there is no optional clock path from the PRCM like it is the case for the McASP / McBSP.arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2104
Quoted 8 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +7
-0This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. XXX This is + * really a hardware issue workaround: every IP block should + * be able to source its main functional clock from either + * on-chip or off-chip sources. McPDM seems to be the only + * current exception.I do not think this is the right place to put some complaint about the HW :-). I guess we should just describe the facts.
Quoted 2 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c static struct omap_hwmod omap44xx_mcpdm_hwmod = { · line 2106
Quoted 2 lines
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +2
-0+*/ + .flags = HWMOD_EXT_OPT_MAIN_CLK,
I've updated this one to take your comments into account for 3.7-rc fixes. But...
Quoted 3 lines
Could you please update the hints for this IP in the autogen scripts? I added a comment attribute to add a custom comment on top of the flags entry. The latest branch is "omap5430_for_3.6".
... could you please take care of updating the autogen side? Updated patch is below.
- Paul
From: Paul Walmsley <[email protected]>
Date: Mon, 29 Oct 2012 22:02:14 -0600
Subject: [PATCH] ARM: OMAP4: hwmod data: do not enable or reset the McPDM
during kernel init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolve this kernel boot message:
omap_hwmod: mcpdm: cannot be enabled for reset (3)
The McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init.
At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code.
This patch works around the issue by marking the McPDM hwmod record with the HWMOD_EXT_OPT_MAIN_CLK flag. This prevents the hwmod code from touching the device early during boot.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +8 -0
@@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", +/* +* It's suspected that the McPDM requires an off-chip main +* functional clock, controlled via I2C. This IP block is +* currently reset very early during boot, before I2C is +* available, so it doesn't seem that we have any choice in +* the kernel other than to avoid resetting it. +*/ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck",
Signature · 1 line
1.7.10.4
PATCH v2 12/12 ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
Hi Paul,
Quoted 20 lines · Paul Walmsley
omap_hwmod: mcpdm: cannot be enabled for reset (3)The McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init.
At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code.
Quoted 7 lines
This patch works around the issue by marking the McPDM hwmod record with the
HWMOD_EXT_OPT_MAIN_CLKflag. This prevents the hwmod code from touching the device early during boot.Signed-off-by Paul Walmsley <[email protected]>Cc P?ter Ujfalusi <[email protected]>Cc Beno?t Cousson <[email protected]>
Quoted 24 lines
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/mach-omap2/omap_hwmod_44xx_data.c +8
-0@@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", +/* +* It's suspected that the McPDM requires an off-chip main +* functional clock, controlled via I2C. This IP block is +* currently reset very early during boot, before I2C is +* available, so it doesn't seem that we have any choice in +* the kernel other than to avoid resetting it. +*/ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck",
Signature · 1 line
P?ter