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_set_clock(&clocksource_mips
, mips_hpt_frequency
);
83 clocksource_register(&clocksource_mips
);
87 * struct tim_c - free running counter
88 * @hi: High 16 bits of the counter
89 * @lo: Low 32 bits of the counter
91 * Lays out the structure of the free running counter in memory. This counter
92 * increments at a rate of 27 MHz/8 on all platforms.
99 static struct tim_c
*tim_c
;
101 static cycle_t
tim_c_read(struct clocksource
*cs
)
104 unsigned int next_hi
;
107 hi
= readl(&tim_c
->hi
);
110 lo
= readl(&tim_c
->lo
);
111 next_hi
= readl(&tim_c
->hi
);
117 pr_crit("%s: read %llx\n", __func__
, ((u64
) hi
<< 32) | lo
);
118 return ((u64
) hi
<< 32) | lo
;
121 #define TIM_C_SIZE 48 /* # bits in the timer */
123 static struct clocksource clocksource_tim_c
= {
124 .name
= "powertv-tim_c",
126 .mask
= CLOCKSOURCE_MASK(TIM_C_SIZE
),
127 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
131 * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
133 * The hard part here is coming up with a constant k and shift s such that
134 * the 48-bit TIM_C value multiplied by k doesn't overflow and that value,
135 * when shifted right by s, yields the corresponding number of nanoseconds.
136 * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
137 * 1 / (27,000,000/8) seconds. Multiply that by a billion and you get the
138 * number of nanoseconds. Since the TIM_C value has 48 bits and the math is
139 * done in 64 bits, avoiding an overflow means that k must be less than
142 static void __init
powertv_tim_c_clocksource_init(void)
145 unsigned long dividend
;
148 const int max_k_bits
= (64 - 48) - 1;
149 const unsigned long billion
= 1000000000;
150 const unsigned long counts_per_second
= 27000000 / 8;
152 prescale
= BITS_PER_LONG
- ilog2(billion
) - 1;
153 dividend
= billion
<< prescale
;
154 k
= dividend
/ counts_per_second
;
155 s
= ilog2(k
) - max_k_bits
;
165 clocksource_tim_c
.mult
= k
;
166 clocksource_tim_c
.shift
= s
;
167 clocksource_tim_c
.rating
= 200;
169 clocksource_register(&clocksource_tim_c
);
170 tim_c
= (struct tim_c
*) asic_reg_addr(tim_ch
);
174 powertv_clocksource_init - initialize all clocksources
176 void __init
powertv_clocksource_init(void)
178 powertv_c0_hpt_clocksource_init();
179 powertv_tim_c_clocksource_init();