Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 372405
b: refs/heads/master
c: 36ba5d5
h: refs/heads/master
i:
  372403: af5aa1d
v: v3
  • Loading branch information
Thomas Abraham authored and Kukjin Kim committed Mar 9, 2013
1 parent 3c9efd5 commit 7535954
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c371dc60aebf7ada4d5b4585ea8f46a3a06f8f04
refs/heads/master: 36ba5d527e9567ed303bad6e86a5f3c2723470f6
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Samsung's Multi Core Timer (MCT)

The Samsung's Multi Core Timer (MCT) module includes two main blocks, the
global timer and CPU local timers. The global timer is a 64-bit free running
up-counter and can generate 4 interrupts when the counter reaches one of the
four preset counter values. The CPU local timers are 32-bit free running
down-counters and generate an interrupt when the counter expires. There is
one CPU local timer instantiated in MCT for every CPU in the system.

Required properties:

- compatible: should be "samsung,exynos4210-mct".
(a) "samsung,exynos4210-mct", for mct compatible with Exynos4210 mct.
(b) "samsung,exynos4412-mct", for mct compatible with Exynos4412 mct.

- reg: base address of the mct controller and length of the address space
it occupies.

- interrupts: the list of interrupts generated by the controller. The following
should be the order of the interrupts specified. The local timer interrupts
should be specified after the four global timer interrupts have been
specified.

0: Global Timer Interrupt 0
1: Global Timer Interrupt 1
2: Global Timer Interrupt 2
3: Global Timer Interrupt 3
4: Local Timer Interrupt 0
5: Local Timer Interrupt 1
6: ..
7: ..
i: Local Timer Interrupt n

Example 1: In this example, the system uses only the first global timer
interrupt generated by MCT and the remaining three global timer
interrupts are unused. Two local timer interrupts have been
specified.

mct@10050000 {
compatible = "samsung,exynos4210-mct";
reg = <0x10050000 0x800>;
interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>,
<0 42 0>, <0 48 0>;
};

Example 2: In this example, the MCT global and local timer interrupts are
connected to two seperate interrupt controllers. Hence, an
interrupt-map is created to map the interrupts to the respective
interrupt controllers.

mct@101C0000 {
compatible = "samsung,exynos4210-mct";
reg = <0x101C0000 0x800>;
interrupt-controller;
#interrups-cells = <2>;
interrupt-parent = <&mct_map>;
interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
<4 0>, <5 0>;

mct_map: mct-map {
#interrupt-cells = <2>;
#address-cells = <0>;
#size-cells = <0>;
interrupt-map = <0x0 0 &combiner 23 3>,
<0x4 0 &gic 0 120 0>,
<0x5 0 &gic 0 121 0>;
};
};
6 changes: 0 additions & 6 deletions trunk/arch/arm/mach-exynos/include/mach/irqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@

/* For EXYNOS4 and EXYNOS5 */

#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12)

#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32)

/* For EXYNOS4 SoCs */
Expand Down Expand Up @@ -323,8 +321,6 @@
#define EXYNOS5_IRQ_CEC IRQ_SPI(114)
#define EXYNOS5_IRQ_SATA IRQ_SPI(115)

#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120)
#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)
#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)
#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)
#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)
Expand Down Expand Up @@ -419,8 +415,6 @@
#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)

#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0)
#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3)
#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)

#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)
#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
Expand Down
49 changes: 37 additions & 12 deletions trunk/arch/arm/mach-exynos/mct.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <linux/delay.h>
#include <linux/percpu.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>

#include <asm/arch_timer.h>
#include <asm/localtimer.h>
Expand Down Expand Up @@ -474,14 +476,16 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
};
#endif /* CONFIG_LOCAL_TIMERS */

static void __init exynos4_timer_resources(void)
static void __init exynos4_timer_resources(struct device_node *np)
{
struct clk *mct_clk;
mct_clk = clk_get(NULL, "xtal");

clk_rate = clk_get_rate(mct_clk);

reg_base = S5P_VA_SYSTIMER;
reg_base = np ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
if (!reg_base)
panic("%s: unable to ioremap mct address space\n", __func__);

#ifdef CONFIG_LOCAL_TIMERS
if (mct_int_type == MCT_INT_PPI) {
Expand All @@ -498,30 +502,51 @@ static void __init exynos4_timer_resources(void)
#endif /* CONFIG_LOCAL_TIMERS */
}

static const struct of_device_id exynos_mct_ids[] = {
{ .compatible = "samsung,exynos4210-mct", .data = (void *)MCT_INT_SPI },
{ .compatible = "samsung,exynos4412-mct", .data = (void *)MCT_INT_PPI },
};

void __init exynos4_timer_init(void)
{
struct device_node *np = NULL;
const struct of_device_id *match;
u32 nr_irqs, i;

if (soc_is_exynos5440()) {
arch_timer_of_register();
return;
}

if (soc_is_exynos4210()) {
#ifdef CONFIG_OF
np = of_find_matching_node_and_match(NULL, exynos_mct_ids, &match);
#endif
if (np) {
mct_int_type = (u32)(match->data);

/* This driver uses only one global timer interrupt */
mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);

/*
* Find out the number of local irqs specified. The local
* timer irqs are specified after the four global timer
* irqs are specified.
*/
#ifdef CONFIG_OF
nr_irqs = of_irq_count(np);
#endif
for (i = MCT_L0_IRQ; i < nr_irqs; i++)
mct_irqs[i] = irq_of_parse_and_map(np, i);
} else if (soc_is_exynos4210()) {
mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0;
mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1;
mct_int_type = MCT_INT_SPI;
} else if (soc_is_exynos5250()) {
mct_irqs[MCT_G0_IRQ] = EXYNOS5_IRQ_MCT_G0;
mct_irqs[MCT_L0_IRQ] = EXYNOS5_IRQ_MCT_L0;
mct_irqs[MCT_L1_IRQ] = EXYNOS5_IRQ_MCT_L1;
mct_int_type = MCT_INT_SPI;
} else {
mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
mct_irqs[MCT_L0_IRQ] = EXYNOS_IRQ_MCT_LOCALTIMER;
mct_int_type = MCT_INT_PPI;
panic("unable to determine mct controller type\n");
}

exynos4_timer_resources();
exynos4_timer_resources(np);
exynos4_clocksource_init();
exynos4_clockevent_init();
}

0 comments on commit 7535954

Please sign in to comment.