Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
9dc57643
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
9dc57643
编写于
11月 13, 2012
作者:
T
Tony Lindgren
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'fixes-timer' of github.com:jonhunter/linux into omap-for-v3.8/timer
上级
d308ba50
b1538832
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
188 addition
and
91 deletion
+188
-91
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+14
-1
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+20
-21
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+4
-0
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/timer.c
+52
-18
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/dmtimer.c
+46
-31
arch/arm/plat-omap/include/plat/dmtimer.h
arch/arm/plat-omap/include/plat/dmtimer.h
+52
-20
未找到文件。
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
浏览文件 @
9dc57643
...
...
@@ -58,8 +58,9 @@ 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
),
.
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 */
...
...
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
浏览文件 @
9dc57643
...
...
@@ -153,29 +153,16 @@ 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
|
SYSS_HAS_RESET_STATUS
),
.
idlemodes
=
(
SIDLE_FORCE
|
SIDLE_NO
|
SIDLE_SMART
),
.
clockact
=
CLOCKACT_TEST_ICLK
,
.
sysc_fields
=
&
omap_hwmod_sysc_type1
,
};
...
...
@@ -224,7 +211,8 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
},
},
.
dev_attr
=
&
capability_alwon_dev_attr
,
.
class
=
&
omap3xxx_timer_1ms_hwmod_class
,
.
class
=
&
omap3xxx_timer_hwmod_class
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/* timer2 */
...
...
@@ -241,7 +229,8 @@ 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
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/* timer3 */
...
...
@@ -259,6 +248,7 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
},
},
.
class
=
&
omap3xxx_timer_hwmod_class
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/* timer4 */
...
...
@@ -276,6 +266,7 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
},
},
.
class
=
&
omap3xxx_timer_hwmod_class
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/* timer5 */
...
...
@@ -294,6 +285,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 */
...
...
@@ -312,6 +304,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 */
...
...
@@ -330,6 +323,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 */
...
...
@@ -348,6 +342,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 */
...
...
@@ -366,6 +361,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 */
...
...
@@ -383,7 +379,8 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
},
},
.
dev_attr
=
&
capability_pwm_dev_attr
,
.
class
=
&
omap3xxx_timer_1ms_hwmod_class
,
.
class
=
&
omap3xxx_timer_hwmod_class
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/* timer11 */
...
...
@@ -402,6 +399,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 */
...
...
@@ -425,6 +423,7 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = {
},
.
dev_attr
=
&
capability_secure_dev_attr
,
.
class
=
&
omap3xxx_timer_hwmod_class
,
.
flags
=
HWMOD_SET_DEFAULT_CLOCKACT
,
};
/*
...
...
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
浏览文件 @
9dc57643
...
...
@@ -3067,6 +3067,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
,
};
...
...
@@ -3120,6 +3121,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
=
{
...
...
@@ -3142,6 +3144,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
=
{
...
...
@@ -3316,6 +3319,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
=
{
...
...
arch/arm/mach-omap2/timer.c
浏览文件 @
9dc57643
...
...
@@ -108,7 +108,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
;
}
...
...
@@ -118,7 +118,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
:
...
...
@@ -126,10 +126,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
;
...
...
@@ -222,10 +222,24 @@ void __init omap_dmtimer_init(void)
}
}
/**
* omap_dm_timer_get_errata - get errata flags for a timer
*
* Get the timer errata flags that are specific to the OMAP device being used.
*/
u32
__init
omap_dm_timer_get_errata
(
void
)
{
if
(
cpu_is_omap24xx
())
return
0
;
return
OMAP_TIMER_ERRATA_I103_I767
;
}
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
;
...
...
@@ -260,9 +274,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
;
...
...
@@ -292,8 +304,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
;
...
...
@@ -302,19 +312,26 @@ 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
);
__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 +343,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
);
clkev
.
errata
=
omap_dm_timer_get_errata
();
/*
* 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 +386,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_NONPOSTED
);
}
static
struct
clocksource
clocksource_gpt
=
{
...
...
@@ -373,7 +401,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_NONPOSTED
);
return
0
;
}
...
...
@@ -451,11 +480,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
);
clksrc
.
errata
=
omap_dm_timer_get_errata
();
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
,
1
);
OMAP_TIMER_CTRL_ST
|
OMAP_TIMER_CTRL_AR
,
0
,
OMAP_TIMER_NONPOSTED
);
setup_sched_clock
(
dmtimer_read_sched_clock
,
32
,
clksrc
.
rate
);
if
(
clocksource_register_hz
(
&
clocksource_gpt
,
clksrc
.
rate
))
...
...
@@ -693,6 +726,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
if
(
timer_dev_attr
)
pdata
->
timer_capability
=
timer_dev_attr
->
timer_capability
;
pdata
->
timer_errata
=
omap_dm_timer_get_errata
();
pdata
->
get_context_loss_count
=
omap_pm_get_dev_context_loss_count
;
pdev
=
omap_device_build
(
name
,
id
,
oh
,
pdata
,
sizeof
(
*
pdata
),
...
...
arch/arm/plat-omap/dmtimer.c
浏览文件 @
9dc57643
...
...
@@ -35,6 +35,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/device.h>
...
...
@@ -83,10 +84,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
);
omap_dm_timer_write_reg
(
timer
,
OMAP_TIMER_COUNTER_REG
,
...
...
@@ -121,21 +118,13 @@ 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_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_disable
(
timer
);
timer
->
posted
=
1
;
}
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.
...
...
@@ -149,13 +138,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
)
...
...
@@ -449,7 +440,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
;
}
...
...
@@ -459,7 +449,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
))
...
...
@@ -478,11 +468,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
:
...
...
@@ -501,18 +488,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
;
}
...
...
@@ -595,8 +579,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
;
...
...
@@ -672,6 +656,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
;
...
...
@@ -693,8 +708,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
);
...
...
@@ -797,6 +811,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer
->
capability
|=
OMAP_TIMER_SECURE
;
}
else
{
timer
->
id
=
pdev
->
id
;
timer
->
errata
=
pdata
->
timer_errata
;
timer
->
capability
=
pdata
->
timer_capability
;
timer
->
reserved
=
omap_dm_timer_reserved_systimer
(
timer
->
id
);
timer
->
get_context_loss_count
=
pdata
->
get_context_loss_count
;
...
...
arch/arm/plat-omap/include/plat/dmtimer.h
浏览文件 @
9dc57643
...
...
@@ -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>
...
...
@@ -55,6 +54,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
...
...
@@ -62,6 +65,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
;
};
...
...
@@ -70,8 +83,6 @@ struct omap_dm_timer;
struct
timer_regs
{
u32
tidr
;
u32
tistat
;
u32
tisr
;
u32
tier
;
u32
twer
;
u32
tclr
;
...
...
@@ -93,6 +104,7 @@ struct timer_regs {
struct
dmtimer_platform_data
{
/* set_timer_src - Only used for OMAP1 devices */
int
(
*
set_timer_src
)(
struct
platform_device
*
pdev
,
int
source
);
u32
timer_errata
;
u32
timer_capability
;
int
(
*
get_context_loss_count
)(
struct
device
*
);
};
...
...
@@ -122,6 +134,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
);
...
...
@@ -269,6 +282,7 @@ struct omap_dm_timer {
int
ctx_loss_count
;
int
revision
;
u32
capability
;
u32
errata
;
struct
platform_device
*
pdev
;
struct
list_head
node
;
};
...
...
@@ -307,7 +321,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
{
...
...
@@ -340,28 +354,46 @@ 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
,
struct
clk
*
parent
)
/*
* __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.
*/
static
inline
void
__omap_dm_timer_enable_posted
(
struct
omap_dm_timer
*
timer
)
{
int
ret
;
if
(
timer
->
posted
)
return
;
clk_disable
(
timer_fck
);
ret
=
clk_set_parent
(
timer_fck
,
parent
);
clk_enable
(
timer_fck
);
if
(
timer
->
errata
&
OMAP_TIMER_ERRATA_I103_I767
)
return
;
/*
* When the functional clock disappears, too quick writes seem
* to cause an abort. XXX Is this still necessary?
*/
__delay
(
300000
);
__omap_dm_timer_write
(
timer
,
OMAP_TIMER_IF_CTRL_REG
,
OMAP_TIMER_CTRL_POSTED
,
0
);
timer
->
context
.
tsicr
=
OMAP_TIMER_CTRL_POSTED
;
timer
->
posted
=
OMAP_TIMER_POSTED
;
}
return
ret
;
/**
* __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.
*/
static
inline
void
__omap_dm_timer_override_errata
(
struct
omap_dm_timer
*
timer
,
u32
errata
)
{
timer
->
errata
&=
~
errata
;
}
static
inline
void
__omap_dm_timer_stop
(
struct
omap_dm_timer
*
timer
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录