aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2013-07-11 12:22:29 -0400
committerSimon Horman <horms+renesas@verge.net.au>2013-07-17 01:26:56 -0400
commit81b9d5351fa96caad4accc6711bc1b9342927d4a (patch)
treea8e98aecd34fdf7b2cba967781ff9502196e53f7
parent512e53bc7f0088e3adfd89b3fea3447495fc8423 (diff)
ARM: shmobile: Setup r8a7790 arch timer based on MD pins
Update the r8a7790 arch timer setup code to configure the frequency dynamically at boot time. This means that the arch timer driver will be able to detect a timer frequency that has been calculated based on the MD pins instead of a fixed and potentially incorrect 13 MHz. With this patch applied the Linux kernel will correctly support the r8a7790 Lager board that uses a 20 Mhz EXTAL. The arch timer will operate on 10 MHz and the Linux arch timer driver will be correctly configured to use 10 MHz. Without this patch the 20 MHz EXTAL will be used to drive the arch timer at 10 MHz, but the Linux arch timer driver will believe it is counting at 13 Mhz. Reported-by: Ulrich Hecht <ulrich.hecht@gmail.com> Signed-off-by: Magnus Damm <damm@opensource.se> Tested-by: Ulrich Hecht <ulrich.hecht@gmail.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7790.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index 6acddc139d88..4c96dad21195 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -210,14 +210,53 @@ u32 __init r8a7790_read_mode_pins(void)
210 return mode; 210 return mode;
211} 211}
212 212
213#define CNTCR 0
214#define CNTFID0 0x20
215
213void __init r8a7790_timer_init(void) 216void __init r8a7790_timer_init(void)
214{ 217{
215 void __iomem *cntcr; 218#ifdef CONFIG_ARM_ARCH_TIMER
216 219 u32 mode = r8a7790_read_mode_pins();
217 /* make sure arch timer is started by setting bit 0 of CNTCT */ 220 void __iomem *base;
218 cntcr = ioremap(0xe6080000, PAGE_SIZE); 221 int extal_mhz = 0;
219 iowrite32(1, cntcr); 222 u32 freq;
220 iounmap(cntcr); 223
224 /* At Linux boot time the r8a7790 arch timer comes up
225 * with the counter disabled. Moreover, it may also report
226 * a potentially incorrect fixed 13 MHz frequency. To be
227 * correct these registers need to be updated to use the
228 * frequency EXTAL / 2 which can be determined by the MD pins.
229 */
230
231 switch (mode & (MD(14) | MD(13))) {
232 case 0:
233 extal_mhz = 15;
234 break;
235 case MD(13):
236 extal_mhz = 20;
237 break;
238 case MD(14):
239 extal_mhz = 26;
240 break;
241 case MD(13) | MD(14):
242 extal_mhz = 30;
243 break;
244 }
245
246 /* The arch timer frequency equals EXTAL / 2 */
247 freq = extal_mhz * (1000000 / 2);
248
249 /* Remap "armgcnt address map" space */
250 base = ioremap(0xe6080000, PAGE_SIZE);
251
252 /* Update registers with correct frequency */
253 iowrite32(freq, base + CNTFID0);
254 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
255
256 /* make sure arch timer is started by setting bit 0 of CNTCR */
257 iowrite32(1, base + CNTCR);
258 iounmap(base);
259#endif /* CONFIG_ARM_ARCH_TIMER */
221 260
222 shmobile_timer_init(); 261 shmobile_timer_init();
223} 262}