* [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 22:04 ` Santosh Shilimkar
2012-11-07 19:01 ` [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer Jon Hunter
` (14 subsequent siblings)
15 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
For OMAP2+ devices, when using DMTIMERs for system timers (clock-events and
clock-source) the posted mode configuration of the timers is used. To allow
the compiler to optimise the functions for configuring and reading the system
timers, the posted flag variable is hard-coded with the value 1. To make it
clear that posted mode is being used add some definitions so that it is more
readable.
Add separate definitions for the clock-events and clock-source timers so that
we can change the posted mode of clock-events and clock-source independently.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 26 +++++++++++++++++++-------
arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 0758bae..28c6078 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -82,6 +82,13 @@
#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
+/*
+ * For clock-events timer, always use posted mode to
+ * minimise CPU overhead for configuring the timer.
+ */
+#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
+#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
+
/* Clockevent code */
static struct omap_dm_timer clkev;
@@ -107,7 +114,7 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
__omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
- 0xffffffff - cycles, 1);
+ 0xffffffff - cycles, OMAP_CLKEVT_POSTEDMODE);
return 0;
}
@@ -117,7 +124,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
{
u32 period;
- __omap_dm_timer_stop(&clkev, 1, clkev.rate);
+ __omap_dm_timer_stop(&clkev, OMAP_CLKEVT_POSTEDMODE, clkev.rate);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -125,10 +132,12 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
period -= 1;
/* Looks like we need to first set the load value separately */
__omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
- 0xffffffff - period, 1);
+ 0xffffffff - period,
+ OMAP_CLKEVT_POSTEDMODE);
__omap_dm_timer_load_start(&clkev,
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
- 0xffffffff - period, 1);
+ 0xffffffff - period,
+ OMAP_CLKEVT_POSTEDMODE);
break;
case CLOCK_EVT_MODE_ONESHOT:
break;
@@ -358,7 +367,8 @@ static bool use_gptimer_clksrc;
*/
static cycle_t clocksource_read_cycles(struct clocksource *cs)
{
- return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1);
+ return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
+ OMAP_CLKSRC_POSTEDMODE);
}
static struct clocksource clocksource_gpt = {
@@ -372,7 +382,8 @@ static struct clocksource clocksource_gpt = {
static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
- return __omap_dm_timer_read_counter(&clksrc, 1);
+ return __omap_dm_timer_read_counter(&clksrc,
+ OMAP_CLKSRC_POSTEDMODE);
return 0;
}
@@ -454,7 +465,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
- OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
+ OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
+ OMAP_CLKSRC_POSTEDMODE);
setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 348f855..835c3bdf 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -55,6 +55,10 @@
#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
+/* posted mode types */
+#define OMAP_TIMER_NONPOSTED 0x00
+#define OMAP_TIMER_POSTED 0x01
+
/* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000
#define OMAP_TIMER_ALWON 0x40000000
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 19:01 ` [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode Jon Hunter
@ 2012-11-07 22:04 ` Santosh Shilimkar
2012-11-07 22:11 ` Jon Hunter
2012-11-08 16:52 ` Jon Hunter
0 siblings, 2 replies; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:04 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
> For OMAP2+ devices, when using DMTIMERs for system timers (clock-events and
> clock-source) the posted mode configuration of the timers is used. To allow
> the compiler to optimise the functions for configuring and reading the system
> timers, the posted flag variable is hard-coded with the value 1. To make it
> clear that posted mode is being used add some definitions so that it is more
> readable.
>
> Add separate definitions for the clock-events and clock-source timers so that
> we can change the posted mode of clock-events and clock-source independently.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
> arch/arm/mach-omap2/timer.c | 26 +++++++++++++++++++-------
> arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
> 2 files changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 0758bae..28c6078 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -82,6 +82,13 @@
> #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
> #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
>
> +/*
> + * For clock-events timer, always use posted mode to
> + * minimise CPU overhead for configuring the timer.
> + */
> +#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
> +#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
> +
I don't see need of above defines. Just use OMAP_TIMER_POSTED directly
with API. Rest of the patch looks fine.
Apart from above one comment,
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 22:04 ` Santosh Shilimkar
@ 2012-11-07 22:11 ` Jon Hunter
2012-11-07 22:18 ` Santosh Shilimkar
2012-11-08 16:52 ` Jon Hunter
1 sibling, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 22:11 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 04:04 PM, Santosh Shilimkar wrote:
> On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
>> For OMAP2+ devices, when using DMTIMERs for system timers
>> (clock-events and
>> clock-source) the posted mode configuration of the timers is used. To
>> allow
>> the compiler to optimise the functions for configuring and reading the
>> system
>> timers, the posted flag variable is hard-coded with the value 1. To
>> make it
>> clear that posted mode is being used add some definitions so that it
>> is more
>> readable.
>>
>> Add separate definitions for the clock-events and clock-source timers
>> so that
>> we can change the posted mode of clock-events and clock-source
>> independently.
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>> arch/arm/mach-omap2/timer.c | 26
>> +++++++++++++++++++-------
>> arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
>> 2 files changed, 23 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>> index 0758bae..28c6078 100644
>> --- a/arch/arm/mach-omap2/timer.c
>> +++ b/arch/arm/mach-omap2/timer.c
>> @@ -82,6 +82,13 @@
>> #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
>> #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
>>
>> +/*
>> + * For clock-events timer, always use posted mode to
>> + * minimise CPU overhead for configuring the timer.
>> + */
>> +#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
>> +#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
>> +
> I don't see need of above defines. Just use OMAP_TIMER_POSTED directly
> with API. Rest of the patch looks fine.
Yes that's possible, however, in patch #2, I am disabling posted mode
for clock-source (see changelog of patch #2 for details). Having these
#defines makes it easier to change the posted configuration. That was
the real motivation here.
Cheers
Jon
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 22:11 ` Jon Hunter
@ 2012-11-07 22:18 ` Santosh Shilimkar
2012-11-07 22:47 ` Jon Hunter
0 siblings, 1 reply; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:18 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 04:11 PM, Jon Hunter wrote:
>
> On 11/07/2012 04:04 PM, Santosh Shilimkar wrote:
>> On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
>>> For OMAP2+ devices, when using DMTIMERs for system timers
>>> (clock-events and
>>> clock-source) the posted mode configuration of the timers is used. To
>>> allow
>>> the compiler to optimise the functions for configuring and reading the
>>> system
>>> timers, the posted flag variable is hard-coded with the value 1. To
>>> make it
>>> clear that posted mode is being used add some definitions so that it
>>> is more
>>> readable.
>>>
>>> Add separate definitions for the clock-events and clock-source timers
>>> so that
>>> we can change the posted mode of clock-events and clock-source
>>> independently.
>>>
>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>> arch/arm/mach-omap2/timer.c | 26
>>> +++++++++++++++++++-------
>>> arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
>>> 2 files changed, 23 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>> index 0758bae..28c6078 100644
>>> --- a/arch/arm/mach-omap2/timer.c
>>> +++ b/arch/arm/mach-omap2/timer.c
>>> @@ -82,6 +82,13 @@
>>> #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
>>> #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
>>>
>>> +/*
>>> + * For clock-events timer, always use posted mode to
>>> + * minimise CPU overhead for configuring the timer.
>>> + */
>>> +#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
>>> +#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
>>> +
>> I don't see need of above defines. Just use OMAP_TIMER_POSTED directly
>> with API. Rest of the patch looks fine.
>
> Yes that's possible, however, in patch #2, I am disabling posted mode
> for clock-source (see changelog of patch #2 for details). Having these
> #defines makes it easier to change the posted configuration. That was
> the real motivation here.
>
Sure but that is more confusing because you are flipping
the meaning of the macro. Better to specify direct
argument to avoid the confusion.
Regards
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 22:18 ` Santosh Shilimkar
@ 2012-11-07 22:47 ` Jon Hunter
0 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 22:47 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 04:18 PM, Santosh Shilimkar wrote:
> On Wednesday 07 November 2012 04:11 PM, Jon Hunter wrote:
>>
>> On 11/07/2012 04:04 PM, Santosh Shilimkar wrote:
>>> On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
>>>> For OMAP2+ devices, when using DMTIMERs for system timers
>>>> (clock-events and
>>>> clock-source) the posted mode configuration of the timers is used. To
>>>> allow
>>>> the compiler to optimise the functions for configuring and reading the
>>>> system
>>>> timers, the posted flag variable is hard-coded with the value 1. To
>>>> make it
>>>> clear that posted mode is being used add some definitions so that it
>>>> is more
>>>> readable.
>>>>
>>>> Add separate definitions for the clock-events and clock-source timers
>>>> so that
>>>> we can change the posted mode of clock-events and clock-source
>>>> independently.
>>>>
>>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>>>> ---
>>>> arch/arm/mach-omap2/timer.c | 26
>>>> +++++++++++++++++++-------
>>>> arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
>>>> 2 files changed, 23 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>>> index 0758bae..28c6078 100644
>>>> --- a/arch/arm/mach-omap2/timer.c
>>>> +++ b/arch/arm/mach-omap2/timer.c
>>>> @@ -82,6 +82,13 @@
>>>> #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
>>>> #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
>>>>
>>>> +/*
>>>> + * For clock-events timer, always use posted mode to
>>>> + * minimise CPU overhead for configuring the timer.
>>>> + */
>>>> +#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
>>>> +#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
>>>> +
>>> I don't see need of above defines. Just use OMAP_TIMER_POSTED directly
>>> with API. Rest of the patch looks fine.
>>
>> Yes that's possible, however, in patch #2, I am disabling posted mode
>> for clock-source (see changelog of patch #2 for details). Having these
>> #defines makes it easier to change the posted configuration. That was
>> the real motivation here.
>>
> Sure but that is more confusing because you are flipping
> the meaning of the macro. Better to specify direct
> argument to avoid the confusion.
Hmmm ... I guess I don't see it that way. The intent was that the
definitions OMAP_CLKxxx_POSTEDMODE described the posted configuration
(ie. posted or non-posted) and a user could change/flip it if so desired.
I can use the OMAP_TIMER_POSTED/NONPOSTED directly, but my concern with
that was if someone wanted to changed the posted mode then they have to
change it in multiple places and there is a chance they could miss one.
This way, as long as I have it right to begin with, then no one should
be able to screw it up :-)
Cheers
Jon
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode
2012-11-07 22:04 ` Santosh Shilimkar
2012-11-07 22:11 ` Jon Hunter
@ 2012-11-08 16:52 ` Jon Hunter
1 sibling, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-08 16:52 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 04:04 PM, Santosh Shilimkar wrote:
> On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
>> For OMAP2+ devices, when using DMTIMERs for system timers
>> (clock-events and
>> clock-source) the posted mode configuration of the timers is used. To
>> allow
>> the compiler to optimise the functions for configuring and reading the
>> system
>> timers, the posted flag variable is hard-coded with the value 1. To
>> make it
>> clear that posted mode is being used add some definitions so that it
>> is more
>> readable.
>>
>> Add separate definitions for the clock-events and clock-source timers
>> so that
>> we can change the posted mode of clock-events and clock-source
>> independently.
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>> arch/arm/mach-omap2/timer.c | 26
>> +++++++++++++++++++-------
>> arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
>> 2 files changed, 23 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>> index 0758bae..28c6078 100644
>> --- a/arch/arm/mach-omap2/timer.c
>> +++ b/arch/arm/mach-omap2/timer.c
>> @@ -82,6 +82,13 @@
>> #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
>> #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
>>
>> +/*
>> + * For clock-events timer, always use posted mode to
>> + * minimise CPU overhead for configuring the timer.
>> + */
>> +#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
>> +#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
>> +
> I don't see need of above defines. Just use OMAP_TIMER_POSTED directly
> with API. Rest of the patch looks fine.
>
> Apart from above one comment,
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Ok, updated and dropped the additional definitions. Let me know if you
are ok with this.
Cheers
Jon
>From f1c783b5af933374431bcb8acb01d0b5c79d5661 Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 27 Sep 2012 11:49:45 -0500
Subject: [PATCH 1/2] ARM: OMAP: Add DMTIMER definitions for posted mode
For OMAP2+ devices, when using DMTIMERs for system timers (clock-events and
clock-source) the posted mode configuration of the timers is used. To allow
the compiler to optimise the functions for configuring and reading the system
timers, the posted flag variable is hard-coded with the value 1. To make it
clear that posted mode is being used add some definitions so that it is more
readable.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 17 ++++++++++-------
arch/arm/plat-omap/include/plat/dmtimer.h | 4 ++++
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 0758bae..ad427ba 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -107,7 +107,7 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
__omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
- 0xffffffff - cycles, 1);
+ 0xffffffff - cycles, OMAP_TIMER_POSTED);
return 0;
}
@@ -117,7 +117,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
{
u32 period;
- __omap_dm_timer_stop(&clkev, 1, clkev.rate);
+ __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -125,10 +125,10 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
period -= 1;
/* Looks like we need to first set the load value separately */
__omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
- 0xffffffff - period, 1);
+ 0xffffffff - period, OMAP_TIMER_POSTED);
__omap_dm_timer_load_start(&clkev,
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
- 0xffffffff - period, 1);
+ 0xffffffff - period, OMAP_TIMER_POSTED);
break;
case CLOCK_EVT_MODE_ONESHOT:
break;
@@ -358,7 +358,8 @@ static bool use_gptimer_clksrc;
*/
static cycle_t clocksource_read_cycles(struct clocksource *cs)
{
- return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1);
+ return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
+ OMAP_TIMER_POSTED);
}
static struct clocksource clocksource_gpt = {
@@ -372,7 +373,8 @@ static struct clocksource clocksource_gpt = {
static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
- return __omap_dm_timer_read_counter(&clksrc, 1);
+ return __omap_dm_timer_read_counter(&clksrc,
+ OMAP_TIMER_POSTED);
return 0;
}
@@ -454,7 +456,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
- OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
+ OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
+ OMAP_TIMER_POSTED);
setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 348f855..835c3bdf 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -55,6 +55,10 @@
#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
+/* posted mode types */
+#define OMAP_TIMER_NONPOSTED 0x00
+#define OMAP_TIMER_POSTED 0x01
+
/* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000
#define OMAP_TIMER_ALWON 0x40000000
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
2012-11-07 19:01 ` [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 22:10 ` Santosh Shilimkar
2012-11-07 19:01 ` [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767 Jon Hunter
` (13 subsequent siblings)
15 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
When using a DMTIMER as the clock-source timer, posted mode configuration of
the DMTIMER is used. Posted mode is only benefical when configuring timers as
it allows writes to be posted and does not stall the CPU until the write is
complete. The clock-source timer is only configured once on boot and so using
posted mode has no benefit. In fact, by using posted mode, it adds overhead
to reading the timer. Therefore, by default disable posted mode for DMTIMERs
used for clock-source.
Using objdump this change reduces the function clocksource_read_cycles()
function from a total of 15 instructions (including 3 branches and 7 loads)
to 5 instructions (including 1 branch and 3 loads). Please note that before
the minimum number of instructions that would be executed when calling
clocksource_read_cycles() would be 9 instructions (including 2 branches and 5
loads) where as now it will always be 5 instructions.
This change also reduces the function dmtimer_read_sched_clock() function from
a total of 17 instructions (including 4 branches and 8 loads) to 6 instructions
(including 1 branch and 4 loads). Please note that before the minimum number of
instructions that would be executed when calling dmtimer_read_sched_clock()
would be 11 instructions (including 2 branches and 6 loads) where as now it
will always be 6 instructions.
This change removes the configuration of posted mode from the
__omap_dm_timer_reset() function and adds a new function called
omap_dm_timer_enable_posted() for enabling posted mode. Hence, call
omap_dm_timer_enable_posted() where ever we are calling __omap_dm_timer_reset().
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 28 ++++++++++++++++++++--------
arch/arm/plat-omap/dmtimer.c | 23 ++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/dmtimer.h | 5 +----
3 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 28c6078..78b7712 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -83,11 +83,19 @@
#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
/*
- * For clock-events timer, always use posted mode to
- * minimise CPU overhead for configuring the timer.
+ * For the clock-events timer, always use posted mode to
+ * minimise CPU overhead for configuring the timer. This timer
+ * is never read and so overhead of reading the timer in posted
+ * mode is not applicable.
*/
#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
-#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
+
+/*
+ * For the clock-source timer, always use non-posted mode to
+ * minimise CPU overhead for reading the timer. This timer is
+ * only configured once and so using posted mode has no benefit.
+ */
+#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_NONPOSTED
/* Clockevent code */
@@ -233,7 +241,8 @@ void __init omap_dmtimer_init(void)
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
int gptimer_id,
const char *fck_source,
- const char *property)
+ const char *property,
+ int posted)
{
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name;
@@ -319,10 +328,11 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
__omap_dm_timer_init_regs(timer);
__omap_dm_timer_reset(timer, 1, 1);
- timer->posted = 1;
- timer->rate = clk_get_rate(timer->fclk);
+ if (posted)
+ omap_dm_timer_enable_posted(timer);
+ timer->rate = clk_get_rate(timer->fclk);
timer->reserved = 1;
return res;
@@ -334,7 +344,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property);
+ res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
+ OMAP_CLKEVT_POSTEDMODE);
BUG_ON(res);
omap2_gp_timer_irq.dev_id = &clkev;
@@ -461,7 +472,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL);
+ res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
+ OMAP_CLKSRC_POSTEDMODE);
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index b09e556..699570b 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -131,8 +131,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
}
__omap_dm_timer_reset(timer, 0, 0);
+ omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
- timer->posted = 1;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
@@ -176,6 +176,27 @@ int omap_dm_timer_reserve_systimer(int id)
return 0;
}
+/**
+ * omap_dm_timer_enable_posted - enables write posted mode
+ * @timer: pointer to timer instance handle
+ *
+ * Enables the write posted mode for the timer. When posted mode is enabled
+ * writes to certain timer registers are immediately acknowledged by the
+ * internal bus and hence prevents stalling the CPU waiting for the write to
+ * complete. Enabling this feature can improve performance for writing to the
+ * timer registers.
+ */
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
+{
+ if (timer->posted)
+ return;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
+ timer->posted = OMAP_TIMER_POSTED;
+}
+
struct omap_dm_timer *omap_dm_timer_request(void)
{
struct omap_dm_timer *timer = NULL, *t;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 835c3bdf..2d0228f 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -101,6 +101,7 @@ struct dmtimer_platform_data {
};
int omap_dm_timer_reserve_systimer(int id);
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
@@ -342,10 +343,6 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
l |= 1 << 2;
__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-
- /* Match hardware reset default of posted mode */
- __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
- OMAP_TIMER_CTRL_POSTED, 0);
}
static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer
2012-11-07 19:01 ` [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer Jon Hunter
@ 2012-11-07 22:10 ` Santosh Shilimkar
2012-11-07 22:41 ` Jon Hunter
0 siblings, 1 reply; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:10 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
> When using a DMTIMER as the clock-source timer, posted mode configuration of
> the DMTIMER is used. Posted mode is only benefical when configuring timers as
> it allows writes to be posted and does not stall the CPU until the write is
> complete. The clock-source timer is only configured once on boot and so using
> posted mode has no benefit. In fact, by using posted mode, it adds overhead
> to reading the timer. Therefore, by default disable posted mode for DMTIMERs
> used for clock-source.
>
> Using objdump this change reduces the function clocksource_read_cycles()
> function from a total of 15 instructions (including 3 branches and 7 loads)
> to 5 instructions (including 1 branch and 3 loads). Please note that before
> the minimum number of instructions that would be executed when calling
> clocksource_read_cycles() would be 9 instructions (including 2 branches and 5
> loads) where as now it will always be 5 instructions.
>
> This change also reduces the function dmtimer_read_sched_clock() function from
> a total of 17 instructions (including 4 branches and 8 loads) to 6 instructions
> (including 1 branch and 4 loads). Please note that before the minimum number of
> instructions that would be executed when calling dmtimer_read_sched_clock()
> would be 11 instructions (including 2 branches and 6 loads) where as now it
> will always be 6 instructions.
>
This isn't right way to calculate the penalty of posted mode. Non-posted
mode can results in 100 of cycles wait over interconnect
and that can not be justified with few instructions savings.
> This change removes the configuration of posted mode from the
> __omap_dm_timer_reset() function and adds a new function called
> omap_dm_timer_enable_posted() for enabling posted mode. Hence, call
> omap_dm_timer_enable_posted() where ever we are calling __omap_dm_timer_reset().
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
But clock-source doesn't involve much into writes so patch as
such is fine.
Regards
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer
2012-11-07 22:10 ` Santosh Shilimkar
@ 2012-11-07 22:41 ` Jon Hunter
0 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 22:41 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 04:10 PM, Santosh Shilimkar wrote:
> On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
>> When using a DMTIMER as the clock-source timer, posted mode
>> configuration of
>> the DMTIMER is used. Posted mode is only benefical when configuring
>> timers as
>> it allows writes to be posted and does not stall the CPU until the
>> write is
>> complete. The clock-source timer is only configured once on boot and
>> so using
>> posted mode has no benefit. In fact, by using posted mode, it adds
>> overhead
>> to reading the timer. Therefore, by default disable posted mode for
>> DMTIMERs
>> used for clock-source.
>>
>> Using objdump this change reduces the function clocksource_read_cycles()
>> function from a total of 15 instructions (including 3 branches and 7
>> loads)
>> to 5 instructions (including 1 branch and 3 loads). Please note that
>> before
>> the minimum number of instructions that would be executed when calling
>> clocksource_read_cycles() would be 9 instructions (including 2
>> branches and 5
>> loads) where as now it will always be 5 instructions.
>>
>> This change also reduces the function dmtimer_read_sched_clock()
>> function from
>> a total of 17 instructions (including 4 branches and 8 loads) to 6
>> instructions
>> (including 1 branch and 4 loads). Please note that before the minimum
>> number of
>> instructions that would be executed when calling
>> dmtimer_read_sched_clock()
>> would be 11 instructions (including 2 branches and 6 loads) where as
>> now it
>> will always be 6 instructions.
>>
> This isn't right way to calculate the penalty of posted mode. Non-posted
> mode can results in 100 of cycles wait over interconnect
> and that can not be justified with few instructions savings.
Right, I see your point. Non-posted reads are going to add
re-synchronisation overhead. However, our hands are tied here because of
errata i103 we can't use posted mode for reading the counter.
So may be I should squash this change with patch #3 and just make this
part of the errata workaround. I can always re-visit later and do some
profiling to see what the optimal configuration should be.
>> This change removes the configuration of posted mode from the
>> __omap_dm_timer_reset() function and adds a new function called
>> omap_dm_timer_enable_posted() for enabling posted mode. Hence, call
>> omap_dm_timer_enable_posted() where ever we are calling
>> __omap_dm_timer_reset().
>>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
> But clock-source doesn't involve much into writes so patch as
> such is fine.
Yes writes are only on init.
Cheers
Jon
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
2012-11-07 19:01 ` [PATCH V2 01/14] ARM: OMAP: Add DMTIMER definitions for posted mode Jon Hunter
2012-11-07 19:01 ` [PATCH V2 02/14] ARM: OMAP2+: Disable posted mode for the clocksource timer Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 22:14 ` Santosh Shilimkar
2012-11-07 19:01 ` [PATCH V2 04/14] ARM: OMAP: Fix timer posted mode support Jon Hunter
` (12 subsequent siblings)
15 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Errata Titles:
i103: Delay needed to read some GP timer, WD timer and sync timer registers
after wakeup (OMAP3/4)
i767: Delay needed to read some GP timer registers after wakeup (OMAP5)
Description (i103/i767):
If a General Purpose Timer (GPTimer) is in posted mode (TSICR [2].POSTED=1),
due to internal resynchronizations, values read in TCRR, TCAR1 and TCAR2
registers right after the timer interface clock (L4) goes from stopped to
active may not return the expected values. The most common event leading to
this situation occurs upon wake up from idle.
GPTimer non-posted synchronization mode is not impacted by this limitation.
Workarounds:
1). Disable posted mode
2). Use static dependency between timer clock domain and MPUSS clock domain
3). Use no-idle mode when the timer is active
Workarounds #2 and #3 are not pratical from a power standpoint and so
workaround #1 has been implemented. Disabling posted mode adds some CPU overhead
for configuring the timers as the CPU has to wait for the write to complete.
However, disabling posted mode guarantees correct operation.
Please note that it is safe to use posted mode for timers if the counter (TCRR)
and capture (TCARx) registers will never be read. An example of this is the
clock-event system timer. This is used by the kernel to schedule events however,
the timers counter is never read and capture registers are not used. Given that
the kernel configures this timer often yet never reads the counter register it
is safe to enable posted mode in this case. Hence, for the timer used for kernel
clock-events, posted mode is enabled by overriding the errata for devices that
are impacted by this defect.
For drivers using the timers that do not read the counter or capture registers
and wish to use posted mode, can override the errata and enable posted mode by
making the following function calls.
omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
omap_dm_timer_enable_posted(timer);
Both dmtimers and watchdogs are impacted by this defect this patch only
implements the workaround for the dmtimer. Currently the watchdog driver does
not read the counter register and so no workaround is necessary.
Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx devices.
Please note that now calls to omap_dm_timer_enable_posted() may not able posted
mode if the device is impacted by this errata. Therefore, for system-timers
check to see if the intended posted mode matches the actual. If it does not then
there is a configuration error in the system timers posted configuration.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 15 ++++++++++++
arch/arm/plat-omap/dmtimer.c | 36 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/dmtimer.h | 14 +++++++++++
3 files changed, 65 insertions(+)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 78b7712..8b0068c 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -332,6 +332,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
if (posted)
omap_dm_timer_enable_posted(timer);
+ /* Check that the intended posted configuration matches the actual */
+ if (posted != timer->posted)
+ return -EINVAL;
+
timer->rate = clk_get_rate(timer->fclk);
timer->reserved = 1;
@@ -344,6 +348,15 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
{
int res;
+ omap_dm_timer_populate_errata(&clkev);
+
+ /*
+ * For clock-event timers we never read the timer counter and
+ * so we are not impacted by errata i103 and i767. Therefore,
+ * we can safely ignore this errata for clock-event timers.
+ */
+ omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
+
res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
OMAP_CLKEVT_POSTEDMODE);
BUG_ON(res);
@@ -472,6 +485,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int res;
+ omap_dm_timer_populate_errata(&clksrc);
+
res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
OMAP_CLKSRC_POSTEDMODE);
BUG_ON(res);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 699570b..4abbbe5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -177,6 +177,37 @@ int omap_dm_timer_reserve_systimer(int id)
}
/**
+ * omap_dm_timer_populate_errata - populate errata flags for a timer
+ * @timer: pointer to timer handle
+ *
+ * For a given timer, populate the timer errata flags that are specific to the
+ * OMAP device being used.
+ */
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer)
+{
+ timer->errata = 0;
+
+ if (cpu_class_is_omap1() || cpu_is_omap24xx())
+ return;
+
+ timer->errata = OMAP_TIMER_ERRATA_I103_I767;
+}
+
+/**
+ * omap_dm_timer_override_errata - override errata flags for a timer
+ * @timer: pointer to timer handle
+ * @errata: errata flags to be ignored
+ *
+ * For a given timer, override a timer errata by clearing the flags specified
+ * by the errata argument. A specific erratum should only be overridden for a
+ * timer if the timer is used in such a way the erratum has no impact.
+ */
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata)
+{
+ timer->errata &= ~errata;
+}
+
+/*
* omap_dm_timer_enable_posted - enables write posted mode
* @timer: pointer to timer instance handle
*
@@ -191,6 +222,9 @@ void omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
if (timer->posted)
return;
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+ return;
+
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
OMAP_TIMER_CTRL_POSTED);
timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
@@ -824,6 +858,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer->irq = irq->start;
timer->pdev = pdev;
+ omap_dm_timer_populate_errata(timer);
+
/* Skip pm_runtime_enable for OMAP1 */
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
pm_runtime_enable(dev);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 2d0228f..ef93017 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <plat/cpu.h>
#ifndef __ASM_ARCH_DMTIMER_H
#define __ASM_ARCH_DMTIMER_H
@@ -66,6 +67,16 @@
#define OMAP_TIMER_NEEDS_RESET 0x10000000
#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
struct omap_timer_capability_dev_attr {
u32 timer_capability;
};
@@ -101,6 +112,8 @@ struct dmtimer_platform_data {
};
int omap_dm_timer_reserve_systimer(int id);
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer);
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata);
void omap_dm_timer_enable_posted(struct omap_dm_timer *timer);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
@@ -272,6 +285,7 @@ struct omap_dm_timer {
int ctx_loss_count;
int revision;
u32 capability;
+ u32 errata;
struct platform_device *pdev;
struct list_head node;
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-07 19:01 ` [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767 Jon Hunter
@ 2012-11-07 22:14 ` Santosh Shilimkar
2012-11-07 23:28 ` Jon Hunter
0 siblings, 1 reply; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:14 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
> Errata Titles:
> i103: Delay needed to read some GP timer, WD timer and sync timer registers
> after wakeup (OMAP3/4)
> i767: Delay needed to read some GP timer registers after wakeup (OMAP5)
>
> Description (i103/i767):
> If a General Purpose Timer (GPTimer) is in posted mode (TSICR [2].POSTED=1),
> due to internal resynchronizations, values read in TCRR, TCAR1 and TCAR2
> registers right after the timer interface clock (L4) goes from stopped to
> active may not return the expected values. The most common event leading to
> this situation occurs upon wake up from idle.
>
> GPTimer non-posted synchronization mode is not impacted by this limitation.
>
> Workarounds:
> 1). Disable posted mode
> 2). Use static dependency between timer clock domain and MPUSS clock domain
> 3). Use no-idle mode when the timer is active
>
> Workarounds #2 and #3 are not pratical from a power standpoint and so
> workaround #1 has been implemented. Disabling posted mode adds some CPU overhead
> for configuring the timers as the CPU has to wait for the write to complete.
> However, disabling posted mode guarantees correct operation.
>
> Please note that it is safe to use posted mode for timers if the counter (TCRR)
> and capture (TCARx) registers will never be read. An example of this is the
> clock-event system timer. This is used by the kernel to schedule events however,
> the timers counter is never read and capture registers are not used. Given that
> the kernel configures this timer often yet never reads the counter register it
> is safe to enable posted mode in this case. Hence, for the timer used for kernel
> clock-events, posted mode is enabled by overriding the errata for devices that
> are impacted by this defect.
>
> For drivers using the timers that do not read the counter or capture registers
> and wish to use posted mode, can override the errata and enable posted mode by
> making the following function calls.
>
> omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
> omap_dm_timer_enable_posted(timer);
>
> Both dmtimers and watchdogs are impacted by this defect this patch only
> implements the workaround for the dmtimer. Currently the watchdog driver does
> not read the counter register and so no workaround is necessary.
>
> Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx devices.
>
> Please note that now calls to omap_dm_timer_enable_posted() may not able posted
> mode if the device is impacted by this errata. Therefore, for system-timers
> check to see if the intended posted mode matches the actual. If it does not then
> there is a configuration error in the system timers posted configuration.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
Looks sensible considering alternative WAs.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-07 22:14 ` Santosh Shilimkar
@ 2012-11-07 23:28 ` Jon Hunter
2012-11-07 23:43 ` Santosh Shilimkar
0 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 23:28 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 04:14 PM, Santosh Shilimkar wrote:
> Looks sensible considering alternative WAs.
>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Thanks. With further thought I think that it would be best to combine
patches #2 and #3. Really the main motivation here is the errata
workaround and without actually benchmarking the timer read I should
not claim the improvement in overhead as stated in patch #2. So I
have combined #2 and #3 and updated the changelog/comments
appropriately. Let me know if you guys are ok with this.
Cheers
Jon
>From 0143aa216ef4c4b7554588bd72c417bc8c614525 Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 27 Sep 2012 12:47:43 -0500
Subject: [PATCH] ARM: OMAP3+: Implement timer workaround for errata i103 and
i767
Errata Titles:
i103: Delay needed to read some GP timer, WD timer and sync timer
registers after wakeup (OMAP3/4)
i767: Delay needed to read some GP timer registers after wakeup (OMAP5)
Description (i103/i767):
If a General Purpose Timer (GPTimer) is in posted mode
(TSICR [2].POSTED=1), due to internal resynchronizations, values read in
TCRR, TCAR1 and TCAR2 registers right after the timer interface clock
(L4) goes from stopped to active may not return the expected values. The
most common event leading to this situation occurs upon wake up from
idle.
GPTimer non-posted synchronization mode is not impacted by this
limitation.
Workarounds:
1). Disable posted mode
2). Use static dependency between timer clock domain and MPUSS clock
domain
3). Use no-idle mode when the timer is active
Workarounds #2 and #3 are not pratical from a power standpoint and so
workaround #1 has been implemented. Disabling posted mode adds some CPU
overhead for configuring and reading the timers as the CPU has to wait
for accesses to be re-synchronised within the timer. However, disabling
posted mode guarantees correct operation.
Please note that it is safe to use posted mode for timers if the counter
(TCRR) and capture (TCARx) registers will never be read. An example of
this is the clock-event system timer. This is used by the kernel to
schedule events however, the timers counter is never read and capture
registers are not used. Given that the kernel configures this timer
often yet never reads the counter register it is safe to enable posted
mode in this case. Hence, for the timer used for kernel clock-events,
posted mode is enabled by overriding the errata for devices that are
impacted by this defect.
For drivers using the timers that do not read the counter or capture
registers and wish to use posted mode, can override the errata and
enable posted mode by making the following function calls.
omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
omap_dm_timer_enable_posted(timer);
Both dmtimers and watchdogs are impacted by this defect this patch only
implements the workaround for the dmtimer. Currently the watchdog driver
does not read the counter register and so no workaround is necessary.
Posted mode will be disabled for all OMAP2+ devices (including AM33xx)
using a GP timer as a clock-source timer to guarantee correct operation.
This is not necessary for OMAP24xx devices but the default clock-source
timer for OMAP24xx devices is the 32k-sync timer and not the GP timer
and so should not have any impact. This should be re-visited for future
devices if this errata is fixed.
Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx
devices.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 44 +++++++++++++++++----
arch/arm/plat-omap/dmtimer.c | 59 ++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/dmtimer.h | 19 ++++++++--
3 files changed, 109 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 28c6078..37e3089 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -83,11 +83,20 @@
#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
/*
- * For clock-events timer, always use posted mode to
- * minimise CPU overhead for configuring the timer.
+ * For the clock-events timer, always use posted mode to
+ * minimise CPU overhead for configuring the timer. This timer
+ * is never read and so overhead of reading the timer in posted
+ * mode is not applicable.
*/
#define OMAP_CLKEVT_POSTEDMODE OMAP_TIMER_POSTED
-#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_POSTED
+
+/*
+ * For the clock-source timer, use non-posted mode default due to
+ * errata i103/i767 that can cause the timer to return an incorrect
+ * counter value for OMAP3/4/5 devices. REVISIT this to see what is
+ * the optimal way to handle for future devices.
+ */
+#define OMAP_CLKSRC_POSTEDMODE OMAP_TIMER_NONPOSTED
/* Clockevent code */
@@ -233,7 +242,8 @@ void __init omap_dmtimer_init(void)
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
int gptimer_id,
const char *fck_source,
- const char *property)
+ const char *property,
+ int posted)
{
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name;
@@ -319,10 +329,15 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
__omap_dm_timer_init_regs(timer);
__omap_dm_timer_reset(timer, 1, 1);
- timer->posted = 1;
- timer->rate = clk_get_rate(timer->fclk);
+ if (posted)
+ omap_dm_timer_enable_posted(timer);
+
+ /* Check that the intended posted configuration matches the actual */
+ if (posted != timer->posted)
+ return -EINVAL;
+ timer->rate = clk_get_rate(timer->fclk);
timer->reserved = 1;
return res;
@@ -334,7 +349,17 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property);
+ omap_dm_timer_populate_errata(&clkev);
+
+ /*
+ * For clock-event timers we never read the timer counter and
+ * so we are not impacted by errata i103 and i767. Therefore,
+ * we can safely ignore this errata for clock-event timers.
+ */
+ omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
+
+ res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
+ OMAP_CLKEVT_POSTEDMODE);
BUG_ON(res);
omap2_gp_timer_irq.dev_id = &clkev;
@@ -461,7 +486,10 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL);
+ omap_dm_timer_populate_errata(&clksrc);
+
+ res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
+ OMAP_CLKSRC_POSTEDMODE);
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index b09e556..4abbbe5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -131,8 +131,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
}
__omap_dm_timer_reset(timer, 0, 0);
+ omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
- timer->posted = 1;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
@@ -176,6 +176,61 @@ int omap_dm_timer_reserve_systimer(int id)
return 0;
}
+/**
+ * omap_dm_timer_populate_errata - populate errata flags for a timer
+ * @timer: pointer to timer handle
+ *
+ * For a given timer, populate the timer errata flags that are specific to the
+ * OMAP device being used.
+ */
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer)
+{
+ timer->errata = 0;
+
+ if (cpu_class_is_omap1() || cpu_is_omap24xx())
+ return;
+
+ timer->errata = OMAP_TIMER_ERRATA_I103_I767;
+}
+
+/**
+ * omap_dm_timer_override_errata - override errata flags for a timer
+ * @timer: pointer to timer handle
+ * @errata: errata flags to be ignored
+ *
+ * For a given timer, override a timer errata by clearing the flags specified
+ * by the errata argument. A specific erratum should only be overridden for a
+ * timer if the timer is used in such a way the erratum has no impact.
+ */
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata)
+{
+ timer->errata &= ~errata;
+}
+
+/*
+ * omap_dm_timer_enable_posted - enables write posted mode
+ * @timer: pointer to timer instance handle
+ *
+ * Enables the write posted mode for the timer. When posted mode is enabled
+ * writes to certain timer registers are immediately acknowledged by the
+ * internal bus and hence prevents stalling the CPU waiting for the write to
+ * complete. Enabling this feature can improve performance for writing to the
+ * timer registers.
+ */
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
+{
+ if (timer->posted)
+ return;
+
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+ return;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
+ timer->posted = OMAP_TIMER_POSTED;
+}
+
struct omap_dm_timer *omap_dm_timer_request(void)
{
struct omap_dm_timer *timer = NULL, *t;
@@ -803,6 +858,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer->irq = irq->start;
timer->pdev = pdev;
+ omap_dm_timer_populate_errata(timer);
+
/* Skip pm_runtime_enable for OMAP1 */
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
pm_runtime_enable(dev);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 835c3bdf..ef93017 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <plat/cpu.h>
#ifndef __ASM_ARCH_DMTIMER_H
#define __ASM_ARCH_DMTIMER_H
@@ -66,6 +67,16 @@
#define OMAP_TIMER_NEEDS_RESET 0x10000000
#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
struct omap_timer_capability_dev_attr {
u32 timer_capability;
};
@@ -101,6 +112,9 @@ struct dmtimer_platform_data {
};
int omap_dm_timer_reserve_systimer(int id);
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer);
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata);
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
@@ -271,6 +285,7 @@ struct omap_dm_timer {
int ctx_loss_count;
int revision;
u32 capability;
+ u32 errata;
struct platform_device *pdev;
struct list_head node;
};
@@ -342,10 +357,6 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
l |= 1 << 2;
__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-
- /* Match hardware reset default of posted mode */
- __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
- OMAP_TIMER_CTRL_POSTED, 0);
}
static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-07 23:28 ` Jon Hunter
@ 2012-11-07 23:43 ` Santosh Shilimkar
2012-11-08 16:55 ` Jon Hunter
0 siblings, 1 reply; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 23:43 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 05:28 PM, Jon Hunter wrote:
>
> On 11/07/2012 04:14 PM, Santosh Shilimkar wrote:
>
>> Looks sensible considering alternative WAs.
>>
>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>
> Thanks. With further thought I think that it would be best to combine
> patches #2 and #3. Really the main motivation here is the errata
> workaround and without actually benchmarking the timer read I should
> not claim the improvement in overhead as stated in patch #2. So I
> have combined #2 and #3 and updated the changelog/comments
> appropriately. Let me know if you guys are ok with this.
>
Yep. Sounds good.
Regards
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-07 23:43 ` Santosh Shilimkar
@ 2012-11-08 16:55 ` Jon Hunter
2012-11-09 19:41 ` Jon Hunter
0 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-08 16:55 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 05:43 PM, Santosh Shilimkar wrote:
> On Wednesday 07 November 2012 05:28 PM, Jon Hunter wrote:
>>
>> On 11/07/2012 04:14 PM, Santosh Shilimkar wrote:
>>
>>> Looks sensible considering alternative WAs.
>>>
>>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>
>> Thanks. With further thought I think that it would be best to combine
>> patches #2 and #3. Really the main motivation here is the errata
>> workaround and without actually benchmarking the timer read I should
>> not claim the improvement in overhead as stated in patch #2. So I
>> have combined #2 and #3 and updated the changelog/comments
>> appropriately. Let me know if you guys are ok with this.
>>
> Yep. Sounds good.
Updated, removing the additional OMAP_CLKEVT/SRC_POSTEDMODE definitions.
Cheers
Jon
>From 5b55c6c2ca6f41e37f531d8ca0ea80a0e49f3e4d Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 27 Sep 2012 12:47:43 -0500
Subject: [PATCH 2/2] ARM: OMAP3+: Implement timer workaround for errata i103
and i767
Errata Titles:
i103: Delay needed to read some GP timer, WD timer and sync timer
registers after wakeup (OMAP3/4)
i767: Delay needed to read some GP timer registers after wakeup (OMAP5)
Description (i103/i767):
If a General Purpose Timer (GPTimer) is in posted mode
(TSICR [2].POSTED=1), due to internal resynchronizations, values read in
TCRR, TCAR1 and TCAR2 registers right after the timer interface clock
(L4) goes from stopped to active may not return the expected values. The
most common event leading to this situation occurs upon wake up from
idle.
GPTimer non-posted synchronization mode is not impacted by this
limitation.
Workarounds:
1). Disable posted mode
2). Use static dependency between timer clock domain and MPUSS clock
domain
3). Use no-idle mode when the timer is active
Workarounds #2 and #3 are not pratical from a power standpoint and so
workaround #1 has been implemented. Disabling posted mode adds some CPU
overhead for configuring and reading the timers as the CPU has to wait
for accesses to be re-synchronised within the timer. However, disabling
posted mode guarantees correct operation.
Please note that it is safe to use posted mode for timers if the counter
(TCRR) and capture (TCARx) registers will never be read. An example of
this is the clock-event system timer. This is used by the kernel to
schedule events however, the timers counter is never read and capture
registers are not used. Given that the kernel configures this timer
often yet never reads the counter register it is safe to enable posted
mode in this case. Hence, for the timer used for kernel clock-events,
posted mode is enabled by overriding the errata for devices that are
impacted by this defect.
For drivers using the timers that do not read the counter or capture
registers and wish to use posted mode, can override the errata and
enable posted mode by making the following function calls.
omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
omap_dm_timer_enable_posted(timer);
Both dmtimers and watchdogs are impacted by this defect this patch only
implements the workaround for the dmtimer. Currently the watchdog driver
does not read the counter register and so no workaround is necessary.
Posted mode will be disabled for all OMAP2+ devices (including AM33xx)
using a GP timer as a clock-source timer to guarantee correct operation.
This is not necessary for OMAP24xx devices but the default clock-source
timer for OMAP24xx devices is the 32k-sync timer and not the GP timer
and so should not have any impact. This should be re-visited for future
devices if this errata is fixed.
Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx
devices.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 35 +++++++++++++----
arch/arm/plat-omap/dmtimer.c | 59 ++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/dmtimer.h | 19 ++++++++--
3 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index ad427ba..e99b95c 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -224,7 +224,8 @@ void __init omap_dmtimer_init(void)
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
int gptimer_id,
const char *fck_source,
- const char *property)
+ const char *property,
+ int posted)
{
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name;
@@ -310,10 +311,15 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
__omap_dm_timer_init_regs(timer);
__omap_dm_timer_reset(timer, 1, 1);
- timer->posted = 1;
- timer->rate = clk_get_rate(timer->fclk);
+ if (posted)
+ omap_dm_timer_enable_posted(timer);
+ /* Check that the intended posted configuration matches the actual */
+ if (posted != timer->posted)
+ return -EINVAL;
+
+ timer->rate = clk_get_rate(timer->fclk);
timer->reserved = 1;
return res;
@@ -325,7 +331,17 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property);
+ omap_dm_timer_populate_errata(&clkev);
+
+ /*
+ * For clock-event timers we never read the timer counter and
+ * so we are not impacted by errata i103 and i767. Therefore,
+ * we can safely ignore this errata for clock-event timers.
+ */
+ omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
+
+ res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
+ OMAP_TIMER_POSTED);
BUG_ON(res);
omap2_gp_timer_irq.dev_id = &clkev;
@@ -359,7 +375,7 @@ static bool use_gptimer_clksrc;
static cycle_t clocksource_read_cycles(struct clocksource *cs)
{
return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
}
static struct clocksource clocksource_gpt = {
@@ -374,7 +390,7 @@ static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
return __omap_dm_timer_read_counter(&clksrc,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
return 0;
}
@@ -452,12 +468,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL);
+ omap_dm_timer_populate_errata(&clksrc);
+
+ res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
+ OMAP_TIMER_NONPOSTED);
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index b09e556..4abbbe5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -131,8 +131,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
}
__omap_dm_timer_reset(timer, 0, 0);
+ omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
- timer->posted = 1;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
@@ -176,6 +176,61 @@ int omap_dm_timer_reserve_systimer(int id)
return 0;
}
+/**
+ * omap_dm_timer_populate_errata - populate errata flags for a timer
+ * @timer: pointer to timer handle
+ *
+ * For a given timer, populate the timer errata flags that are specific to the
+ * OMAP device being used.
+ */
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer)
+{
+ timer->errata = 0;
+
+ if (cpu_class_is_omap1() || cpu_is_omap24xx())
+ return;
+
+ timer->errata = OMAP_TIMER_ERRATA_I103_I767;
+}
+
+/**
+ * omap_dm_timer_override_errata - override errata flags for a timer
+ * @timer: pointer to timer handle
+ * @errata: errata flags to be ignored
+ *
+ * For a given timer, override a timer errata by clearing the flags specified
+ * by the errata argument. A specific erratum should only be overridden for a
+ * timer if the timer is used in such a way the erratum has no impact.
+ */
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata)
+{
+ timer->errata &= ~errata;
+}
+
+/*
+ * omap_dm_timer_enable_posted - enables write posted mode
+ * @timer: pointer to timer instance handle
+ *
+ * Enables the write posted mode for the timer. When posted mode is enabled
+ * writes to certain timer registers are immediately acknowledged by the
+ * internal bus and hence prevents stalling the CPU waiting for the write to
+ * complete. Enabling this feature can improve performance for writing to the
+ * timer registers.
+ */
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
+{
+ if (timer->posted)
+ return;
+
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+ return;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
+ timer->posted = OMAP_TIMER_POSTED;
+}
+
struct omap_dm_timer *omap_dm_timer_request(void)
{
struct omap_dm_timer *timer = NULL, *t;
@@ -803,6 +858,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer->irq = irq->start;
timer->pdev = pdev;
+ omap_dm_timer_populate_errata(timer);
+
/* Skip pm_runtime_enable for OMAP1 */
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
pm_runtime_enable(dev);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 835c3bdf..ef93017 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <plat/cpu.h>
#ifndef __ASM_ARCH_DMTIMER_H
#define __ASM_ARCH_DMTIMER_H
@@ -66,6 +67,16 @@
#define OMAP_TIMER_NEEDS_RESET 0x10000000
#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
struct omap_timer_capability_dev_attr {
u32 timer_capability;
};
@@ -101,6 +112,9 @@ struct dmtimer_platform_data {
};
int omap_dm_timer_reserve_systimer(int id);
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer);
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata);
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
@@ -271,6 +285,7 @@ struct omap_dm_timer {
int ctx_loss_count;
int revision;
u32 capability;
+ u32 errata;
struct platform_device *pdev;
struct list_head node;
};
@@ -342,10 +357,6 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
l |= 1 << 2;
__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-
- /* Match hardware reset default of posted mode */
- __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
- OMAP_TIMER_CTRL_POSTED, 0);
}
static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767
2012-11-08 16:55 ` Jon Hunter
@ 2012-11-09 19:41 ` Jon Hunter
0 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-09 19:41 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/08/2012 10:55 AM, Jon Hunter wrote:
>
> On 11/07/2012 05:43 PM, Santosh Shilimkar wrote:
>> On Wednesday 07 November 2012 05:28 PM, Jon Hunter wrote:
>>>
>>> On 11/07/2012 04:14 PM, Santosh Shilimkar wrote:
>>>
>>>> Looks sensible considering alternative WAs.
>>>>
>>>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>
>>> Thanks. With further thought I think that it would be best to combine
>>> patches #2 and #3. Really the main motivation here is the errata
>>> workaround and without actually benchmarking the timer read I should
>>> not claim the improvement in overhead as stated in patch #2. So I
>>> have combined #2 and #3 and updated the changelog/comments
>>> appropriately. Let me know if you guys are ok with this.
>>>
>> Yep. Sounds good.
>
> Updated, removing the additional OMAP_CLKEVT/SRC_POSTEDMODE definitions.
Another minor update after rebasing on Tony's linux-omap master. I
needed to fix-up headers included.
Cheers
Jon
>From 0b2e3ef2cea7896f6466e010f9ab22a86a00bba1 Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 27 Sep 2012 12:47:43 -0500
Subject: [PATCH] ARM: OMAP3+: Implement timer workaround for errata i103 and
i767
Errata Titles:
i103: Delay needed to read some GP timer, WD timer and sync timer
registers after wakeup (OMAP3/4)
i767: Delay needed to read some GP timer registers after wakeup (OMAP5)
Description (i103/i767):
If a General Purpose Timer (GPTimer) is in posted mode
(TSICR [2].POSTED=1), due to internal resynchronizations, values read in
TCRR, TCAR1 and TCAR2 registers right after the timer interface clock
(L4) goes from stopped to active may not return the expected values. The
most common event leading to this situation occurs upon wake up from
idle.
GPTimer non-posted synchronization mode is not impacted by this
limitation.
Workarounds:
1). Disable posted mode
2). Use static dependency between timer clock domain and MPUSS clock
domain
3). Use no-idle mode when the timer is active
Workarounds #2 and #3 are not pratical from a power standpoint and so
workaround #1 has been implemented. Disabling posted mode adds some CPU
overhead for configuring and reading the timers as the CPU has to wait
for accesses to be re-synchronised within the timer. However, disabling
posted mode guarantees correct operation.
Please note that it is safe to use posted mode for timers if the counter
(TCRR) and capture (TCARx) registers will never be read. An example of
this is the clock-event system timer. This is used by the kernel to
schedule events however, the timers counter is never read and capture
registers are not used. Given that the kernel configures this timer
often yet never reads the counter register it is safe to enable posted
mode in this case. Hence, for the timer used for kernel clock-events,
posted mode is enabled by overriding the errata for devices that are
impacted by this defect.
For drivers using the timers that do not read the counter or capture
registers and wish to use posted mode, can override the errata and
enable posted mode by making the following function calls.
omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
omap_dm_timer_enable_posted(timer);
Both dmtimers and watchdogs are impacted by this defect this patch only
implements the workaround for the dmtimer. Currently the watchdog driver
does not read the counter register and so no workaround is necessary.
Posted mode will be disabled for all OMAP2+ devices (including AM33xx)
using a GP timer as a clock-source timer to guarantee correct operation.
This is not necessary for OMAP24xx devices but the default clock-source
timer for OMAP24xx devices is the 32k-sync timer and not the GP timer
and so should not have any impact. This should be re-visited for future
devices if this errata is fixed.
Confirmed with Vaibhav Hiremath that this bug also impacts AM33xx
devices.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
arch/arm/mach-omap2/timer.c | 35 +++++++++++++----
arch/arm/plat-omap/dmtimer.c | 60 ++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/dmtimer.h | 18 +++++++--
3 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index a135d28..23ebe15 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -225,7 +225,8 @@ void __init omap_dmtimer_init(void)
static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
int gptimer_id,
const char *fck_source,
- const char *property)
+ const char *property,
+ int posted)
{
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name;
@@ -311,10 +312,15 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
__omap_dm_timer_init_regs(timer);
__omap_dm_timer_reset(timer, 1, 1);
- timer->posted = 1;
- timer->rate = clk_get_rate(timer->fclk);
+ if (posted)
+ omap_dm_timer_enable_posted(timer);
+ /* Check that the intended posted configuration matches the actual */
+ if (posted != timer->posted)
+ return -EINVAL;
+
+ timer->rate = clk_get_rate(timer->fclk);
timer->reserved = 1;
return res;
@@ -326,7 +332,17 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property);
+ omap_dm_timer_populate_errata(&clkev);
+
+ /*
+ * For clock-event timers we never read the timer counter and
+ * so we are not impacted by errata i103 and i767. Therefore,
+ * we can safely ignore this errata for clock-event timers.
+ */
+ omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
+
+ res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
+ OMAP_TIMER_POSTED);
BUG_ON(res);
omap2_gp_timer_irq.dev_id = &clkev;
@@ -360,7 +376,7 @@ static bool use_gptimer_clksrc;
static cycle_t clocksource_read_cycles(struct clocksource *cs)
{
return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
}
static struct clocksource clocksource_gpt = {
@@ -375,7 +391,7 @@ static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
return __omap_dm_timer_read_counter(&clksrc,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
return 0;
}
@@ -453,12 +469,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
{
int res;
- res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL);
+ omap_dm_timer_populate_errata(&clksrc);
+
+ res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
+ OMAP_TIMER_NONPOSTED);
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
- OMAP_TIMER_POSTED);
+ OMAP_TIMER_NONPOSTED);
setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 9dca23e..9a15123 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -43,6 +43,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
+#include <plat/cpu.h>
#include <plat/dmtimer.h>
static u32 omap_reserved_systimers;
@@ -128,8 +129,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
}
__omap_dm_timer_reset(timer, 0, 0);
+ omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
- timer->posted = 1;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
@@ -173,6 +174,61 @@ int omap_dm_timer_reserve_systimer(int id)
return 0;
}
+/**
+ * omap_dm_timer_populate_errata - populate errata flags for a timer
+ * @timer: pointer to timer handle
+ *
+ * For a given timer, populate the timer errata flags that are specific to the
+ * OMAP device being used.
+ */
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer)
+{
+ timer->errata = 0;
+
+ if (cpu_class_is_omap1() || cpu_is_omap24xx())
+ return;
+
+ timer->errata = OMAP_TIMER_ERRATA_I103_I767;
+}
+
+/**
+ * omap_dm_timer_override_errata - override errata flags for a timer
+ * @timer: pointer to timer handle
+ * @errata: errata flags to be ignored
+ *
+ * For a given timer, override a timer errata by clearing the flags specified
+ * by the errata argument. A specific erratum should only be overridden for a
+ * timer if the timer is used in such a way the erratum has no impact.
+ */
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata)
+{
+ timer->errata &= ~errata;
+}
+
+/*
+ * omap_dm_timer_enable_posted - enables write posted mode
+ * @timer: pointer to timer instance handle
+ *
+ * Enables the write posted mode for the timer. When posted mode is enabled
+ * writes to certain timer registers are immediately acknowledged by the
+ * internal bus and hence prevents stalling the CPU waiting for the write to
+ * complete. Enabling this feature can improve performance for writing to the
+ * timer registers.
+ */
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
+{
+ if (timer->posted)
+ return;
+
+ if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
+ return;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
+ timer->posted = OMAP_TIMER_POSTED;
+}
+
struct omap_dm_timer *omap_dm_timer_request(void)
{
struct omap_dm_timer *timer = NULL, *t;
@@ -805,6 +861,8 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer->irq = irq->start;
timer->pdev = pdev;
+ omap_dm_timer_populate_errata(timer);
+
/* Skip pm_runtime_enable for OMAP1 */
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
pm_runtime_enable(dev);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 1bee0ac..2ebc8d6 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -66,6 +66,16 @@
#define OMAP_TIMER_NEEDS_RESET 0x10000000
#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
struct omap_timer_capability_dev_attr {
u32 timer_capability;
};
@@ -102,6 +112,9 @@ struct dmtimer_platform_data {
};
int omap_dm_timer_reserve_systimer(int id);
+void omap_dm_timer_populate_errata(struct omap_dm_timer *timer);
+void omap_dm_timer_override_errata(struct omap_dm_timer *timer, u32 errata);
+void omap_dm_timer_enable_posted(struct omap_dm_timer *timer);
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
@@ -273,6 +286,7 @@ struct omap_dm_timer {
int ctx_loss_count;
int revision;
u32 capability;
+ u32 errata;
struct platform_device *pdev;
struct list_head node;
};
@@ -344,10 +358,6 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
l |= 1 << 2;
__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-
- /* Match hardware reset default of posted mode */
- __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
- OMAP_TIMER_CTRL_POSTED, 0);
}
static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 04/14] ARM: OMAP: Fix timer posted mode support
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (2 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 03/14] ARM: OMAP3+: Implement timer workaround for errata i103 and i767 Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 22:21 ` Santosh Shilimkar
2012-11-07 19:01 ` [PATCH V2 05/14] ARM: OMAP3: Correct HWMOD DMTIMER SYSC register declarations Jon Hunter
` (11 subsequent siblings)
15 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Currently the dmtimer posted mode is being enabled when the function
omap_dm_timer_enable_posted() is called. This function is only being called
for OMAP1 timers and OMAP2+ timers that are being used as system timers. Hence,
for OMAP2+ timers that are NOT being used as a system timer, posted mode is
not enabled but the "timer->posted" variable is still set (incorrectly) in
the omap_dm_timer_prepare() function.
This is a regression introduced by commit 3392cdd3 (ARM: OMAP: dmtimer:
switch-over to platform device driver) which was before the
omap_dm_timer_enable_posted() function was introduced. Although this is a
regression from the original code it only impacts performance and so is not
needed for stable.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 4abbbe5..bf484aa 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -124,21 +124,16 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
- omap_dm_timer_enable(timer);
if (timer->pdev->id != 1) {
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
omap_dm_timer_wait_for_reset(timer);
}
__omap_dm_timer_reset(timer, 0, 0);
- omap_dm_timer_enable_posted(timer);
- omap_dm_timer_disable(timer);
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
- int ret;
-
/*
* FIXME: OMAP1 devices do not use the clock framework for dmtimers so
* do not call clk_get() for these devices.
@@ -152,13 +147,15 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
}
}
+ omap_dm_timer_enable(timer);
+
if (timer->capability & OMAP_TIMER_NEEDS_RESET)
omap_dm_timer_reset(timer);
- ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+ omap_dm_timer_enable_posted(timer);
+ omap_dm_timer_disable(timer);
- timer->posted = 1;
- return ret;
+ return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
}
static inline u32 omap_dm_timer_reserved_systimer(int id)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 04/14] ARM: OMAP: Fix timer posted mode support
2012-11-07 19:01 ` [PATCH V2 04/14] ARM: OMAP: Fix timer posted mode support Jon Hunter
@ 2012-11-07 22:21 ` Santosh Shilimkar
0 siblings, 0 replies; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:21 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
> Currently the dmtimer posted mode is being enabled when the function
> omap_dm_timer_enable_posted() is called. This function is only being called
> for OMAP1 timers and OMAP2+ timers that are being used as system timers. Hence,
> for OMAP2+ timers that are NOT being used as a system timer, posted mode is
> not enabled but the "timer->posted" variable is still set (incorrectly) in
> the omap_dm_timer_prepare() function.
>
> This is a regression introduced by commit 3392cdd3 (ARM: OMAP: dmtimer:
> switch-over to platform device driver) which was before the
> omap_dm_timer_enable_posted() function was introduced. Although this is a
> regression from the original code it only impacts performance and so is not
> needed for stable.
>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH V2 05/14] ARM: OMAP3: Correct HWMOD DMTIMER SYSC register declarations
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (3 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 04/14] ARM: OMAP: Fix timer posted mode support Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 06/14] ARM: OMAP2/3: Define HWMOD software reset status for DMTIMERs Jon Hunter
` (10 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Currently, the OMAP3 HWMOD data defines two TIOCP_CFG register structures
(referred to as the SYSC register in the HWMOD data) where timers 1, 2 and 10
use one of the defintions and the other timers use the other definition. For
OMAP3 devices the structure of the DMTIMER TIOCP_CFG register is the same for
all 12 instances of the DMTIMER. Please note that this is a difference between
OMAP3 and OMAP4 and could be the source of the confusion.
For OMAP3 devices, the DMTIMER TIOCP_CFG register has the fields,
clock-activity, emufree, idlemode, enwakeup, softreset and autoidle for all
12 timers. Therefore, remove one of the SYSC register definitions for the
DMTIMERs and ensure the appropriate register fields are defined for all
DMTIMERs.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 27 ++++++---------------------
1 file changed, 6 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index f67b7ee..679c0ec 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -149,28 +149,13 @@ static struct omap_hwmod omap3xxx_debugss_hwmod = {
};
/* timer class */
-static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {
- .rev_offs = 0x0000,
- .sysc_offs = 0x0010,
- .syss_offs = 0x0014,
- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
- SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
- .sysc_fields = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {
- .name = "timer",
- .sysc = &omap3xxx_timer_1ms_sysc,
-};
-
static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
.syss_offs = 0x0014,
- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};
@@ -220,7 +205,7 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
},
},
.dev_attr = &capability_alwon_dev_attr,
- .class = &omap3xxx_timer_1ms_hwmod_class,
+ .class = &omap3xxx_timer_hwmod_class,
};
/* timer2 */
@@ -237,7 +222,7 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
},
},
- .class = &omap3xxx_timer_1ms_hwmod_class,
+ .class = &omap3xxx_timer_hwmod_class,
};
/* timer3 */
@@ -379,7 +364,7 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
},
},
.dev_attr = &capability_pwm_dev_attr,
- .class = &omap3xxx_timer_1ms_hwmod_class,
+ .class = &omap3xxx_timer_hwmod_class,
};
/* timer11 */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 06/14] ARM: OMAP2/3: Define HWMOD software reset status for DMTIMERs
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (4 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 05/14] ARM: OMAP3: Correct HWMOD DMTIMER SYSC register declarations Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 07/14] ARM: OMAP2+: Don't use __omap_dm_timer_reset() Jon Hunter
` (9 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
For OMAP2/3 devices, the HWMOD data does not define a software reset status
field for the DMTIMERs. Therefore, when HWMOD performs a soft-reset of the
DMTIMER we don't check and wait for the reset to complete. For OMAP2/3 devices,
the software reset status for a DMTIMER can be read from bit 0 of the DMTIMER
TISTAT register (referred to as the SYSS register in HWMOD). Add the
appropriate HWMOD definitions so that HWMOD will check the software reset
status when performing a software reset of the DMTIMER.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 2 +-
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index bd9220e..8c3b3f0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -58,7 +58,7 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
.syss_offs = 0x0014,
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
- SYSC_HAS_AUTOIDLE),
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 679c0ec..306c627 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -155,7 +155,8 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
.syss_offs = 0x0014,
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
- SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 07/14] ARM: OMAP2+: Don't use __omap_dm_timer_reset()
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (5 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 06/14] ARM: OMAP2/3: Define HWMOD software reset status for DMTIMERs Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 08/14] ARM: OMAP: Fix dmtimer reset for timer1 Jon Hunter
` (8 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Currently OMAP2+ devices are using the function __omap_dm_timer_reset() to
configure the clock-activity, idle, wakeup-enable and auto-idle fields in the
timer OCP_CFG register. The name of the function is mis-leading because this
function does not actually perform a reset of the timer.
For OMAP2+ devices, HWMOD is responsible for reseting and configuring the
timer OCP_CFG register. Therefore, do not use __omap_dm_timer_reset() for
OMAP2+ devices and rely on HWMOD. Furthermore, some timer instances do not
have the fields clock-activity, wakeup-enable and auto-idle and so this
function could configure the OCP_CFG register incorrectly.
Currently HWMOD is not configuring the clock-activity field in the OCP_CFG
register for timers that have this field. Commit 0f0d080 (ARM: OMAP: DMTimer:
Use posted mode) configures the clock-activity field to keep the f-clk enabled
so that the wake-up capability is enabled. Therefore, add the appropriate flags
to the timer HWMOD structures to configure this field in the same way.
For OMAP2/3 devices all dmtimers have the clock-activity field, where as for
OMAP4 devices, only dmtimer 1, 2 and 10 have the clock-activity field.
Verified on OMAP2420 H4, OMAP3430 Beagle and OMAP4430 Panda that HWMOD is
configuring the dmtimer OCP_CFG register as expected for clock-events timer.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 13 +++++++++++++
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 13 +++++++++++++
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 4 ++++
arch/arm/mach-omap2/timer.c | 1 -
4 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 8c3b3f0..043b952 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -60,6 +60,7 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .clockact = CLOCKACT_TEST_ICLK,
.sysc_fields = &omap_hwmod_sysc_type1,
};
@@ -268,6 +269,7 @@ struct omap_hwmod omap2xxx_timer1_hwmod = {
},
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer2 */
@@ -286,6 +288,7 @@ struct omap_hwmod omap2xxx_timer2_hwmod = {
},
},
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer3 */
@@ -304,6 +307,7 @@ struct omap_hwmod omap2xxx_timer3_hwmod = {
},
},
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer4 */
@@ -322,6 +326,7 @@ struct omap_hwmod omap2xxx_timer4_hwmod = {
},
},
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer5 */
@@ -341,6 +346,7 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer6 */
@@ -360,6 +366,7 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer7 */
@@ -379,6 +386,7 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer8 */
@@ -398,6 +406,7 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer9 */
@@ -417,6 +426,7 @@ struct omap_hwmod omap2xxx_timer9_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer10 */
@@ -436,6 +446,7 @@ struct omap_hwmod omap2xxx_timer10_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer11 */
@@ -455,6 +466,7 @@ struct omap_hwmod omap2xxx_timer11_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer12 */
@@ -474,6 +486,7 @@ struct omap_hwmod omap2xxx_timer12_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* wd_timer2 */
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 306c627..9cdbd3c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -158,6 +158,7 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .clockact = CLOCKACT_TEST_ICLK,
.sysc_fields = &omap_hwmod_sysc_type1,
};
@@ -207,6 +208,7 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
},
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer2 */
@@ -224,6 +226,7 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
},
},
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer3 */
@@ -241,6 +244,7 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
},
},
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer4 */
@@ -258,6 +262,7 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
},
},
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer5 */
@@ -276,6 +281,7 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer6 */
@@ -294,6 +300,7 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer7 */
@@ -312,6 +319,7 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
},
.dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer8 */
@@ -330,6 +338,7 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
},
.dev_attr = &capability_dsp_pwm_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer9 */
@@ -348,6 +357,7 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer10 */
@@ -366,6 +376,7 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer11 */
@@ -384,6 +395,7 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = {
},
.dev_attr = &capability_pwm_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/* timer12 */
@@ -407,6 +419,7 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = {
},
.dev_attr = &capability_secure_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
/*
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 652d028..e1f652f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -3066,6 +3066,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = {
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .clockact = CLOCKACT_TEST_ICLK,
.sysc_fields = &omap_hwmod_sysc_type1,
};
@@ -3119,6 +3120,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
.name = "timer1",
.class = &omap44xx_timer_1ms_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
.mpu_irqs = omap44xx_timer1_irqs,
.main_clk = "timer1_fck",
.prcm = {
@@ -3141,6 +3143,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.name = "timer2",
.class = &omap44xx_timer_1ms_hwmod_class,
.clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
.mpu_irqs = omap44xx_timer2_irqs,
.main_clk = "timer2_fck",
.prcm = {
@@ -3315,6 +3318,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
.name = "timer10",
.class = &omap44xx_timer_1ms_hwmod_class,
.clkdm_name = "l4_per_clkdm",
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
.mpu_irqs = omap44xx_timer10_irqs,
.main_clk = "timer10_fck",
.prcm = {
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 8b0068c..b9b6f21 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -327,7 +327,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
}
}
__omap_dm_timer_init_regs(timer);
- __omap_dm_timer_reset(timer, 1, 1);
if (posted)
omap_dm_timer_enable_posted(timer);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 08/14] ARM: OMAP: Fix dmtimer reset for timer1
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (6 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 07/14] ARM: OMAP2+: Don't use __omap_dm_timer_reset() Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 09/14] ARM: OMAP: Don't restore of DMTIMER TISTAT register Jon Hunter
` (7 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
In commit e32f7ec2 (ARM: OMAP: Fix 32 kHz timer and modify GP timer to use GPT1)
a fix was added to prevent timer1 being reset in the function
omap_dm_timer_reset() because timer1 was being used as the system timer for
OMAP2 devices. Although timer1 is still used by most OMAP2+ devices as a system
timer, the function omap_dm_timer_reset() is now only being called for OMAP1
devices and OMAP1 does not use timer1 as a system timer. Therefore, remove the
check in omap_dm_timer_reset() so that timer1 is reset for OMAP1 devices.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index bf484aa..5a9f29b 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -124,11 +124,8 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
- if (timer->pdev->id != 1) {
- omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
- omap_dm_timer_wait_for_reset(timer);
- }
-
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
+ omap_dm_timer_wait_for_reset(timer);
__omap_dm_timer_reset(timer, 0, 0);
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 09/14] ARM: OMAP: Don't restore of DMTIMER TISTAT register
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (7 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 08/14] ARM: OMAP: Fix dmtimer reset for timer1 Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 10/14] ARM: OMAP: Don't restore DMTIMER interrupt status register Jon Hunter
` (6 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
The timer TISTAT register is a read-only register and therefore restoring the
context is not needed. Furthermore, the context of TISTAT is never saved
anywhere in the current code. The TISTAT register is read-only for all OMAP
devices from OMAP1 to OMAP4. OMAP5 timers no longer have this register.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 3 ---
arch/arm/plat-omap/include/plat/dmtimer.h | 1 -
2 files changed, 4 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 5a9f29b..a350f12 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -86,9 +86,6 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
static void omap_timer_restore_context(struct omap_dm_timer *timer)
{
- if (timer->revision == 1)
- __raw_writel(timer->context.tistat, timer->sys_stat);
-
__raw_writel(timer->context.tisr, timer->irq_stat);
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
timer->context.twer);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index ef93017..36b71a5 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -85,7 +85,6 @@ struct omap_dm_timer;
struct timer_regs {
u32 tidr;
- u32 tistat;
u32 tisr;
u32 tier;
u32 twer;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 10/14] ARM: OMAP: Don't restore DMTIMER interrupt status register
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (8 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 09/14] ARM: OMAP: Don't restore of DMTIMER TISTAT register Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 11/14] ARM: OMAP: Fix spurious interrupts when using timer match feature Jon Hunter
` (5 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Restoring the timer interrupt status is not possible because writing a 1 to any
bit in the register clears that bit if set and writing a 0 has no affect.
Furthermore, if an interrupt is pending when someone attempts to disable a
timer, the timer will fail to transition to the idle state and hence it's
context will not be lost. Users should take care to service all interrupts
before disabling the timer.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 5 +----
arch/arm/plat-omap/include/plat/dmtimer.h | 1 -
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index a350f12..76553fd5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -86,7 +86,6 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
static void omap_timer_restore_context(struct omap_dm_timer *timer)
{
- __raw_writel(timer->context.tisr, timer->irq_stat);
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
timer->context.twer);
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
@@ -495,7 +494,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
*/
timer->context.tclr =
omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
- timer->context.tisr = __raw_readl(timer->irq_stat);
omap_dm_timer_disable(timer);
return 0;
}
@@ -738,8 +736,7 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
return -EINVAL;
__omap_dm_timer_write_status(timer, value);
- /* Save the context */
- timer->context.tisr = value;
+
return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 36b71a5..af145a9 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -85,7 +85,6 @@ struct omap_dm_timer;
struct timer_regs {
u32 tidr;
- u32 tisr;
u32 tier;
u32 twer;
u32 tclr;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 11/14] ARM: OMAP: Fix spurious interrupts when using timer match feature
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (9 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 10/14] ARM: OMAP: Don't restore DMTIMER interrupt status register Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 12/14] ARM: OMAP: Add dmtimer interrupt disable function Jon Hunter
` (4 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
The OMAP DMTIMERs can generate an interrupt when the timer counter value
matches the value stored in the timer's match register. When using this
feature spurious interrupts were seen, because the compare logic is being
enabled before the match value is loaded and according to the documentation
the match value must be loaded before the compare logic is enable.
The reset value for the timer counter and match registers is 0 and hence,
by enabling the compare logic before the actual match value is loaded a
spurious interrupt can be generated as the reset values match.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 76553fd5..e7bf0d1 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -638,8 +638,8 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
l |= OMAP_TIMER_CTRL_CE;
else
l &= ~OMAP_TIMER_CTRL_CE;
- omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
/* Save the context */
timer->context.tclr = l;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 12/14] ARM: OMAP: Add dmtimer interrupt disable function
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (10 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 11/14] ARM: OMAP: Fix spurious interrupts when using timer match feature Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 13/14] ARM: OMAP: Remove unnecessary call to clk_get() Jon Hunter
` (3 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
The OMAP dmtimer driver does not currently have a function to disable the
timer interrupts. For some timer instances the timer interrupt enable
function can be used to disable the interrupts because the same interrupt
enable register is used to disable interrupts. However, some timer instances
have separate interrupt enable/disable registers and so this will not work.
Therefore, add a dedicated function to disable interrupts.
This change is required for OMAP4+ devices. For OMAP4, all timers apart from 1,
2 and 10 need this function and for OMAP5 all timers need this function.
Please note that the interrupt disable function has been written so that it
can be used by all OMAP devices.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 31 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/dmtimer.h | 3 ++-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index e7bf0d1..508a38e 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -715,6 +715,37 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
+/**
+ * omap_dm_timer_set_int_disable - disable timer interrupts
+ * @timer: pointer to timer handle
+ * @mask: bit mask of interrupts to be disabled
+ *
+ * Disables the specified timer interrupts for a timer.
+ */
+int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+{
+ u32 l = mask;
+
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ if (timer->revision == 1)
+ l = __raw_readl(timer->irq_ena) & ~mask;
+
+ __raw_writel(l, timer->irq_dis);
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
+
+ /* Save the context */
+ timer->context.tier &= ~mask;
+ timer->context.twer &= ~mask;
+ omap_dm_timer_disable(timer);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
+
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
unsigned int l;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index af145a9..14190e8 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -137,6 +137,7 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, i
int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
@@ -322,7 +323,7 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
OMAP_TIMER_V1_SYS_STAT_OFFSET;
timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
- timer->irq_dis = NULL;
+ timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
timer->func_base = timer->io_base;
} else {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 13/14] ARM: OMAP: Remove unnecessary call to clk_get()
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (11 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 12/14] ARM: OMAP: Add dmtimer interrupt disable function Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 19:01 ` [PATCH V2 14/14] ARM: OMAP: Remove __omap_dm_timer_set_source function Jon Hunter
` (2 subsequent siblings)
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
Whenever we call the function omap_dm_timer_set_source() to set the clock
source of a dmtimer we look-up the dmtimer functional clock source by
calling clk_get(). This is not necessary because on requesting a dmtimer
we look-up the functional clock source and store it in the omap_dm_timer
structure. So instead of looking up the clock again used the clock handle
that stored in the omap_dm_timer structure.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/plat-omap/dmtimer.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 508a38e..191d5e5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -503,7 +503,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{
int ret;
char *parent_name = NULL;
- struct clk *fclk, *parent;
+ struct clk *parent;
struct dmtimer_platform_data *pdata;
if (unlikely(!timer))
@@ -522,11 +522,8 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
if (pdata && pdata->set_timer_src)
return pdata->set_timer_src(timer->pdev, source);
- fclk = clk_get(&timer->pdev->dev, "fck");
- if (IS_ERR_OR_NULL(fclk)) {
- pr_err("%s: fck not found\n", __func__);
+ if (!timer->fclk)
return -EINVAL;
- }
switch (source) {
case OMAP_TIMER_SRC_SYS_CLK:
@@ -545,18 +542,15 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
parent = clk_get(&timer->pdev->dev, parent_name);
if (IS_ERR_OR_NULL(parent)) {
pr_err("%s: %s not found\n", __func__, parent_name);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
- ret = clk_set_parent(fclk, parent);
+ ret = clk_set_parent(timer->fclk, parent);
if (IS_ERR_VALUE(ret))
pr_err("%s: failed to set %s as parent\n", __func__,
parent_name);
clk_put(parent);
-out:
- clk_put(fclk);
return ret;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH V2 14/14] ARM: OMAP: Remove __omap_dm_timer_set_source function
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (12 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 13/14] ARM: OMAP: Remove unnecessary call to clk_get() Jon Hunter
@ 2012-11-07 19:01 ` Jon Hunter
2012-11-07 21:22 ` [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Tony Lindgren
2012-11-07 22:27 ` Santosh Shilimkar
15 siblings, 0 replies; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 19:01 UTC (permalink / raw)
To: Tony Lindgren, Kevin Hilman, Paul Walmsley
Cc: linux-omap, linux-arm, Jon Hunter
The __omap_dm_timer_set_source() function is only used by the system timer
(clock-events and clock-source) code for OMAP2+ devices. Therefore, we can
remove this code from the dmtimer driver and move it to the system timer
code for OMAP2+ devices.
The current __omap_dm_timer_set_source() function calls clk_disable() before
calling clk_set_parent() and clk_enable() afterwards. We can avoid these calls
to clk_disable/enable by moving the calls to omap_hwmod_setup_one() and
omap_hwmod_enable() to after the call to clk_set_parent() in
omap_dm_timer_init_one().
The function omap_hwmod_setup_one() will enable the timers functional clock
and therefore increment the use-count of the functional clock to 1.
clk_set_parent() will fail if the use-count is not 0 when called. Hence, if
omap_hwmod_setup_one() is called before clk_set_parent(), we will need to call
clk_disable() before calling clk_set_parent() to decrement the use-count.
Hence, avoid these extra calls to disable and enable the functional clock by
moving the calls to omap_hwmod_setup_one() and omap_hwmod_enable() to after
clk_set_parent().
We can also remove the delay from the __omap_dm_timer_set_source() function
because enabling the clock will now be handled via the HWMOD framework by
calling omap_hwmod_setup_one(). Therefore, by moving the calls to
omap_hwmod_setup_one() and omap_hwmod_enable() to after the call to
clk_set_parent(), we can simply replace __omap_dm_timer_set_source() with
clk_set_parent().
It should be safe to move these hwmod calls to later in the
omap_dm_timer_init_one() because other calls to the hwmod layer that occur
before are just requesting resource information.
Testing includes boot testing on OMAP2420 H4, OMAP3430 SDP and OMAP4430 Blaze
with the following configurations:
1. CONFIG_OMAP_32K_TIMER=y
2. CONFIG_OMAP_32K_TIMER=y and boot parameter "clocksource=gp_timer"
3. CONFIG_OMAP_32K_TIMER not set
4. CONFIG_OMAP_32K_TIMER not set and boot parameter "clocksource=gp_timer"
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/mach-omap2/timer.c | 9 ++++-----
arch/arm/plat-omap/include/plat/dmtimer.h | 19 -------------------
2 files changed, 4 insertions(+), 24 deletions(-)
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index b9b6f21..066a48d 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -277,9 +277,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
oh_name = name;
}
- omap_hwmod_setup_one(oh_name);
oh = omap_hwmod_lookup(oh_name);
-
if (!oh)
return -ENODEV;
@@ -309,8 +307,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
if (IS_ERR(timer->fclk))
return -ENODEV;
- omap_hwmod_enable(oh);
-
/* FIXME: Need to remove hard-coded test on timer ID */
if (gptimer_id != 12) {
struct clk *src;
@@ -319,13 +315,16 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
if (IS_ERR(src)) {
res = -EINVAL;
} else {
- res = __omap_dm_timer_set_source(timer->fclk, src);
+ res = clk_set_parent(timer->fclk, src);
if (IS_ERR_VALUE(res))
pr_warn("%s: %s cannot set source\n",
__func__, oh->name);
clk_put(src);
}
}
+
+ omap_hwmod_setup_one(oh_name);
+ omap_hwmod_enable(oh);
__omap_dm_timer_init_regs(timer);
if (posted)
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 14190e8..24a1c74 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -32,7 +32,6 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
@@ -358,24 +357,6 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
__raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
}
-static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
- struct clk *parent)
-{
- int ret;
-
- clk_disable(timer_fck);
- ret = clk_set_parent(timer_fck, parent);
- clk_enable(timer_fck);
-
- /*
- * When the functional clock disappears, too quick writes seem
- * to cause an abort. XXX Is this still necessary?
- */
- __delay(300000);
-
- return ret;
-}
-
static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,
int posted, unsigned long rate)
{
--
1.7.9.5
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (13 preceding siblings ...)
2012-11-07 19:01 ` [PATCH V2 14/14] ARM: OMAP: Remove __omap_dm_timer_set_source function Jon Hunter
@ 2012-11-07 21:22 ` Tony Lindgren
2012-11-07 21:44 ` Jon Hunter
2012-11-07 22:27 ` Santosh Shilimkar
15 siblings, 1 reply; 32+ messages in thread
From: Tony Lindgren @ 2012-11-07 21:22 UTC (permalink / raw)
To: Jon Hunter; +Cc: Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
* Jon Hunter <jon-hunter@ti.com> [121107 11:03]:
> This series includes several fixes for the OMAP DMTIMER driver. This is
> based upon 3.7-rc4 with the two series adding device-tree support for
> DMTIMERs [1] and the 32kHz Counter [2]
These look OK to me, I'm assuming you'll do a pull request eventually
for these. Might be worth checking if these merge fine also on
omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3, rename detection
might be able to deal with that for the header.
Regards,
Tony
> [1] http://marc.info/?l=linux-omap&m=135065875808614&w=2
> [2] http://marc.info/?l=linux-omap&m=135119308123513&w=2
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes
2012-11-07 21:22 ` [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Tony Lindgren
@ 2012-11-07 21:44 ` Jon Hunter
2012-11-07 21:52 ` Tony Lindgren
0 siblings, 1 reply; 32+ messages in thread
From: Jon Hunter @ 2012-11-07 21:44 UTC (permalink / raw)
To: Tony Lindgren; +Cc: Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
On 11/07/2012 03:22 PM, Tony Lindgren wrote:
> * Jon Hunter <jon-hunter@ti.com> [121107 11:03]:
>> This series includes several fixes for the OMAP DMTIMER driver. This is
>> based upon 3.7-rc4 with the two series adding device-tree support for
>> DMTIMERs [1] and the 32kHz Counter [2]
>
> These look OK to me, I'm assuming you'll do a pull request eventually
> for these. Might be worth checking if these merge fine also on
> omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3, rename detection
> might be able to deal with that for the header.
Yes I was going to wait a few days for people to review before sending a
pull request. I will make sure it merges on your master. Is Monday too
late for v3.8?
Cheers
Jon
>> [1] http://marc.info/?l=linux-omap&m=135065875808614&w=2
>> [2] http://marc.info/?l=linux-omap&m=135119308123513&w=2
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes
2012-11-07 21:44 ` Jon Hunter
@ 2012-11-07 21:52 ` Tony Lindgren
0 siblings, 0 replies; 32+ messages in thread
From: Tony Lindgren @ 2012-11-07 21:52 UTC (permalink / raw)
To: Jon Hunter; +Cc: Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
* Jon Hunter <jon-hunter@ti.com> [121107 13:45]:
>
> On 11/07/2012 03:22 PM, Tony Lindgren wrote:
> > * Jon Hunter <jon-hunter@ti.com> [121107 11:03]:
> >> This series includes several fixes for the OMAP DMTIMER driver. This is
> >> based upon 3.7-rc4 with the two series adding device-tree support for
> >> DMTIMERs [1] and the 32kHz Counter [2]
> >
> > These look OK to me, I'm assuming you'll do a pull request eventually
> > for these. Might be worth checking if these merge fine also on
> > omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3, rename detection
> > might be able to deal with that for the header.
>
> Yes I was going to wait a few days for people to review before sending a
> pull request. I will make sure it merges on your master. Is Monday too
> late for v3.8?
Probably not for this series as it fixes some issues, but in general
we should have most of the patches queued by -rc4 time.
Regards,
Tony
> >> [1] http://marc.info/?l=linux-omap&m=135065875808614&w=2
> >> [2] http://marc.info/?l=linux-omap&m=135119308123513&w=2
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes
2012-11-07 19:01 [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Jon Hunter
` (14 preceding siblings ...)
2012-11-07 21:22 ` [PATCH V2 00/14] ARM: OMAP: DMTIMER fixes Tony Lindgren
@ 2012-11-07 22:27 ` Santosh Shilimkar
15 siblings, 0 replies; 32+ messages in thread
From: Santosh Shilimkar @ 2012-11-07 22:27 UTC (permalink / raw)
To: Jon Hunter
Cc: Tony Lindgren, Kevin Hilman, Paul Walmsley, linux-omap, linux-arm
Jon,
On Wednesday 07 November 2012 01:01 PM, Jon Hunter wrote:
> This series includes several fixes for the OMAP DMTIMER driver. This is
> based upon 3.7-rc4 with the two series adding device-tree support for
> DMTIMERs [1] and the 32kHz Counter [2]
>
> Tested on OMAP5912 OSK, OMAP2420 H4, OMAP3430 Beagle and OMAP4430 Panda.
> Testing includes ...
> 1. Booting kernel on above boards
> 2. Set date and ensuring time of day is correct after 24 hours
> 3. Checking the timer counter is incrementing when configuring and starting
> a timer
> 4. Checking the timer overflow interrupt when timer expires.
> 5. Using different clock sources to operate the timer with.
> 6. Running a loop test overnight that continually runs test #3 and #4 for
> each available timer
>
> This has also been boot tested on the AM335x Beagle Bone.
>
> [1] http://marc.info/?l=linux-omap&m=135065875808614&w=2
> [2] http://marc.info/?l=linux-omap&m=135119308123513&w=2
>
> Jon Hunter (14):
> ARM: OMAP: Add DMTIMER definitions for posted mode
> ARM: OMAP2+: Disable posted mode for the clocksource timer
> ARM: OMAP3+: Implement timer workaround for errata i103 and i767
> ARM: OMAP: Fix timer posted mode support
> ARM: OMAP3: Correct HWMOD DMTIMER SYSC register declarations
> ARM: OMAP2/3: Define HWMOD software reset status for DMTIMERs
> ARM: OMAP2+: Don't use __omap_dm_timer_reset()
> ARM: OMAP: Fix dmtimer reset for timer1
> ARM: OMAP: Don't restore of DMTIMER TISTAT register
> ARM: OMAP: Don't restore DMTIMER interrupt status register
> ARM: OMAP: Fix spurious interrupts when using timer match feature
> ARM: OMAP: Add dmtimer interrupt disable function
> ARM: OMAP: Remove unnecessary call to clk_get()
> ARM: OMAP: Remove __omap_dm_timer_set_source function
>
> arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 15 ++-
> arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 41 +++---
> arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 4 +
> arch/arm/mach-omap2/timer.c | 73 ++++++++---
> arch/arm/plat-omap/dmtimer.c | 132 +++++++++++++++-----
> arch/arm/plat-omap/include/plat/dmtimer.h | 47 ++++---
> 6 files changed, 215 insertions(+), 97 deletions(-)
>
Nice work. Apart from some minor comments, this series looks pretty
good to me.
Feel free to add my ack for entire series.
Regards
Santosh
^ permalink raw reply [flat|nested] 32+ messages in thread