dmtimer.c 15.1 KB
Newer Older
1 2 3 4 5 6
/*
 * linux/arch/arm/plat-omap/dmtimer.c
 *
 * OMAP Dual-Mode Timers
 *
 * Copyright (C) 2005 Nokia Corporation
7 8
 * OMAP2 support by Juha Yrjola
 * API improvements and OMAP2 clock framework support by Timo Teras
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * You should have received a copy of the  GNU General Public License along
 * with this program; if not, write  to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/init.h>
30 31 32 33 34
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/delay.h>
35
#include <asm/hardware.h>
36 37 38 39
#include <asm/arch/dmtimer.h>
#include <asm/io.h>
#include <asm/arch/irqs.h>

40
/* register offsets */
41 42 43 44 45 46 47 48 49 50
#define OMAP_TIMER_ID_REG		0x00
#define OMAP_TIMER_OCP_CFG_REG		0x10
#define OMAP_TIMER_SYS_STAT_REG		0x14
#define OMAP_TIMER_STAT_REG		0x18
#define OMAP_TIMER_INT_EN_REG		0x1c
#define OMAP_TIMER_WAKEUP_EN_REG	0x20
#define OMAP_TIMER_CTRL_REG		0x24
#define OMAP_TIMER_COUNTER_REG		0x28
#define OMAP_TIMER_LOAD_REG		0x2c
#define OMAP_TIMER_TRIGGER_REG		0x30
51
#define OMAP_TIMER_WRITE_PEND_REG	0x34
52 53 54 55
#define OMAP_TIMER_MATCH_REG		0x38
#define OMAP_TIMER_CAPTURE_REG		0x3c
#define OMAP_TIMER_IF_CTRL_REG		0x40

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/* timer control reg bits */
#define OMAP_TIMER_CTRL_GPOCFG		(1 << 14)
#define OMAP_TIMER_CTRL_CAPTMODE	(1 << 13)
#define OMAP_TIMER_CTRL_PT		(1 << 12)
#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH	(0x1 << 8)
#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW	(0x2 << 8)
#define OMAP_TIMER_CTRL_TCM_BOTHEDGES	(0x3 << 8)
#define OMAP_TIMER_CTRL_SCPWM		(1 << 7)
#define OMAP_TIMER_CTRL_CE		(1 << 6)	/* compare enable */
#define OMAP_TIMER_CTRL_PRE		(1 << 5)	/* prescaler enable */
#define OMAP_TIMER_CTRL_PTV_SHIFT	2		/* how much to shift the prescaler value */
#define OMAP_TIMER_CTRL_AR		(1 << 1)	/* auto-reload enable */
#define OMAP_TIMER_CTRL_ST		(1 << 0)	/* start timer */

struct omap_dm_timer {
	unsigned long phys_base;
	int irq;
73
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
74 75 76 77
	struct clk *iclk, *fclk;
#endif
	void __iomem *io_base;
	unsigned reserved:1;
78
	unsigned enabled:1;
79 80 81 82
};

#ifdef CONFIG_ARCH_OMAP1

83 84
#define omap_dm_clk_enable(x)
#define omap_dm_clk_disable(x)
85 86 87
#define omap2_dm_timers			NULL
#define omap2_dm_source_names		NULL
#define omap2_dm_source_clocks		NULL
88 89 90
#define omap3_dm_timers			NULL
#define omap3_dm_source_names		NULL
#define omap3_dm_source_clocks		NULL
91

