1 /* 2 * linux/arch/arm/mach-omap2/timer.c 3 * 4 * OMAP2 GP timer support. 5 * 6 * Copyright (C) 2009 Nokia Corporation 7 * 8 * Update to use new clocksource/clockevent layers 9 * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> 10 * Copyright (C) 2007 MontaVista Software, Inc. 11 * 12 * Original driver: 13 * Copyright (C) 2005 Nokia Corporation 14 * Author: Paul Mundt <paul.mundt@nokia.com> 15 * Juha Yrjölä <juha.yrjola@nokia.com> 16 * OMAP Dual-mode timer framework support by Timo Teras 17 * 18 * Some parts based off of TI's 24xx code: 19 * 20 * Copyright (C) 2004-2009 Texas Instruments, Inc. 21 * 22 * Roughly modelled after the OMAP1 MPU timer code. 23 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 24 * 25 * This file is subject to the terms and conditions of the GNU General Public 26 * License. See the file "COPYING" in the main directory of this archive 27 * for more details. 28 */ 29 #include <linux/clk.h> 30 #include <linux/clocksource.h> 31 32 #include "soc.h" 33 #include "common.h" 34 #include "control.h" 35 #include "omap-secure.h" 36 37 #define REALTIME_COUNTER_BASE 0x48243200 38 #define INCREMENTER_NUMERATOR_OFFSET 0x10 39 #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 40 #define NUMERATOR_DENUMERATOR_MASK 0xfffff000 41 42 static unsigned long arch_timer_freq; 43 44 void set_cntfreq(void) 45 { 46 omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); 47 } 48 49 /* 50 * The realtime counter also called master counter, is a free-running 51 * counter, which is related to real time. It produces the count used 52 * by the CPU local timer peripherals in the MPU cluster. The timer counts 53 * at a rate of 6.144 MHz. Because the device operates on different clocks 54 * in different power modes, the master counter shifts operation between 55 * clocks, adjusting the increment per clock in hardware accordingly to 56 * maintain a constant count rate. 57 */ 58 static void __init realtime_counter_init(void) 59 { 60 void __iomem *base; 61 static struct clk *sys_clk; 62 unsigned long rate; 63 unsigned int reg; 64 unsigned long long num, den; 65 66 base = ioremap(REALTIME_COUNTER_BASE, SZ_32); 67 if (!base) { 68 pr_err("%s: ioremap failed\n", __func__); 69 return; 70 } 71 sys_clk = clk_get(NULL, "sys_clkin"); 72 if (IS_ERR(sys_clk)) { 73 pr_err("%s: failed to get system clock handle\n", __func__); 74 iounmap(base); 75 return; 76 } 77 78 rate = clk_get_rate(sys_clk); 79 clk_put(sys_clk); 80 81 if (soc_is_dra7xx()) { 82 /* 83 * Errata i856 says the 32.768KHz crystal does not start at 84 * power on, so the CPU falls back to an emulated 32KHz clock 85 * based on sysclk / 610 instead. This causes the master counter 86 * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2 87 * (OR sysclk * 75 / 244) 88 * 89 * This affects at least the DRA7/AM572x 1.0, 1.1 revisions. 90 * Of course any board built without a populated 32.768KHz 91 * crystal would also need this fix even if the CPU is fixed 92 * later. 93 * 94 * Either case can be detected by using the two speedselect bits 95 * If they are not 0, then the 32.768KHz clock driving the 96 * coarse counter that corrects the fine counter every time it 97 * ticks is actually rate/610 rather than 32.768KHz and we 98 * should compensate to avoid the 570ppm (at 20MHz, much worse 99 * at other rates) too fast system time. 100 */ 101 reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); 102 if (reg & DRA7_SPEEDSELECT_MASK) { 103 num = 75; 104 den = 244; 105 goto sysclk1_based; 106 } 107 } 108 109 /* Numerator/denumerator values refer TRM Realtime Counter section */ 110 switch (rate) { 111 case 12000000: 112 num = 64; 113 den = 125; 114 break; 115 case 13000000: 116 num = 768; 117 den = 1625; 118 break; 119 case 19200000: 120 num = 8; 121 den = 25; 122 break; 123 case 20000000: 124 num = 192; 125 den = 625; 126 break; 127 case 26000000: 128 num = 384; 129 den = 1625; 130 break; 131 case 27000000: 132 num = 256; 133 den = 1125; 134 break; 135 case 38400000: 136 default: 137 /* Program it for 38.4 MHz */ 138 num = 4; 139 den = 25; 140 break; 141 } 142 143 sysclk1_based: 144 /* Program numerator and denumerator registers */ 145 reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & 146 NUMERATOR_DENUMERATOR_MASK; 147 reg |= num; 148 writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET); 149 150 reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) & 151 NUMERATOR_DENUMERATOR_MASK; 152 reg |= den; 153 writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); 154 155 arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den); 156 set_cntfreq(); 157 158 iounmap(base); 159 } 160 161 void __init omap5_realtime_timer_init(void) 162 { 163 omap_clk_init(); 164 realtime_counter_init(); 165 166 timer_probe(); 167 } 168