All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomasz Figa <tomasz.figa@gmail.com>
To: linux-arm-kernel@lists.infradead.org
Cc: linux-samsung-soc@vger.kernel.org,
	"Kukjin Kim" <kgene.kim@samsung.com>,
	kyungmin.park@samsung.com, linux@simtec.co.uk,
	broonie@opensource.wolfsonmicro.com, kwangwoo.lee@gmail.com,
	jacmet@sunsite.dk, augulis.darius@gmail.com,
	mcuelenaere@gmail.com, linux@arm.linux.org.uk,
	"Sylwester Nawrocki" <sylvester.nawrocki@gmail.com>,
	buserror@gmail.com, christer@weinigel.se, jekhor@gmail.com,
	ghcstop@gmail.com, "Mark Rutland" <mark.rutland@arm.com>,
	"Tomasz Figa" <tomasz.figa@gmail.com>,
	"Heiko Stübner" <heiko@sntech.de>,
	"Rob Herring" <robherring2@gmail.com>
Subject: [PATCH v3 02/12] clocksource: samsung-time: Set platform-specific parameters at runtime
Date: Sat,  9 Mar 2013 21:23:11 +0100	[thread overview]
Message-ID: <1362860601-18464-3-git-send-email-tomasz.figa@gmail.com> (raw)
In-Reply-To: <1362860601-18464-1-git-send-email-tomasz.figa@gmail.com>

This patch removes static platform-specific defines from samsung-time
implementation and introduces an interface to configure
platform-specific timer parameters from platform code.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-exynos/mach-universal_c210.c        |  7 ++++
 arch/arm/mach-s3c24xx/common.c                    |  9 +++++
 arch/arm/mach-s3c64xx/common.c                    |  9 +++++
 arch/arm/mach-s5p64x0/common.c                    |  9 +++++
 arch/arm/mach-s5pc100/common.c                    |  9 +++++
 arch/arm/mach-s5pv210/common.c                    |  9 +++++
 arch/arm/plat-samsung/include/plat/samsung-time.h | 28 ++++++++-------
 drivers/clocksource/samsung-time.c                | 42 ++++++++++++++++++-----
 8 files changed, 101 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 72f08fd..00554fe 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1089,10 +1089,17 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s5p_device_fimc_md,
 };
 
+static const struct samsung_timer_variant universal_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 static void __init universal_map_io(void)
 {
 	exynos_init_io(NULL, 0);
 	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
+	samsung_timer_set_variant(&universal_timer_variant);
 	samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4);
 	xxti_f = 0;
 	xusbxti_f = 24000000;
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index d97533d..816428f 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -49,6 +49,7 @@
 #include <plat/clock.h>
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -216,6 +217,12 @@ static void s3c24xx_default_idle(void)
 		     S3C2410_CLKCON);
 }
 
+static const struct samsung_timer_variant s3c24xx_timer_variant = {
+	.bits = 16,
+	.prescale = 25,
+	.divisor = 2,
+};
+
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
 	arm_pm_idle = s3c24xx_default_idle;
@@ -232,6 +239,8 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	s3c24xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s3c24xx_timer_variant);
 }
 
 /* Serial port registrations */
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 0b9c0ba..b6aa36d 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -44,6 +44,7 @@
 #include <plat/irq-vic-timer.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -148,6 +149,12 @@ static struct device s3c64xx_dev = {
 	.bus	= &s3c64xx_subsys,
 };
 
+static const struct samsung_timer_variant s3c64xx_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -160,6 +167,8 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 	s3c64xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s3c64xx_timer_variant);
 }
 
 static __init int s3c64xx_dev_init(void)
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 8ae5800..a339fbb 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -48,6 +48,7 @@
 #include <plat/gpio-cfg.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -156,6 +157,12 @@ static void s5p64x0_idle(void)
 	cpu_do_idle();
 }
 
+static const struct samsung_timer_variant s5p64x0_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5p64x0_map_io
  *
@@ -173,6 +180,8 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P64X0_SYS_ID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5p64x0_timer_variant);
 }
 
 void __init s5p6440_map_io(void)
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index cc6e561..09e76d4 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -47,6 +47,7 @@
 #include <plat/onenand-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -131,6 +132,12 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
 	}
 };
 
+static const struct samsung_timer_variant s5pc100_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5pc100_map_io
  *
@@ -148,6 +155,8 @@ void __init s5pc100_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5pc100_timer_variant);
 }
 
 void __init s5pc100_map_io(void)
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 9dfe93e..44d3a5c 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -42,6 +42,7 @@
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
 #include <plat/keypad-core.h>
