Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
4d01cdaf
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4d01cdaf
编写于
9月 29, 2008
作者:
P
Paul Mundt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sh: SH-5 clk fwk support.
Signed-off-by:
N
Paul Mundt
<
lethal@linux-sh.org
>
上级
50b72e60
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
91 addition
and
161 deletion
+91
-161
arch/sh/kernel/cpu/sh5/Makefile
arch/sh/kernel/cpu/sh5/Makefile
+5
-0
arch/sh/kernel/cpu/sh5/clock-sh5.c
arch/sh/kernel/cpu/sh5/clock-sh5.c
+79
-0
arch/sh/kernel/time_64.c
arch/sh/kernel/time_64.c
+7
-161
未找到文件。
arch/sh/kernel/cpu/sh5/Makefile
浏览文件 @
4d01cdaf
...
...
@@ -5,3 +5,8 @@ obj-y := entry.o probe.o switchto.o
obj-$(CONFIG_SH_FPU)
+=
fpu.o
obj-$(CONFIG_KALLSYMS)
+=
unwind.o
# Primary on-chip clocks (common)
clock-$(CONFIG_CPU_SH5)
:=
clock-sh5.o
obj-y
+=
$
(
clock-y
)
arch/sh/kernel/cpu/sh5/clock-sh5.c
0 → 100644
浏览文件 @
4d01cdaf
/*
* arch/sh/kernel/cpu/sh5/clock-sh5.c
*
* SH-5 support for the clock framework
*
* Copyright (C) 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/clock.h>
#include <asm/io.h>
static
int
ifc_table
[]
=
{
2
,
4
,
6
,
8
,
10
,
12
,
16
,
24
};
/* Clock, Power and Reset Controller */
#define CPRC_BLOCK_OFF 0x01010000
#define CPRC_BASE (PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF)
static
unsigned
long
cprc_base
;
static
void
master_clk_init
(
struct
clk
*
clk
)
{
int
idx
=
(
ctrl_inl
(
cprc_base
+
0x00
)
>>
6
)
&
0x0007
;
clk
->
rate
*=
ifc_table
[
idx
];
}
static
struct
clk_ops
sh5_master_clk_ops
=
{
.
init
=
master_clk_init
,
};
static
void
module_clk_recalc
(
struct
clk
*
clk
)
{
int
idx
=
(
ctrl_inw
(
cprc_base
)
>>
12
)
&
0x0007
;
clk
->
rate
=
clk
->
parent
->
rate
/
ifc_table
[
idx
];
}
static
struct
clk_ops
sh5_module_clk_ops
=
{
.
recalc
=
module_clk_recalc
,
};
static
void
bus_clk_recalc
(
struct
clk
*
clk
)
{
int
idx
=
(
ctrl_inw
(
cprc_base
)
>>
3
)
&
0x0007
;
clk
->
rate
=
clk
->
parent
->
rate
/
ifc_table
[
idx
];
}
static
struct
clk_ops
sh5_bus_clk_ops
=
{
.
recalc
=
bus_clk_recalc
,
};
static
void
cpu_clk_recalc
(
struct
clk
*
clk
)
{
int
idx
=
(
ctrl_inw
(
cprc_base
)
&
0x0007
);
clk
->
rate
=
clk
->
parent
->
rate
/
ifc_table
[
idx
];
}
static
struct
clk_ops
sh5_cpu_clk_ops
=
{
.
recalc
=
cpu_clk_recalc
,
};
static
struct
clk_ops
*
sh5_clk_ops
[]
=
{
&
sh5_master_clk_ops
,
&
sh5_module_clk_ops
,
&
sh5_bus_clk_ops
,
&
sh5_cpu_clk_ops
,
};
void
__init
arch_init_clk_ops
(
struct
clk_ops
**
ops
,
int
idx
)
{
cprc_base
=
onchip_remap
(
CPRC_BASE
,
1024
,
"CPRC"
);
BUG_ON
(
!
cprc_base
);
if
(
idx
<
ARRAY_SIZE
(
sh5_clk_ops
))
*
ops
=
sh5_clk_ops
[
idx
];
}
arch/sh/kernel/time_64.c
浏览文件 @
4d01cdaf
...
...
@@ -39,6 +39,7 @@
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/clock.h>
#define TMU_TOCR_INIT 0x00
#define TMU0_TCR_INIT 0x0020
...
...
@@ -51,14 +52,6 @@
#define RTC_RCR1_CIE 0x10
/* Carry Interrupt Enable */
#define RTC_RCR1 (rtc_base + 0x38)
/* Clock, Power and Reset Controller */
#define CPRC_BLOCK_OFF 0x01010000
#define CPRC_BASE PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF
#define FRQCR (cprc_base+0x0)
#define WTCSR (cprc_base+0x0018)
#define STBCR (cprc_base+0x0030)
/* Time Management Unit */
#define TMU_BLOCK_OFF 0x01020000
#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
...
...
@@ -293,103 +286,17 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
return
IRQ_HANDLED
;
}
static
__init
unsigned
int
get_cpu_hz
(
void
)
{
unsigned
int
count
;
unsigned
long
__dummy
;
unsigned
long
ctc_val_init
,
ctc_val
;
/*
** Regardless the toolchain, force the compiler to use the
** arbitrary register r3 as a clock tick counter.
** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
*/
register
unsigned
long
long
__rtc_irq_flag
__asm__
(
"r3"
);
local_irq_enable
();
do
{}
while
(
ctrl_inb
(
rtc_base
)
!=
0
);
ctrl_outb
(
RTC_RCR1_CIE
,
RTC_RCR1
);
/* Enable carry interrupt */
/*
* r3 is arbitrary. CDC does not support "=z".
*/
ctc_val_init
=
0xffffffff
;
ctc_val
=
ctc_val_init
;
asm
volatile
(
"gettr tr0, %1
\n\t
"
"putcon %0, "
__CTC
"
\n\t
"
"and %2, r63, %2
\n\t
"
"pta $+4, tr0
\n\t
"
"beq/l %2, r63, tr0
\n\t
"
"ptabs %1, tr0
\n\t
"
"getcon "
__CTC
", %0
\n\t
"
:
"=r"
(
ctc_val
),
"=r"
(
__dummy
),
"=r"
(
__rtc_irq_flag
)
:
"0"
(
0
));
local_irq_disable
();
/*
* SH-3:
* CPU clock = 4 stages * loop
* tst rm,rm if id ex
* bt/s 1b if id ex
* add #1,rd if id ex
* (if) pipe line stole
* tst rm,rm if id ex
* ....
*
*
* SH-4:
* CPU clock = 6 stages * loop
* I don't know why.
* ....
*
* SH-5:
* Use CTC register to count. This approach returns the right value
* even if the I-cache is disabled (e.g. whilst debugging.)
*
*/
count
=
ctc_val_init
-
ctc_val
;
/* CTC counts down */
/*
* This really is count by the number of clock cycles
* by the ratio between a complete R64CNT
* wrap-around (128) and CUI interrupt being raised (64).
*/
return
count
*
2
;
}
static
irqreturn_t
sh64_rtc_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
pt_regs
*
regs
=
get_irq_regs
();
ctrl_outb
(
0
,
RTC_RCR1
);
/* Disable Carry Interrupts */
regs
->
regs
[
3
]
=
1
;
/* Using r3 */
return
IRQ_HANDLED
;
}
static
struct
irqaction
irq0
=
{
.
handler
=
timer_interrupt
,
.
flags
=
IRQF_DISABLED
,
.
mask
=
CPU_MASK_NONE
,
.
name
=
"timer"
,
};
static
struct
irqaction
irq1
=
{
.
handler
=
sh64_rtc_interrupt
,
.
flags
=
IRQF_DISABLED
,
.
mask
=
CPU_MASK_NONE
,
.
name
=
"rtc"
,
};
void
__init
time_init
(
void
)
{
unsigned
int
cpu_clock
,
master_clock
,
bus_clock
,
module_clock
;
unsigned
long
interval
;
unsigned
long
frqcr
,
ifc
,
pfc
;
static
int
ifc_table
[]
=
{
2
,
4
,
6
,
8
,
10
,
12
,
16
,
24
};
#define bfc_table ifc_table
/* Same */
#define pfc_table ifc_table
/* Same */
struct
clk
*
clk
;
tmu_base
=
onchip_remap
(
TMU_BASE
,
1024
,
"TMU"
);
if
(
!
tmu_base
)
{
...
...
@@ -401,50 +308,19 @@ void __init time_init(void)
panic
(
"Unable to remap RTC
\n
"
);
}
cprc_base
=
onchip_remap
(
CPRC_BASE
,
1024
,
"CPRC"
);
if
(
!
cprc_base
)
{
panic
(
"Unable to remap CPRC
\n
"
);
}
clk
=
clk_get
(
NULL
,
"cpu_clk"
);
scaled_recip_ctc_ticks_per_jiffy
=
((
1ULL
<<
CTC_JIFFY_SCALE_SHIFT
)
/
(
unsigned
long
long
)(
clk_get_rate
(
clk
)
/
HZ
));
rtc_sh_get_time
(
&
xtime
);
setup_irq
(
TIMER_IRQ
,
&
irq0
);
setup_irq
(
RTC_IRQ
,
&
irq1
);
/* Check how fast it is.. */
cpu_clock
=
get_cpu_hz
();
/* Note careful order of operations to maintain reasonable precision and avoid overflow. */
scaled_recip_ctc_ticks_per_jiffy
=
((
1ULL
<<
CTC_JIFFY_SCALE_SHIFT
)
/
(
unsigned
long
long
)(
cpu_clock
/
HZ
));
free_irq
(
RTC_IRQ
,
NULL
);
printk
(
"CPU clock: %d.%02dMHz
\n
"
,
(
cpu_clock
/
1000000
),
(
cpu_clock
%
1000000
)
/
10000
);
{
unsigned
short
bfc
;
frqcr
=
ctrl_inl
(
FRQCR
);
ifc
=
ifc_table
[(
frqcr
>>
6
)
&
0x0007
];
bfc
=
bfc_table
[(
frqcr
>>
3
)
&
0x0007
];
pfc
=
pfc_table
[(
frqcr
>>
12
)
&
0x0007
];
master_clock
=
cpu_clock
*
ifc
;
bus_clock
=
master_clock
/
bfc
;
}
printk
(
"Bus clock: %d.%02dMHz
\n
"
,
(
bus_clock
/
1000000
),
(
bus_clock
%
1000000
)
/
10000
);
module_clock
=
master_clock
/
pfc
;
printk
(
"Module clock: %d.%02dMHz
\n
"
,
(
module_clock
/
1000000
),
(
module_clock
%
1000000
)
/
10000
);
interval
=
(
module_clock
/
(
HZ
*
4
));
clk
=
clk_get
(
NULL
,
"module_clk"
);
interval
=
(
clk_get_rate
(
clk
)
/
(
HZ
*
4
));
printk
(
"Interval = %ld
\n
"
,
interval
);
current_cpu_data
.
cpu_clock
=
cpu_clock
;
current_cpu_data
.
master_clock
=
master_clock
;
current_cpu_data
.
bus_clock
=
bus_clock
;
current_cpu_data
.
module_clock
=
module_clock
;
/* Start TMU0 */
ctrl_outb
(
TMU_TSTR_OFF
,
TMU_TSTR
);
ctrl_outb
(
TMU_TOCR_INIT
,
TMU_TOCR
);
...
...
@@ -454,36 +330,6 @@ void __init time_init(void)
ctrl_outb
(
TMU_TSTR_INIT
,
TMU_TSTR
);
}
void
enter_deep_standby
(
void
)
{
/* Disable watchdog timer */
ctrl_outl
(
0xa5000000
,
WTCSR
);
/* Configure deep standby on sleep */
ctrl_outl
(
0x03
,
STBCR
);
#ifdef CONFIG_SH_ALPHANUMERIC
{
extern
void
mach_alphanum
(
int
position
,
unsigned
char
value
);
extern
void
mach_alphanum_brightness
(
int
setting
);
char
halted
[]
=
"Halted. "
;
int
i
;
mach_alphanum_brightness
(
6
);
/* dimmest setting above off */
for
(
i
=
0
;
i
<
8
;
i
++
)
{
mach_alphanum
(
i
,
halted
[
i
]);
}
asm
__volatile__
(
"synco"
);
}
#endif
asm
__volatile__
(
"sleep"
);
asm
__volatile__
(
"synci"
);
asm
__volatile__
(
"nop"
);
asm
__volatile__
(
"nop"
);
asm
__volatile__
(
"nop"
);
asm
__volatile__
(
"nop"
);
panic
(
"Unexpected wakeup!
\n
"
);
}
static
struct
resource
rtc_resources
[]
=
{
[
0
]
=
{
/* RTC base, filled in by rtc_init */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录