diff options
| -rw-r--r-- | MAINTAINERS | 1 | ||||
| -rw-r--r-- | arch/metag/include/asm/clock.h | 51 | ||||
| -rw-r--r-- | arch/metag/include/asm/delay.h | 29 | ||||
| -rw-r--r-- | arch/metag/include/asm/mach/arch.h | 4 | ||||
| -rw-r--r-- | arch/metag/kernel/clock.c | 53 | ||||
| -rw-r--r-- | arch/metag/kernel/time.c | 15 | ||||
| -rw-r--r-- | drivers/clocksource/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clocksource/metag_generic.c | 198 | ||||
| -rw-r--r-- | include/clocksource/metag_generic.h | 21 |
10 files changed, 378 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 401145d7c5bb..749d76699ead 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -5039,6 +5039,7 @@ S: Supported | |||
| 5039 | F: arch/metag/ | 5039 | F: arch/metag/ |
| 5040 | F: Documentation/metag/ | 5040 | F: Documentation/metag/ |
| 5041 | F: Documentation/devicetree/bindings/metag/ | 5041 | F: Documentation/devicetree/bindings/metag/ |
| 5042 | F: drivers/clocksource/metag_generic.c | ||
| 5042 | 5043 | ||
| 5043 | MICROBLAZE ARCHITECTURE | 5044 | MICROBLAZE ARCHITECTURE |
| 5044 | M: Michal Simek <monstr@monstr.eu> | 5045 | M: Michal Simek <monstr@monstr.eu> |
diff --git a/arch/metag/include/asm/clock.h b/arch/metag/include/asm/clock.h new file mode 100644 index 000000000000..3e2915a280c7 --- /dev/null +++ b/arch/metag/include/asm/clock.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | * arch/metag/include/asm/clock.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Imagination Technologies Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _METAG_CLOCK_H_ | ||
| 12 | #define _METAG_CLOCK_H_ | ||
| 13 | |||
| 14 | #include <asm/mach/arch.h> | ||
| 15 | |||
| 16 | /** | ||
| 17 | * struct meta_clock_desc - Meta Core clock callbacks. | ||
| 18 | * @get_core_freq: Get the frequency of the Meta core. If this is NULL, the | ||
| 19 | * core frequency will be determined like this: | ||
| 20 | * Meta 1: based on loops_per_jiffy. | ||
| 21 | * Meta 2: (EXPAND_TIMER_DIV + 1) MHz. | ||
| 22 | */ | ||
| 23 | struct meta_clock_desc { | ||
| 24 | unsigned long (*get_core_freq)(void); | ||
| 25 | }; | ||
| 26 | |||
| 27 | extern struct meta_clock_desc _meta_clock; | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Set up the default clock, ensuring all callbacks are valid - only accessible | ||
| 31 | * during boot. | ||
| 32 | */ | ||
| 33 | void setup_meta_clocks(struct meta_clock_desc *desc); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * get_coreclock() - Get the frequency of the Meta core clock. | ||
| 37 | * | ||
| 38 | * Returns: The Meta core clock frequency in Hz. | ||
| 39 | */ | ||
| 40 | static inline unsigned long get_coreclock(void) | ||
| 41 | { | ||
| 42 | /* | ||
| 43 | * Use the current clock callback. If set correctly this will provide | ||
| 44 | * the most accurate frequency as it can be calculated directly from the | ||
| 45 | * PLL configuration. otherwise a default callback will have been set | ||
| 46 | * instead. | ||
| 47 | */ | ||
| 48 | return _meta_clock.get_core_freq(); | ||
| 49 | } | ||
| 50 | |||
| 51 | #endif /* _METAG_CLOCK_H_ */ | ||
diff --git a/arch/metag/include/asm/delay.h b/arch/metag/include/asm/delay.h new file mode 100644 index 000000000000..9c92f996957a --- /dev/null +++ b/arch/metag/include/asm/delay.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #ifndef _METAG_DELAY_H | ||
| 2 | #define _METAG_DELAY_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (C) 1993 Linus Torvalds | ||
| 6 | * | ||
| 7 | * Delay routines calling functions in arch/metag/lib/delay.c | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* Undefined functions to get compile-time errors */ | ||
| 11 | extern void __bad_udelay(void); | ||
| 12 | extern void __bad_ndelay(void); | ||
| 13 | |||
| 14 | extern void __udelay(unsigned long usecs); | ||
| 15 | extern void __ndelay(unsigned long nsecs); | ||
| 16 | extern void __const_udelay(unsigned long xloops); | ||
| 17 | extern void __delay(unsigned long loops); | ||
| 18 | |||
| 19 | /* 0x10c7 is 2**32 / 1000000 (rounded up) */ | ||
| 20 | #define udelay(n) (__builtin_constant_p(n) ? \ | ||
| 21 | ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ | ||
| 22 | __udelay(n)) | ||
| 23 | |||
| 24 | /* 0x5 is 2**32 / 1000000000 (rounded up) */ | ||
| 25 | #define ndelay(n) (__builtin_constant_p(n) ? \ | ||
| 26 | ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ | ||
| 27 | __ndelay(n)) | ||
| 28 | |||
| 29 | #endif /* _METAG_DELAY_H */ | ||
diff --git a/arch/metag/include/asm/mach/arch.h b/arch/metag/include/asm/mach/arch.h index 6845d80857e4..12c5664fea6e 100644 --- a/arch/metag/include/asm/mach/arch.h +++ b/arch/metag/include/asm/mach/arch.h | |||
| @@ -16,10 +16,13 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/stddef.h> | 17 | #include <linux/stddef.h> |
| 18 | 18 | ||
| 19 | #include <asm/clock.h> | ||
| 20 | |||
| 19 | /** | 21 | /** |
| 20 | * struct machine_desc - Describes a board controlled by a Meta. | 22 | * struct machine_desc - Describes a board controlled by a Meta. |
| 21 | * @name: Board/SoC name. | 23 | * @name: Board/SoC name. |
| 22 | * @dt_compat: Array of device tree 'compatible' strings. | 24 | * @dt_compat: Array of device tree 'compatible' strings. |
| 25 | * @clocks: Clock callbacks. | ||
| 23 | * | 26 | * |
| 24 | * @nr_irqs: Maximum number of IRQs. | 27 | * @nr_irqs: Maximum number of IRQs. |
| 25 | * If 0, defaults to NR_IRQS in asm-generic/irq.h. | 28 | * If 0, defaults to NR_IRQS in asm-generic/irq.h. |
| @@ -37,6 +40,7 @@ | |||
| 37 | struct machine_desc { | 40 | struct machine_desc { |
| 38 | const char *name; | 41 | const char *name; |
| 39 | const char **dt_compat; | 42 | const char **dt_compat; |
| 43 | struct meta_clock_desc *clocks; | ||
| 40 | 44 | ||
| 41 | unsigned int nr_irqs; | 45 | unsigned int nr_irqs; |
| 42 | 46 | ||
diff --git a/arch/metag/kernel/clock.c b/arch/metag/kernel/clock.c new file mode 100644 index 000000000000..defc84056f18 --- /dev/null +++ b/arch/metag/kernel/clock.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* | ||
| 2 | * arch/metag/kernel/clock.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Imagination Technologies Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/delay.h> | ||
| 12 | #include <linux/io.h> | ||
| 13 | |||
| 14 | #include <asm/param.h> | ||
| 15 | #include <asm/clock.h> | ||
| 16 | |||
| 17 | struct meta_clock_desc _meta_clock; | ||
| 18 | |||
| 19 | /* Default machine get_core_freq callback. */ | ||
| 20 | static unsigned long get_core_freq_default(void) | ||
| 21 | { | ||
| 22 | #ifdef CONFIG_METAG_META21 | ||
| 23 | /* | ||
| 24 | * Meta 2 cores divide down the core clock for the Meta timers, so we | ||
| 25 | * can estimate the core clock from the divider. | ||
| 26 | */ | ||
| 27 | return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000; | ||
| 28 | #else | ||
| 29 | /* | ||
| 30 | * On Meta 1 we don't know the core clock, but assuming the Meta timer | ||
| 31 | * is correct it can be estimated based on loops_per_jiffy. | ||
| 32 | */ | ||
| 33 | return (loops_per_jiffy * HZ * 5) >> 1; | ||
| 34 | #endif | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * setup_meta_clocks() - Set up the Meta clock. | ||
| 39 | * @desc: Clock descriptor usually provided by machine description | ||
| 40 | * | ||
| 41 | * Ensures all callbacks are valid. | ||
| 42 | */ | ||
| 43 | void __init setup_meta_clocks(struct meta_clock_desc *desc) | ||
| 44 | { | ||
| 45 | /* copy callbacks */ | ||
| 46 | if (desc) | ||
| 47 | _meta_clock = *desc; | ||
| 48 | |||
| 49 | /* set fallback functions */ | ||
| 50 | if (!_meta_clock.get_core_freq) | ||
| 51 | _meta_clock.get_core_freq = get_core_freq_default; | ||
| 52 | } | ||
| 53 | |||
diff --git a/arch/metag/kernel/time.c b/arch/metag/kernel/time.c new file mode 100644 index 000000000000..17dc10733b2f --- /dev/null +++ b/arch/metag/kernel/time.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2013 Imagination Technologies Ltd. | ||
| 3 | * | ||
| 4 | * This file contains the Meta-specific time handling details. | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/init.h> | ||