+#include <plat/samsung-time.h>
 #include <plat/tv-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
@@ -148,6 +149,12 @@ void s5pv210_restart(char mode, const char *cmd)
 	__raw_writel(0x1, S5P_SWRESET);
 }
 
+static const struct samsung_timer_variant s5pv210_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5pv210_map_io
  *
@@ -165,6 +172,8 @@ void __init s5pv210_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5pv210_timer_variant);
 }
 
 void __init s5pv210_map_io(void)
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
index 4cc99bb..09077f4 100644
--- a/arch/arm/plat-samsung/include/plat/samsung-time.h
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -27,26 +27,28 @@ struct samsung_timer_source {
 	unsigned int source_id;
 };
 
+/**
+ * struct samsung_timer_variant - SoC-specific parameters of Samsung PWM timers
+ * @bits:	bit width of time counters
+ * @prescale:	prescaler divisor
+ * @divisor:	main divisor
+ */
+struct samsung_timer_variant {
+	int bits;
+	u16 prescale;
+	u16 divisor;
+};
+
 /* Be able to sleep for atleast 4 seconds (usually more) */
 #define SAMSUNG_TIMER_MIN_RANGE	4
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
-#define TCNT_MAX		0xffff
-#define TSCALER_DIV		25
-#define TDIV			50
-#define TSIZE			16
-#else
-#define TCNT_MAX		0xffffffff
-#define TSCALER_DIV		2
-#define TDIV			2
-#define TSIZE			32
-#endif
-
 #define NON_PERIODIC		0
 #define PERIODIC		1
 
-extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
+extern void samsung_set_timer_source(enum samsung_timer_mode event,
 					enum samsung_timer_mode source);
+extern void samsung_timer_set_variant(
+				const struct samsung_timer_variant *variant);
 
 extern void __init samsung_timer_init(void);
 
diff --git a/drivers/clocksource/samsung-time.c b/drivers/clocksource/samsung-time.c
index f899cbc..2b617c4 100644
--- a/drivers/clocksource/samsung-time.c
+++ b/drivers/clocksource/samsung-time.c
@@ -33,6 +33,7 @@ static struct clk *tdiv_event;
 static struct clk *tdiv_source;
 static struct clk *timerclk;
 static struct samsung_timer_source timer_source;
+static struct samsung_timer_variant timer_variant;
 static unsigned long clock_count_per_tick;
 static void samsung_timer_resume(void);
 
@@ -213,12 +214,16 @@ static void samsung_set_mode(enum clock_event_mode mode,
 
 static void samsung_timer_resume(void)
 {
+	u32 tcnt_max;
+
+	tcnt_max = (1UL << timer_variant.bits) - 1;
+
 	/* event timer restart */
 	samsung_time_setup(timer_source.event_id, clock_count_per_tick);
 	samsung_time_start(timer_source.event_id, PERIODIC);
 
 	/* source timer restart */
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
+	samsung_time_setup(timer_source.source_id, tcnt_max);
 	samsung_time_start(timer_source.source_id, PERIODIC);
 }
 
@@ -232,6 +237,12 @@ void __init samsung_set_timer_source(enum samsung_timer_mode event,
 	timer_source.source_id = source;
 }
 
+void __init samsung_timer_set_variant(
+				const struct samsung_timer_variant *variant)
+{
+	timer_variant = *variant;
+}
+
 static struct clock_event_device time_event_device = {
 	.name		= "samsung_event_timer",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -267,8 +278,9 @@ static void __init samsung_clockevent_init(void)
 
 	tscaler = clk_get_parent(tdiv_event);
 
-	clk_set_rate(tscaler, pclk / TSCALER_DIV);
-	clk_set_rate(tdiv_event, pclk / TDIV);
+	clk_set_rate(tscaler, pclk / timer_variant.prescale);
+	clk_set_rate(tdiv_event, pclk /
+			(timer_variant.prescale * timer_variant.divisor));
 	clk_set_parent(tin_event, tdiv_event);
 
 	clock_rate = clk_get_rate(tin_event);
@@ -326,21 +338,29 @@ static void __init samsung_clocksource_init(void)
 {
 	unsigned long pclk;
 	unsigned long clock_rate;
+	u32 tcnt_max;
+	int ret;
+
+	tcnt_max = (1UL << timer_variant.bits) - 1;
 
 	pclk = clk_get_rate(timerclk);
 
-	clk_set_rate(tdiv_source, pclk / TDIV);
+	clk_set_rate(tdiv_source, pclk /
+			(timer_variant.prescale * timer_variant.divisor));
 	clk_set_parent(tin_source, tdiv_source);
 
 	clock_rate = clk_get_rate(tin_source);
 
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
+	samsung_time_setup(timer_source.source_id, tcnt_max);
 	samsung_time_start(timer_source.source_id, PERIODIC);
 
-	setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
+	setup_sched_clock(samsung_read_sched_clock,
+						timer_variant.bits, clock_rate);
 
-	if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
-			clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
+	ret = clocksource_mmio_init(samsung_timer_reg(),
+			"samsung_clocksource_timer", clock_rate, 250,
+			timer_variant.bits, clocksource_mmio_readl_down);
+	if (ret)
 		panic("samsung_clocksource_timer: can't register clocksource\n");
 }
 
@@ -388,6 +408,12 @@ static void __init samsung_timer_resources(void)
 
 void __init samsung_timer_init(void)
 {
+	if (!timer_source.source_id && !timer_source.event_id)
+		panic("timer sources not set (see samsung_set_timer_source)!\n");
+
+	if (!timer_variant.bits)
+		panic("timer variant not set (see samsung_timer_set_variant)!\n");
+
 	samsung_timer_resources();
 	samsung_clockevent_init();
 	samsung_clocksource_init();
-- 
1.8.1.5

WARNING: multiple messages have this Message-ID (diff)
From: tomasz.figa@gmail.com (Tomasz Figa)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 02/12] clocksource: samsung-time: Set platform-specific parameters at runtime
Date: Sat,  9 Mar 2013 21:23:11 +0100	[thread overview]
Message-ID: <1362860601-18464-3-git-send-email-tomasz.figa@gmail.com> (raw)
In-Reply-To: <1362860601-18464-1-git-send-email-tomasz.figa@gmail.com>

This patch removes static platform-specific defines from samsung-time
implementation and introduces an interface to configure
platform-specific timer parameters from platform code.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-exynos/mach-universal_c210.c        |  7 ++++
 arch/arm/mach-s3c24xx/common.c                    |  9 +++++
 arch/arm/mach-s3c64xx/common.c                    |  9 +++++
 arch/arm/mach-s5p64x0/common.c                    |  9 +++++
 arch/arm/mach-s5pc100/common.c                    |  9 +++++
 arch/arm/mach-s5pv210/common.c                    |  9 +++++
 arch/arm/plat-samsung/include/plat/samsung-time.h | 28 ++++++++-------
 drivers/clocksource/samsung-time.c                | 42 ++++++++++++++++++-----
 8 files changed, 101 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 72f08fd..00554fe 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1089,10 +1089,17 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s5p_device_fimc_md,
 };
 
+static const struct samsung_timer_variant universal_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 static void __init universal_map_io(void)
 {
 	exynos_init_io(NULL, 0);
 	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
+	samsung_timer_set_variant(&universal_timer_variant);
 	samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4);
 	xxti_f = 0;
 	xusbxti_f = 24000000;
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index d97533d..816428f 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -49,6 +49,7 @@
 #include <plat/clock.h>
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -216,6 +217,12 @@ static void s3c24xx_default_idle(void)
 		     S3C2410_CLKCON);
 }
 
+static const struct samsung_timer_variant s3c24xx_timer_variant = {
+	.bits = 16,
+	.prescale = 25,
+	.divisor = 2,
+};
+
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
 	arm_pm_idle = s3c24xx_default_idle;
@@ -232,6 +239,8 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	s3c24xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s3c24xx_timer_variant);
 }
 
 /* Serial port registrations */
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 0b9c0ba..b6aa36d 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -44,6 +44,7 @@
 #include <plat/irq-vic-timer.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -148,6 +149,12 @@ static struct device s3c64xx_dev = {
 	.bus	= &s3c64xx_subsys,
 };
 
+static const struct samsung_timer_variant s3c64xx_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -160,6 +167,8 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 	s3c64xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s3c64xx_timer_variant);
 }
 
 static __init int s3c64xx_dev_init(void)
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 8ae5800..a339fbb 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -48,6 +48,7 @@
 #include <plat/gpio-cfg.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -156,6 +157,12 @@ static void s5p64x0_idle(void)
 	cpu_do_idle();
 }
 
+static const struct samsung_timer_variant s5p64x0_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5p64x0_map_io
  *
@@ -173,6 +180,8 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P64X0_SYS_ID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5p64x0_timer_variant);
 }
 
 void __init s5p6440_map_io(void)
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index cc6e561..09e76d4 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -47,6 +47,7 @@
 #include <plat/onenand-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 #include <plat/watchdog-reset.h>
 
 #include "common.h"