92
static struct omap_dm_timer omap1_dm_timers[] = {
93 94 95 96 97 98
	{ .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
	{ .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
	{ .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 },
	{ .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 },
	{ .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 },
	{ .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 },
99 100
	{ .phys_base = 0xfffb7400, .irq = INT_1610_GPTIMER7 },
	{ .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 },
101
};
102

103 104
static const int dm_timer_count = ARRAY_SIZE(omap1_dm_timers);

105
#elif defined(CONFIG_ARCH_OMAP2)
106

107 108 109
#define omap_dm_clk_enable(x)		clk_enable(x)
#define omap_dm_clk_disable(x)		clk_disable(x)
#define omap1_dm_timers			NULL
110 111 112
#define omap3_dm_timers			NULL
#define omap3_dm_source_names		NULL
#define omap3_dm_source_clocks		NULL
113

114
static struct omap_dm_timer omap2_dm_timers[] = {
115 116 117 118 119 120 121 122 123 124 125 126
	{ .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
	{ .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
	{ .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
	{ .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
	{ .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
	{ .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
	{ .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
	{ .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
	{ .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
	{ .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
127 128
};

129
static const char *omap2_dm_source_names[] __initdata = {
Timo Teras's avatar
Timo Teras committed
130 131
	"sys_ck",
	"func_32k_ck",
132 133
	"alt_ck",
	NULL
Timo Teras's avatar
Timo Teras committed
134 135
};

136 137
static struct clk **omap2_dm_source_clocks[3];
static const int dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
Timo Teras's avatar
Timo Teras committed
138

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#elif defined(CONFIG_ARCH_OMAP3)

#define omap_dm_clk_enable(x)		clk_enable(x)
#define omap_dm_clk_disable(x)		clk_disable(x)
#define omap1_dm_timers			NULL
#define omap2_dm_timers			NULL
#define omap2_dm_source_names		NULL
#define omap2_dm_source_clocks		NULL

static struct omap_dm_timer omap3_dm_timers[] = {
	{ .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
	{ .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
	{ .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 },
	{ .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 },
	{ .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 },
	{ .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 },
	{ .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 },
	{ .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 },
	{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
	{ .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 },
};

static const char *omap3_dm_source_names[] __initdata = {
	"sys_ck",
	"omap_32k_fck",
	NULL
};

static struct clk **omap3_dm_source_clocks[2];
static const int dm_timer_count = ARRAY_SIZE(omap3_dm_timers);

172 173 174 175 176 177
#else

#error OMAP architecture not supported!

#endif

178 179 180 181
static struct omap_dm_timer *dm_timers;
static char **dm_source_names;
static struct clk **dm_source_clocks;

182 183
static spinlock_t dm_timer_lock;

184 185 186 187
static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
{
	return readl(timer->io_base + reg);
}
188

189
static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
190
{
191
	writel(value, timer->io_base + reg);
192 193 194 195
	while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
		;
}

196
static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
197
{
198 199 200 201 202 203 204 205 206 207
	int c;

	c = 0;
	while (!(omap_dm_timer_read_reg(timer, OMAP_TIMER_SYS_STAT_REG) & 1)) {
		c++;
		if (c > 100000) {
			printk(KERN_ERR "Timer failed to reset\n");
			return;
		}
	}
208 209
}

210 211 212 213
static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
	u32 l;

214
	if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
215 216 217
		omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
		omap_dm_timer_wait_for_reset(timer);
	}
218
	omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
219 220 221 222

	/* Set to smart-idle mode */
	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
	l |= 0x02 << 3;
223 224 225 226 227 228 229

	if (cpu_class_is_omap2() && timer == &dm_timers[0]) {
		/* Enable wake-up only for GPT1 on OMAP2 CPUs*/
		l |= 1 << 2;
		/* Non-posted mode */
		omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0);
	}
230 231 232
	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
}

Timo Teras's avatar
Timo Teras committed
233
static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
234
{
235
	omap_dm_timer_enable(timer);
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
	omap_dm_timer_reset(timer);
}

struct omap_dm_timer *omap_dm_timer_request(void)
{
	struct omap_dm_timer *timer = NULL;
	unsigned long flags;
	int i;

	spin_lock_irqsave(&dm_timer_lock, flags);
	for (i = 0; i < dm_timer_count; i++) {
		if (dm_timers[i].reserved)
			continue;

		timer = &dm_timers[i];
Timo Teras's avatar
Timo Teras committed
251
		timer->reserved = 1;
252 253 254 255
		break;
	}
	spin_unlock_irqrestore(&dm_timer_lock, flags);

Timo Teras's avatar
Timo Teras committed
256 257 258
	if (timer != NULL)
		omap_dm_timer_prepare(timer);

259 260 261 262
	return timer;
}

struct omap_dm_timer *omap_dm_timer_request_specific(int id)
263 264
{
	struct omap_dm_timer *timer;
265
	unsigned long flags;
266

267 268 269 270 271 272 273 274
	spin_lock_irqsave(&dm_timer_lock, flags);
	if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) {
		spin_unlock_irqrestore(&dm_timer_lock, flags);
		printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n",
		       __FILE__, __LINE__, __FUNCTION__, id);
		dump_stack();
		return NULL;
	}
275

276
	timer = &dm_timers[id-1];
Timo Teras's avatar
Timo Teras committed
277
	timer->reserved = 1;
278 279
	spin_unlock_irqrestore(&dm_timer_lock, flags);

Timo Teras's avatar
Timo Teras committed
280 281
	omap_dm_timer_prepare(timer);

282
	return timer;
283 284
}

285 286
void omap_dm_timer_free(struct omap_dm_timer *timer)
{
287
	omap_dm_timer_enable(timer);
288
	omap_dm_timer_reset(timer);
289
	omap_dm_timer_disable(timer);
290

291 292 293 294
	WARN_ON(!timer->reserved);
	timer->reserved = 0;
}

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
void omap_dm_timer_enable(struct omap_dm_timer *timer)
{
	if (timer->enabled)
		return;

	omap_dm_clk_enable(timer->fclk);
	omap_dm_clk_enable(timer->iclk);

	timer->enabled = 1;
}

void omap_dm_timer_disable(struct omap_dm_timer *timer)
{
	if (!timer->enabled)
		return;

	omap_dm_clk_disable(timer->iclk);
	omap_dm_clk_disable(timer->fclk);

	timer->enabled = 0;
}

317 318 319 320 321 322 323
int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
{
	return timer->irq;
}

#if defined(CONFIG_ARCH_OMAP1)

324 325 326 327 328 329
/**
 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
 * @inputmask: current value of idlect mask
 */
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
330
	int i;
331 332 333 334 335 336

	/* If ARMXOR cannot be idled this function call is unnecessary */
	if (!(inputmask & (1 << 1)))
		return inputmask;

	/* If any active timer is using ARMXOR return modified mask */
337 338 339
	for (i = 0; i < dm_timer_count; i++) {
		u32 l;

340
		l = omap_dm_timer_read_reg(&dm_timers[i], OMAP_TIMER_CTRL_REG);
341 342
		if (l & OMAP_TIMER_CTRL_ST) {
			if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
343 344 345 346
				inputmask &= ~(1 << 1);
			else
				inputmask &= ~(1 << 2);
		}
347
	}
348 349 350 351

	return inputmask;
}

352
#elif defined(CONFIG_ARCH_OMAP2) || defined (CONFIG_ARCH_OMAP3)
353

354
struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
355
{
356
	return timer->fclk;
357
}
358

359 360 361
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
	BUG();
362 363

	return 0;
364 365
}

366
#endif
367

368
void omap_dm_timer_trigger(struct omap_dm_timer *timer)
369
{
370
	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
371 372
}

373 374 375
void omap_dm_timer_start(struct omap_dm_timer *timer)
{
	u32 l;
376

377 378 379 380 381 382
	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	if (!(l & OMAP_TIMER_CTRL_ST)) {
		l |= OMAP_TIMER_CTRL_ST;
		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
	}
}
383

384
void omap_dm_timer_stop(struct omap_dm_timer *timer)
385
{
386
	u32 l;
387

388 389 390 391
	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	if (l & OMAP_TIMER_CTRL_ST) {
		l &= ~0x1;
		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
392 393 394
	}
}

395
#ifdef CONFIG_ARCH_OMAP1
396

397
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
398
{
399 400
	int n = (timer - dm_timers) << 1;
	u32 l;
401

402 403 404
	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
	l |= source << n;
	omap_writel(l, MOD_CONF_CTRL_1);
405 406
}

407
#else
408

409
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
410
{
411 412 413 414
	if (source < 0 || source >= 3)
		return;

	clk_disable(timer->fclk);
Timo Teras's avatar
Timo Teras committed
415
	clk_set_parent(timer->fclk, dm_source_clocks[source]);
416 417 418 419
	clk_enable(timer->fclk);

	/* When the functional clock disappears, too quick writes seem to
	 * cause an abort. */
420
	__delay(150000);
421 422
}

423
#endif
424

425 426
void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
			    unsigned int load)
427 428
{
	u32 l;
429

430
	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
431 432 433 434
	if (autoreload)
		l |= OMAP_TIMER_CTRL_AR;
	else
		l &= ~OMAP_TIMER_CTRL_AR;
435
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
436 437
	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
438 439
}

440 441
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
			     unsigned int match)
442 443 444 445
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
Timo Teras's avatar
Timo Teras committed
446
	if (enable)
447 448 449
		l |= OMAP_TIMER_CTRL_CE;
	else
		l &= ~OMAP_TIMER_CTRL_CE;
450
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
451
	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
452 453
}

454 455 456

void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
			   int toggle, int trigger)
457 458 459 460
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
461 462 463 464 465 466 467
	l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
	       OMAP_TIMER_CTRL_PT | (0x03 << 10));
	if (def_on)
		l |= OMAP_TIMER_CTRL_SCPWM;
	if (toggle)
		l |= OMAP_TIMER_CTRL_PT;
	l |= trigger << 10;
468 469 470
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

471
void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
472 473 474 475
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
476 477 478 479 480
	l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
	if (prescaler >= 0x00 && prescaler <= 0x07) {
		l |= OMAP_TIMER_CTRL_PRE;
		l |= prescaler << 2;
	}
481 482 483
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

484 485
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
				  unsigned int value)
486
{
487
	omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
488
	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
489 490
}

491
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
492
{
493 494 495 496 497
	unsigned int l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);

	return l;
498 499
}

500
void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
501
{
502
	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
503 504
}

505
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
506
{
507 508 509 510 511
	unsigned int l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);

