Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2c5d4ed authored by James Hogan's avatar James Hogan
Browse files

metag: Time keeping



Add time keeping code for metag. Meta hardware threads have 2 timers.
The background timer (TXTIMER) is used as a free-running time base, and
the interrupt timer (TXTIMERI) is used for the timer interrupt. Both
counters traditionally count at approximately 1MHz.

Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
parent bc3966bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5039,6 +5039,7 @@ S: Supported
F:	arch/metag/
F:	Documentation/metag/
F:	Documentation/devicetree/bindings/metag/
F:	drivers/clocksource/metag_generic.c

MICROBLAZE ARCHITECTURE
M:	Michal Simek <monstr@monstr.eu>
+51 −0
Original line number Diff line number Diff line
/*
 * arch/metag/include/asm/clock.h
 *
 * Copyright (C) 2012 Imagination Technologies Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef _METAG_CLOCK_H_
#define _METAG_CLOCK_H_

#include <asm/mach/arch.h>

/**
 * struct meta_clock_desc - Meta Core clock callbacks.
 * @get_core_freq:	Get the frequency of the Meta core. If this is NULL, the
 *			core frequency will be determined like this:
 *			Meta 1: based on loops_per_jiffy.
 *			Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
 */
struct meta_clock_desc {
	unsigned long		(*get_core_freq)(void);
};

extern struct meta_clock_desc _meta_clock;

/*
 * Set up the default clock, ensuring all callbacks are valid - only accessible
 * during boot.
 */
void setup_meta_clocks(struct meta_clock_desc *desc);

/**
 * get_coreclock() - Get the frequency of the Meta core clock.
 *
 * Returns:	The Meta core clock frequency in Hz.
 */
static inline unsigned long get_coreclock(void)
{
	/*
	 * Use the current clock callback. If set correctly this will provide
	 * the most accurate frequency as it can be calculated directly from the
	 * PLL configuration. otherwise a default callback will have been set
	 * instead.
	 */
	return _meta_clock.get_core_freq();
}

#endif /* _METAG_CLOCK_H_ */
+29 −0
Original line number Diff line number Diff line
#ifndef _METAG_DELAY_H
#define _METAG_DELAY_H

/*
 * Copyright (C) 1993 Linus Torvalds
 *
 * Delay routines calling functions in arch/metag/lib/delay.c
 */

/* Undefined functions to get compile-time errors */
extern void __bad_udelay(void);
extern void __bad_ndelay(void);

extern void __udelay(unsigned long usecs);
extern void __ndelay(unsigned long nsecs);
extern void __const_udelay(unsigned long xloops);
extern void __delay(unsigned long loops);

/* 0x10c7 is 2**32 / 1000000 (rounded up) */
#define udelay(n) (__builtin_constant_p(n) ? \
	((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
	__udelay(n))

/* 0x5 is 2**32 / 1000000000 (rounded up) */
#define ndelay(n) (__builtin_constant_p(n) ? \
	((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
	__ndelay(n))

#endif /* _METAG_DELAY_H */
+4 −0
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

#include <linux/stddef.h>

#include <asm/clock.h>

/**
 * struct machine_desc - Describes a board controlled by a Meta.
 * @name:		Board/SoC name.
 * @dt_compat:		Array of device tree 'compatible' strings.
 * @clocks:		Clock callbacks.
 *
 * @nr_irqs:		Maximum number of IRQs.
 *			If 0, defaults to NR_IRQS in asm-generic/irq.h.
@@ -37,6 +40,7 @@
struct machine_desc {
	const char		*name;
	const char		**dt_compat;
	struct meta_clock_desc	*clocks;

	unsigned int		nr_irqs;

+53 −0
Original line number Diff line number Diff line
/*
 * arch/metag/kernel/clock.c
 *
 * Copyright (C) 2012 Imagination Technologies Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/io.h>

#include <asm/param.h>
#include <asm/clock.h>

struct meta_clock_desc _meta_clock;

/* Default machine get_core_freq callback. */
static unsigned long get_core_freq_default(void)
{
#ifdef CONFIG_METAG_META21
	/*
	 * Meta 2 cores divide down the core clock for the Meta timers, so we
	 * can estimate the core clock from the divider.
	 */
	return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000;
#else
	/*
	 * On Meta 1 we don't know the core clock, but assuming the Meta timer
	 * is correct it can be estimated based on loops_per_jiffy.
	 */
	return (loops_per_jiffy * HZ * 5) >> 1;
#endif
}

/**
 * setup_meta_clocks() - Set up the Meta clock.
 * @desc:	Clock descriptor usually provided by machine description
 *
 * Ensures all callbacks are valid.
 */
void __init setup_meta_clocks(struct meta_clock_desc *desc)
{
	/* copy callbacks */
	if (desc)
		_meta_clock = *desc;

	/* set fallback functions */
	if (!_meta_clock.get_core_freq)
		_meta_clock.get_core_freq = get_core_freq_default;
}
Loading