Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mips
mti-malta
malta-time.c
Go to the documentation of this file.
1
/*
2
* Carsten Langgaard,
[email protected]
3
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
4
*
5
* This program is free software; you can distribute it and/or modify it
6
* under the terms of the GNU General Public License (Version 2) as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* for more details.
13
*
14
* You should have received a copy of the GNU General Public License along
15
* with this program; if not, write to the Free Software Foundation, Inc.,
16
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17
*
18
* Setting up the clock on the MIPS boards.
19
*/
20
21
#include <linux/types.h>
22
#include <
linux/i8253.h
>
23
#include <
linux/init.h
>
24
#include <
linux/kernel_stat.h
>
25
#include <linux/sched.h>
26
#include <
linux/spinlock.h
>
27
#include <
linux/interrupt.h
>
28
#include <linux/time.h>
29
#include <linux/timex.h>
30
#include <
linux/mc146818rtc.h
>
31
32
#include <
asm/mipsregs.h
>
33
#include <
asm/mipsmtregs.h
>
34
#include <asm/hardirq.h>
35
#include <asm/irq.h>
36
#include <asm/div64.h>
37
#include <asm/cpu.h>
38
#include <asm/setup.h>
39
#include <asm/time.h>
40
#include <
asm/mc146818-time.h
>
41
#include <
asm/msc01_ic.h
>
42
43
#include <
asm/mips-boards/generic.h
>
44
#include <
asm/mips-boards/prom.h
>
45
46
#include <
asm/mips-boards/maltaint.h
>
47
48
unsigned
long
cpu_khz
;
49
50
static
int
mips_cpu_timer_irq;
51
static
int
mips_cpu_perf_irq;
52
extern
int
cp0_perfcount_irq
;
53
54
static
void
mips_timer_dispatch(
void
)
55
{
56
do_IRQ
(mips_cpu_timer_irq);
57
}
58
59
static
void
mips_perf_dispatch(
void
)
60
{
61
do_IRQ
(mips_cpu_perf_irq);
62
}
63
64
/*
65
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
66
*/
67
static
unsigned
int
__init
estimate_cpu_frequency(
void
)
68
{
69
unsigned
int
prid =
read_c0_prid
() & 0xffff00;
70
unsigned
int
count
;
71
72
unsigned
long
flags
;
73
unsigned
int
start
;
74
75
local_irq_save
(flags);
76
77
/* Start counter exactly on falling edge of update flag */
78
while
(
CMOS_READ
(
RTC_REG_A
) &
RTC_UIP
);
79
while
(!(
CMOS_READ
(
RTC_REG_A
) & RTC_UIP));
80
81
/* Start r4k counter. */
82
start =
read_c0_count
();
83
84
/* Read counter exactly on falling edge of update flag */
85
while
(
CMOS_READ
(
RTC_REG_A
) & RTC_UIP);
86
while
(!(
CMOS_READ
(
RTC_REG_A
) & RTC_UIP));
87
88
count =
read_c0_count
() -
start
;
89
90
/* restore interrupts */
91
local_irq_restore
(flags);
92
93
mips_hpt_frequency
=
count
;
94
if
((prid != (
PRID_COMP_MIPS
|
PRID_IMP_20KC
)) &&
95
(prid != (
PRID_COMP_MIPS
|
PRID_IMP_25KF
)))
96
count *= 2;
97
98
count += 5000;
/* round */
99
count -= count%10000;
100
101
return
count
;
102
}
103
104
void
read_persistent_clock
(
struct
timespec
*
ts
)
105
{
106
ts->
tv_sec
= mc146818_get_cmos_time();
107
ts->
tv_nsec
= 0;
108
}
109
110
static
void
__init
plat_perf_setup(
void
)
111
{
112
#ifdef MSC01E_INT_BASE
113
if
(
cpu_has_veic
) {
114
set_vi_handler
(
MSC01E_INT_PERFCTR
, mips_perf_dispatch);
115
mips_cpu_perf_irq =
MSC01E_INT_BASE
+
MSC01E_INT_PERFCTR
;
116
}
else
117
#endif
118
if
(
cp0_perfcount_irq
>= 0) {
119
if
(
cpu_has_vint
)
120
set_vi_handler
(
cp0_perfcount_irq
, mips_perf_dispatch);
121
mips_cpu_perf_irq =
MIPS_CPU_IRQ_BASE
+
cp0_perfcount_irq
;
122
#ifdef CONFIG_SMP
123
irq_set_handler(mips_cpu_perf_irq,
handle_percpu_irq
);
124
#endif
125
}
126
}
127
128
unsigned
int
__cpuinit
get_c0_compare_int
(
void
)
129
{
130
#ifdef MSC01E_INT_BASE
131
if
(
cpu_has_veic
) {
132
set_vi_handler
(
MSC01E_INT_CPUCTR
, mips_timer_dispatch);
133
mips_cpu_timer_irq =
MSC01E_INT_BASE
+
MSC01E_INT_CPUCTR
;
134
}
else
135
#endif
136
{
137
if
(
cpu_has_vint
)
138
set_vi_handler
(
cp0_compare_irq
, mips_timer_dispatch);
139
mips_cpu_timer_irq =
MIPS_CPU_IRQ_BASE
+
cp0_compare_irq
;
140
}
141
142
return
mips_cpu_timer_irq;
143
}
144
145
void
__init
plat_time_init
(
void
)
146
{
147
unsigned
int
est_freq;
148
149
/* Set Data mode - binary. */
150
CMOS_WRITE
(
CMOS_READ
(
RTC_CONTROL
) |
RTC_DM_BINARY
,
RTC_CONTROL
);
151
152
est_freq = estimate_cpu_frequency();
153
154
printk
(
"CPU frequency %d.%02d MHz\n"
, est_freq/1000000,
155
(est_freq%1000000)*100/1000000);
156
157
cpu_khz
= est_freq / 1000;
158
159
mips_scroll_message
();
160
#ifdef CONFIG_I8253
/* Only Malta has a PIT */
161
setup_pit_timer
();
162
#endif
163
164
plat_perf_setup();
165
}
Generated on Thu Jan 10 2013 13:11:49 for Linux Kernel by
1.8.2