Commit c8987470 authored by Changhwan Youn's avatar Changhwan Youn Committed by Kukjin Kim

ARM: EXYNOS4: Add MCT support for EXYNOS4412

Current MCT implementation only provide 2 event timers,
thus cannot support EXYNOS4412 which has 4 CPU cores.
This patch fixes MCT implementation to support SoCs
with 4 cores.
Signed-off-by: default avatarChanghwan Youn <chaos.youn@samsung.com>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent 90a454b4
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) #define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) #define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
#define EXYNOS4_MCT_L0_BASE EXYNOS4_MCTREG(0x300) #define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300)
#define EXYNOS4_MCT_L1_BASE EXYNOS4_MCTREG(0x400) #define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x))
#define EXYNOS4_MCT_L_MASK (0xffffff00)
#define MCT_L_TCNTB_OFFSET (0x00) #define MCT_L_TCNTB_OFFSET (0x00)
#define MCT_L_ICNTB_OFFSET (0x08) #define MCT_L_ICNTB_OFFSET (0x08)
......
...@@ -41,9 +41,10 @@ static unsigned int mct_int_type; ...@@ -41,9 +41,10 @@ static unsigned int mct_int_type;
struct mct_clock_event_device { struct mct_clock_event_device {
struct clock_event_device *evt; struct clock_event_device *evt;
void __iomem *base; void __iomem *base;
char name[10];
}; };
struct mct_clock_event_device mct_tick[2]; struct mct_clock_event_device mct_tick[NR_CPUS];
static void exynos4_mct_write(unsigned int value, void *addr) static void exynos4_mct_write(unsigned int value, void *addr)
{ {
...@@ -53,57 +54,53 @@ static void exynos4_mct_write(unsigned int value, void *addr) ...@@ -53,57 +54,53 @@ static void exynos4_mct_write(unsigned int value, void *addr)
__raw_writel(value, addr); __raw_writel(value, addr);
switch ((u32) addr) { if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) {
case (u32) EXYNOS4_MCT_G_TCON: u32 base = (u32) addr & EXYNOS4_MCT_L_MASK;
stat_addr = EXYNOS4_MCT_G_WSTAT; switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) {
mask = 1 << 16; /* G_TCON write status */ case (u32) MCT_L_TCON_OFFSET:
break; stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
case (u32) EXYNOS4_MCT_G_COMP0_L: mask = 1 << 3; /* L_TCON write status */
stat_addr = EXYNOS4_MCT_G_WSTAT; break;
mask = 1 << 0; /* G_COMP0_L write status */ case (u32) MCT_L_ICNTB_OFFSET:
break; stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
case (u32) EXYNOS4_MCT_G_COMP0_U: mask = 1 << 1; /* L_ICNTB write status */
stat_addr = EXYNOS4_MCT_G_WSTAT; break;
mask = 1 << 1; /* G_COMP0_U write status */ case (u32) MCT_L_TCNTB_OFFSET:
break; stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR: mask = 1 << 0; /* L_TCNTB write status */
stat_addr = EXYNOS4_MCT_G_WSTAT; break;
mask = 1 << 2; /* G_COMP0_ADD_INCR write status */ default:
break; return;
case (u32) EXYNOS4_MCT_G_CNT_L: }
stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; } else {
mask = 1 << 0; /* G_CNT_L write status */ switch ((u32) addr) {
break; case (u32) EXYNOS4_MCT_G_TCON:
case (u32) EXYNOS4_MCT_G_CNT_U: stat_addr = EXYNOS4_MCT_G_WSTAT;
stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; mask = 1 << 16; /* G_TCON write status */
mask = 1 << 1; /* G_CNT_U write status */ break;
break; case (u32) EXYNOS4_MCT_G_COMP0_L:
case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCON_OFFSET): stat_addr = EXYNOS4_MCT_G_WSTAT;
stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; mask = 1 << 0; /* G_COMP0_L write status */
mask = 1 << 3; /* L0_TCON write status */ break;
break; case (u32) EXYNOS4_MCT_G_COMP0_U:
case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCON_OFFSET): stat_addr = EXYNOS4_MCT_G_WSTAT;
stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; mask = 1 << 1; /* G_COMP0_U write status */
mask = 1 << 3; /* L1_TCON write status */ break;
break; case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCNTB_OFFSET): stat_addr = EXYNOS4_MCT_G_WSTAT;
stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; mask = 1 << 2; /* G_COMP0_ADD_INCR w status */
mask = 1 << 0; /* L0_TCNTB write status */ break;
break; case (u32) EXYNOS4_MCT_G_CNT_L:
case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCNTB_OFFSET): stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; mask = 1 << 0; /* G_CNT_L write status */
mask = 1 << 0; /* L1_TCNTB write status */ break;
break; case (u32) EXYNOS4_MCT_G_CNT_U:
case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_ICNTB_OFFSET): stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; mask = 1 << 1; /* G_CNT_U write status */
mask = 1 << 1; /* L0_ICNTB write status */ break;
break; default:
case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_ICNTB_OFFSET): return;
stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; }
mask = 1 << 1; /* L1_ICNTB write status */
break;
default:
return;
} }
/* Wait maximum 1 ms until written values are applied */ /* Wait maximum 1 ms until written values are applied */
...@@ -332,7 +329,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, ...@@ -332,7 +329,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
} }
} }
static inline int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
{ {
struct clock_event_device *evt = mevt->evt; struct clock_event_device *evt = mevt->evt;
...@@ -383,14 +380,10 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) ...@@ -383,14 +380,10 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
mct_tick[cpu].evt = evt; mct_tick[cpu].evt = evt;
if (cpu == 0) { mct_tick[cpu].base = EXYNOS4_MCT_L_BASE(cpu);
mct_tick[cpu].base = EXYNOS4_MCT_L0_BASE; sprintf(mct_tick[cpu].name, "mct_tick%d", cpu);
evt->name = "mct_tick0";
} else {
mct_tick[cpu].base = EXYNOS4_MCT_L1_BASE;
evt->name = "mct_tick1";
}
evt->name = mct_tick[cpu].name;
evt->cpumask = cpumask_of(cpu); evt->cpumask = cpumask_of(cpu);
evt->set_next_event = exynos4_tick_set_next_event; evt->set_next_event = exynos4_tick_set_next_event;
evt->set_mode = exynos4_tick_set_mode; evt->set_mode = exynos4_tick_set_mode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment