Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
4d01cdaf
Commit
4d01cdaf
authored
Sep 29, 2008
by
Paul Mundt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sh: SH-5 clk fwk support.
Signed-off-by:
Paul Mundt
<
lethal@linux-sh.org
>
parent
50b72e60
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
91 additions
and
161 deletions
+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
No files found.
arch/sh/kernel/cpu/sh5/Makefile
View file @
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
View file @
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
View file @
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 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment