Linux Audio

Check our new training course

Loading...
v6.2
  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
 80	if (soc_is_dra7xx()) {
 81		/*
 82		 * Errata i856 says the 32.768KHz crystal does not start at
 83		 * power on, so the CPU falls back to an emulated 32KHz clock
 84		 * based on sysclk / 610 instead. This causes the master counter
 85		 * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
 86		 * (OR sysclk * 75 / 244)
 87		 *
 88		 * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
 89		 * Of course any board built without a populated 32.768KHz
 90		 * crystal would also need this fix even if the CPU is fixed
 91		 * later.
 92		 *
 93		 * Either case can be detected by using the two speedselect bits
 94		 * If they are not 0, then the 32.768KHz clock driving the
 95		 * coarse counter that corrects the fine counter every time it
 96		 * ticks is actually rate/610 rather than 32.768KHz and we
 97		 * should compensate to avoid the 570ppm (at 20MHz, much worse
 98		 * at other rates) too fast system time.
 99		 */
100		reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
101		if (reg & DRA7_SPEEDSELECT_MASK) {
102			num = 75;
103			den = 244;
104			goto sysclk1_based;
105		}
106	}
107
108	/* Numerator/denumerator values refer TRM Realtime Counter section */
109	switch (rate) {
110	case 12000000:
111		num = 64;
112		den = 125;
113		break;
114	case 13000000:
115		num = 768;
116		den = 1625;
117		break;
118	case 19200000:
119		num = 8;
120		den = 25;
121		break;
122	case 20000000:
123		num = 192;
124		den = 625;
125		break;
126	case 26000000:
127		num = 384;
128		den = 1625;
129		break;
130	case 27000000:
131		num = 256;
132		den = 1125;
133		break;
134	case 38400000:
135	default:
136		/* Program it for 38.4 MHz */
137		num = 4;
138		den = 25;
139		break;
140	}
141
142sysclk1_based:
143	/* Program numerator and denumerator registers */
144	reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
145			NUMERATOR_DENUMERATOR_MASK;
146	reg |= num;
147	writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET);
148
149	reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) &
150			NUMERATOR_DENUMERATOR_MASK;
151	reg |= den;
152	writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
153
154	arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
155	set_cntfreq();
156
157	iounmap(base);
158}
159
160void __init omap5_realtime_timer_init(void)
161{
162	omap_clk_init();
163	realtime_counter_init();
164
165	timer_probe();
166}
v5.14.15
  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
 80	if (soc_is_dra7xx()) {
 81		/*
 82		 * Errata i856 says the 32.768KHz crystal does not start at
 83		 * power on, so the CPU falls back to an emulated 32KHz clock
 84		 * based on sysclk / 610 instead. This causes the master counter
 85		 * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
 86		 * (OR sysclk * 75 / 244)
 87		 *
 88		 * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
 89		 * Of course any board built without a populated 32.768KHz
 90		 * crystal would also need this fix even if the CPU is fixed
 91		 * later.
 92		 *
 93		 * Either case can be detected by using the two speedselect bits
 94		 * If they are not 0, then the 32.768KHz clock driving the
 95		 * coarse counter that corrects the fine counter every time it
 96		 * ticks is actually rate/610 rather than 32.768KHz and we
 97		 * should compensate to avoid the 570ppm (at 20MHz, much worse
 98		 * at other rates) too fast system time.
 99		 */
100		reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
101		if (reg & DRA7_SPEEDSELECT_MASK) {
102			num = 75;
103			den = 244;
104			goto sysclk1_based;
105		}
106	}
107
108	/* Numerator/denumerator values refer TRM Realtime Counter section */
109	switch (rate) {
110	case 12000000:
111		num = 64;
112		den = 125;
113		break;
114	case 13000000:
115		num = 768;
116		den = 1625;
117		break;
118	case 19200000:
119		num = 8;
120		den = 25;
121		break;
122	case 20000000:
123		num = 192;
124		den = 625;
125		break;
126	case 26000000:
127		num = 384;
128		den = 1625;
129		break;
130	case 27000000:
131		num = 256;
132		den = 1125;
133		break;
134	case 38400000:
135	default:
136		/* Program it for 38.4 MHz */
137		num = 4;
138		den = 25;
139		break;
140	}
141
142sysclk1_based:
143	/* Program numerator and denumerator registers */
144	reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
145			NUMERATOR_DENUMERATOR_MASK;
146	reg |= num;
147	writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET);
148
149	reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) &
150			NUMERATOR_DENUMERATOR_MASK;
151	reg |= den;
152	writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
153
154	arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
155	set_cntfreq();
156
157	iounmap(base);
158}
159
160void __init omap5_realtime_timer_init(void)
161{
162	omap_clk_init();
163	realtime_counter_init();
164
165	timer_probe();
166}