2 * Copyright (C) 2008 Scientific-Atlanta, Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * The file comes from kernel/csrc-r4k.c
21 #include <linux/clocksource.h>
22 #include <linux/init.h>
24 #include <asm/time.h> /* Not included in linux/time.h */
26 #include <asm/mach-powertv/asic_regs.h>
27 #include "powertv-clock.h"
29 /* MIPS PLL Register Definitions */
30 #define PLL_GET_M(x) (((x) >> 8) & 0x000000FF)
31 #define PLL_GET_N(x) (((x) >> 16) & 0x000000FF)
32 #define PLL_GET_P(x) (((x) >> 24) & 0x00000007)
35 * returns: Clock frequency in kHz
37 unsigned int __init
mips_get_pll_freq(void)
39 unsigned int pll_reg
, m
, n
, p
;
40 unsigned int fin
= 54000; /* Base frequency in kHz */
43 /* Read PLL register setting */
44 pll_reg
= asic_read(mips_pll_setup
);
45 m
= PLL_GET_M(pll_reg
);
46 n
= PLL_GET_N(pll_reg
);
47 p
= PLL_GET_P(pll_reg
);
48 pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg
, m
, n
, p
);
50 /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
51 fout
= ((2 * n
* fin
) / (m
* (0x01 << p
)));
53 pr_info("MIPS Clock Freq=%d kHz\n", fout
);
58 static cycle_t
c0_hpt_read(struct clocksource
*cs
)
60 return read_c0_count();
63 static struct clocksource clocksource_mips
= {
64 .name
= "powertv-counter",
66 .mask
= CLOCKSOURCE_MASK(32),
67 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
70 static void __init
powertv_c0_hpt_clocksource_init(void)
72 unsigned int pll_freq
= mips_get_pll_freq();
74 pr_info("CPU frequency %d.%02d MHz\n", pll_freq
/ 1000,
75 (pll_freq
% 1000) * 100 / 1000);
77 mips_hpt_frequency
= pll_freq
/ 2 * 1000;
79 clocksource_mips
.rating
= 200 + mips_hpt_frequency
/ 10000000;
81 clocksource_register_hz(&clocksource_mips
, mips_hpt_frequency
);
85 * struct tim_c - free running counter
86 * @hi: High 16 bits of the counter
87 * @lo: Low 32 bits of the counter
89 * Lays out the structure of the free running counter in memory. This counter
90 * increments at a rate of 27 MHz/8 on all platforms.
97 static struct tim_c
*tim_c
;
99 static cycle_t
tim_c_read(struct clocksource
*cs
)
102 unsigned int next_hi
;
105 hi
= readl(&tim_c
->hi
);
108 lo
= readl(&tim_c
->lo
);
109 next_hi
= readl(&tim_c
->hi
);
115 pr_crit("%s: read %llx\n", __func__
, ((u64
) hi
<< 32) | lo
);
116 return ((u64
) hi
<< 32) | lo
;
119 #define TIM_C_SIZE 48 /* # bits in the timer */
121 static struct clocksource clocksource_tim_c
= {
122 .name
= "powertv-tim_c",
124 .mask
= CLOCKSOURCE_MASK(TIM_C_SIZE
),
125 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
129 * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
131 * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
132 * 1 / (27,000,000/8) seconds.
134 static void __init
powertv_tim_c_clocksource_init(void)
136 const unsigned long counts_per_second
= 27000000 / 8;
138 clocksource_tim_c
.rating
= 200;
140 clocksource_register_hz(&clocksource_tim_c
, counts_per_second
);
141 tim_c
= (struct tim_c
*) asic_reg_addr(tim_ch
);
145 powertv_clocksource_init - initialize all clocksources
147 void __init
powertv_clocksource_init(void)
149 powertv_c0_hpt_clocksource_init();
150 powertv_tim_c_clocksource_init();