	return l;
512 513
}

Timo Teras's avatar
Timo Teras committed
514 515
void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
516
	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
Timo Teras's avatar
Timo Teras committed
517 518
}

519
int omap_dm_timers_active(void)
520
{
521
	int i;
522

523 524
	for (i = 0; i < dm_timer_count; i++) {
		struct omap_dm_timer *timer;
525

526
		timer = &dm_timers[i];
527 528 529 530

		if (!timer->enabled)
			continue;

531
		if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
532
		    OMAP_TIMER_CTRL_ST) {
533
			return 1;
534
		}
535 536 537
	}
	return 0;
}
538

539
int __init omap_dm_timer_init(void)
540 541
{
	struct omap_dm_timer *timer;
542 543
	int i;

544
	if (!(cpu_is_omap16xx() || cpu_class_is_omap2()))
545
		return -ENODEV;
546 547

	spin_lock_init(&dm_timer_lock);
548 549 550 551 552 553 554

	if (cpu_class_is_omap1())
		dm_timers = omap1_dm_timers;
	else if (cpu_is_omap24xx()) {
		dm_timers = omap2_dm_timers;
		dm_source_names = (char **)omap2_dm_source_names;
		dm_source_clocks = (struct clk **)omap2_dm_source_clocks;
555 556 557 558
	} else if (cpu_is_omap34xx()) {
		dm_timers = omap3_dm_timers;
		dm_source_names = (char **)omap3_dm_source_names;
		dm_source_clocks = (struct clk **)omap3_dm_source_clocks;
Timo Teras's avatar
Timo Teras committed
559
	}
560 561 562 563 564

	if (cpu_class_is_omap2())
		for (i = 0; dm_source_names[i] != NULL; i++)
			dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);

565 566
	if (cpu_is_omap243x())
		dm_timers[0].phys_base = 0x49018000;
Timo Teras's avatar
Timo Teras committed
567

568 569
	for (i = 0; i < dm_timer_count; i++) {
		timer = &dm_timers[i];
570
		timer->io_base = (void __iomem *)io_p2v(timer->phys_base);
571
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
572 573 574 575 576 577 578
		if (cpu_class_is_omap2()) {
			char clk_name[16];
			sprintf(clk_name, "gpt%d_ick", i + 1);
			timer->iclk = clk_get(NULL, clk_name);
			sprintf(clk_name, "gpt%d_fck", i + 1);
			timer->fclk = clk_get(NULL, clk_name);
		}
579
#endif
580 581 582 583
	}

	return 0;
}