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
42static unsigned long arch_timer_freq;
43
44void 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 */
58static 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
143sysclk1_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
161void __init omap5_realtime_timer_init(void)
162{
163	omap_clk_init();
164	realtime_counter_init();
165
166	timer_probe();
167}
168