@@ -131,6 +132,12 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
 	}
 };
 
+static const struct samsung_timer_variant s5pc100_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5pc100_map_io
  *
@@ -148,6 +155,8 @@ void __init s5pc100_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5pc100_timer_variant);
 }
 
 void __init s5pc100_map_io(void)
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 9dfe93e..44d3a5c 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -42,6 +42,7 @@
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
 #include <plat/keypad-core.h>
+#include <plat/samsung-time.h>
 #include <plat/tv-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
@@ -148,6 +149,12 @@ void s5pv210_restart(char mode, const char *cmd)
 	__raw_writel(0x1, S5P_SWRESET);
 }
 
+static const struct samsung_timer_variant s5pv210_timer_variant = {
+	.bits = 32,
+	.prescale = 2,
+	.divisor = 1,
+};
+
 /*
  * s5pv210_map_io
  *
@@ -165,6 +172,8 @@ void __init s5pv210_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_timer_set_variant(&s5pv210_timer_variant);
 }
 
 void __init s5pv210_map_io(void)
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
index 4cc99bb..09077f4 100644
--- a/arch/arm/plat-samsung/include/plat/samsung-time.h
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -27,26 +27,28 @@ struct samsung_timer_source {
 	unsigned int source_id;
 };
 
+/**
+ * struct samsung_timer_variant - SoC-specific parameters of Samsung PWM timers
+ * @bits:	bit width of time counters
+ * @prescale:	prescaler divisor
+ * @divisor:	main divisor
+ */
+struct samsung_timer_variant {
+	int bits;
+	u16 prescale;
+	u16 divisor;
+};
+
 /* Be able to sleep for atleast 4 seconds (usually more) */
 #define SAMSUNG_TIMER_MIN_RANGE	4
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
-#define TCNT_MAX		0xffff
-#define TSCALER_DIV		25
-#define TDIV			50
-#define TSIZE			16
-#else
-#define TCNT_MAX		0xffffffff
-#define TSCALER_DIV		2
-#define TDIV			2
-#define TSIZE			32
-#endif
-
 #define NON_PERIODIC		0
 #define PERIODIC		1
 
-extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
+extern void samsung_set_timer_source(enum samsung_timer_mode event,
 					enum samsung_timer_mode source);
+extern void samsung_timer_set_variant(
+				const struct samsung_timer_variant *variant);
 
 extern void __init samsung_timer_init(void);
 
diff --git a/drivers/clocksource/samsung-time.c b/drivers/clocksource/samsung-time.c
index f899cbc..2b617c4 100644
--- a/drivers/clocksource/samsung-time.c
+++ b/drivers/clocksource/samsung-time.c
@@ -33,6 +33,7 @@ static struct clk *tdiv_event;
 static struct clk *tdiv_source;
 static struct clk *timerclk;
 static struct samsung_timer_source timer_source;
+static struct samsung_timer_variant timer_variant;
 static unsigned long clock_count_per_tick;
 static void samsung_timer_resume(void);
 
@@ -213,12 +214,16 @@ static void samsung_set_mode(enum clock_event_mode mode,
 
 static void samsung_timer_resume(void)
 {
+	u32 tcnt_max;
+
+	tcnt_max = (1UL << timer_variant.bits) - 1;
+
 	/* event timer restart */
 	samsung_time_setup(timer_source.event_id, clock_count_per_tick);
 	samsung_time_start(timer_source.event_id, PERIODIC);
 
 	/* source timer restart */
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
+	samsung_time_setup(timer_source.source_id, tcnt_max);
 	samsung_time_start(timer_source.source_id, PERIODIC);
 }
 
@@ -232,6 +237,12 @@ void __init samsung_set_timer_source(enum samsung_timer_mode event,
 	timer_source.source_id = source;
 }
 
+void __init samsung_timer_set_variant(
+				const struct samsung_timer_variant *variant)
+{
+	timer_variant = *variant;
+}
+
 static struct clock_event_device time_event_device = {
 	.name		= "samsung_event_timer",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -267,8 +278,9 @@ static void __init samsung_clockevent_init(void)
 
 	tscaler = clk_get_parent(tdiv_event);
 
-	clk_set_rate(tscaler, pclk / TSCALER_DIV);
-	clk_set_rate(tdiv_event, pclk / TDIV);
+	clk_set_rate(tscaler, pclk / timer_variant.prescale);
+	clk_set_rate(tdiv_event, pclk /
+			(timer_variant.prescale * timer_variant.divisor));
 	clk_set_parent(tin_event, tdiv_event);
 
 	clock_rate = clk_get_rate(tin_event);
@@ -326,21 +338,29 @@ static void __init samsung_clocksource_init(void)
 {
 	unsigned long pclk;
 	unsigned long clock_rate;
+	u32 tcnt_max;
+	int ret;
+
+	tcnt_max = (1UL << timer_variant.bits) - 1;
 
 	pclk = clk_get_rate(timerclk);
 
-	clk_set_rate(tdiv_source, pclk / TDIV);
+	clk_set_rate(tdiv_source, pclk /
+			(timer_variant.prescale * timer_variant.divisor));
 	clk_set_parent(tin_source, tdiv_source);
 
 	clock_rate = clk_get_rate(tin_source);
 
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
+	samsung_time_setup(timer_source.source_id, tcnt_max);
 	samsung_time_start(timer_source.source_id, PERIODIC);
 
-	setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
+	setup_sched_clock(samsung_read_sched_clock,
+						timer_variant.bits, clock_rate);
 
-	if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
-			clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
+	ret = clocksource_mmio_init(samsung_timer_reg(),
+			"samsung_clocksource_timer", clock_rate, 250,
+			timer_variant.bits, clocksource_mmio_readl_down);
+	if (ret)
 		panic("samsung_clocksource_timer: can't register clocksource\n");
 }
 
@@ -388,6 +408,12 @@ static void __init samsung_timer_resources(void)
 
 void __init samsung_timer_init(void)
 {
+	if (!timer_source.source_id && !timer_source.event_id)
+		panic("timer sources not set (see samsung_set_timer_source)!\n");
+
+	if (!timer_variant.bits)
+		panic("timer variant not set (see samsung_timer_set_variant)!\n");
+
 	samsung_timer_resources();
 	samsung_clockevent_init();
 	samsung_clocksource_init();
-- 
1.8.1.5

  parent reply	other threads:[~2013-03-09 20:23 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-09 20:23 [PATCH v3 00/12] ARM: samsung-time: Prepare for multiplatform support Tomasz Figa
2013-03-09 20:23 ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 01/12] ARM: SAMSUNG: Move samsung-time to drivers/clocksource Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` Tomasz Figa [this message]
2013-03-09 20:23   ` [PATCH v3 02/12] clocksource: samsung-time: Set platform-specific parameters at runtime Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 03/12] clocksource: samsung-time: Drop useless defines from public header Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 04/12] ARM: SAMSUNG: Move samsung-time.h header to inlude/clocksource Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 05/12] clocksource: samsung-time: Use local register definitions Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 06/12] clocksource: samsung-time: Remove use of static register mapping Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 07/12] clocksource: samsung-time: Use clk_get_sys for getting clocks Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 08/12] ARM: SAMSUNG: devs: Drop unnecessary IRQ resources of timer devices Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 09/12] clocksource: samsung-time: Do not use static IRQ definition Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 10/12] clocksource: samsung-time: Move IRQ mask/ack handling to the driver Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 11/12] ARM: SAMSUNG: Remove unused PWM timer IRQ chip code Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-09 20:23 ` [PATCH v3 12/12] clocksource: samsung-time: Add Device Tree support Tomasz Figa
2013-03-09 20:23   ` Tomasz Figa
2013-03-28 12:30   ` Mark Brown
2013-03-28 12:30     ` Mark Brown
2013-03-23 12:27 ` [PATCH v3 00/12] ARM: samsung-time: Prepare for multiplatform support Tomasz Figa
2013-03-23 12:27   ` Tomasz Figa
2013-03-28 13:02 ` Mark Brown
2013-03-28 13:02   ` Mark Brown
2013-03-28 22:29 ` Tomasz Figa
2013-03-28 22:29   ` Tomasz Figa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1362860601-18464-3-git-send-email-tomasz.figa@gmail.com \
    --to=tomasz.figa@gmail.com \
    --cc=augulis.darius@gmail.com \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=buserror@gmail.com \
    --cc=christer@weinigel.se \
    --cc=ghcstop@gmail.com \
    --cc=heiko@sntech.de \
    --cc=jacmet@sunsite.dk \
    --cc=jekhor@gmail.com \
    --cc=kgene.kim@samsung.com \
    --cc=kwangwoo.lee@gmail.com \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=linux@simtec.co.uk \
    --cc=mark.rutland@arm.com \
    --cc=mcuelenaere@gmail.com \
    --cc=robherring2@gmail.com \
    --cc=sylvester.nawrocki@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.