From patchwork Sat Mar 9 20:23:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 2242421 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 249DBDF2F2 for ; Sat, 9 Mar 2013 20:27:53 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UEQJB-0004SR-BF; Sat, 09 Mar 2013 20:23:57 +0000 Received: from mail-wi0-x230.google.com ([2a00:1450:400c:c05::230]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UEQIx-0004Q3-Gv for linux-arm-kernel@lists.infradead.org; Sat, 09 Mar 2013 20:23:48 +0000 Received: by mail-wi0-f176.google.com with SMTP id hm14so296475wib.3 for ; Sat, 09 Mar 2013 12:23:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=MDTxi/yaBY2eo5YXdCdhPi1BTTfBw0nxkU+aY1CdBMY=; b=tfVkFQFqBRirJ2z+OBEFtveB2mkZSdAQvZ69rwn91KZHuftSfvsjXfg1ASk7w/WQbf OUzmNXPokw9lj+w/nHBQjYE5bO+BjtlWGlE2tcXxvvHUGHRZtB7yVU8mkVZFjhBYhTHo X/+pRPO9FYm+sRpTCvdNIlBxYegTKDuVIKUn9/7ycu6SubYsWBFjPv4B8FrJmZiV3igB JaTNdICmtue1jMcugWDAZAOpApFAZM8ysgJWr663cy/Fa4Kzv3AAyQo0mEESFkEfhelP Y6Q/8xpZCKX3Tppyq/wkFtkNQD9P+wfhu+NotQf5cDyf+rdekfMga8mLgMPbRkhbhHxM kVYA== X-Received: by 10.180.24.229 with SMTP id x5mr4933985wif.17.1362860621292; Sat, 09 Mar 2013 12:23:41 -0800 (PST) Received: from flatron.tomeq (87-207-52-162.dynamic.chello.pl. [87.207.52.162]) by mx.google.com with ESMTPS id ed6sm6858911wib.9.2013.03.09.12.23.39 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 09 Mar 2013 12:23:40 -0800 (PST) From: 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 Message-Id: <1362860601-18464-3-git-send-email-tomasz.figa@gmail.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1362860601-18464-1-git-send-email-tomasz.figa@gmail.com> References: <1362860601-18464-1-git-send-email-tomasz.figa@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130309_152344_120847_2EE23DB2 X-CRM114-Status: GOOD ( 18.17 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (tomasz.figa[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: ghcstop@gmail.com, Mark Rutland , Kukjin Kim , linux@arm.linux.org.uk, =?UTF-8?q?Heiko=20St=C3=BCbner?= , kwangwoo.lee@gmail.com, broonie@opensource.wolfsonmicro.com, mcuelenaere@gmail.com, Tomasz Figa , christer@weinigel.se, kyungmin.park@samsung.com, linux-samsung-soc@vger.kernel.org, buserror@gmail.com, augulis.darius@gmail.com, jacmet@sunsite.dk, Sylwester Nawrocki , linux@simtec.co.uk, jekhor@gmail.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 --- 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 #include #include +#include #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 #include #include +#include #include #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 #include #include +#include #include #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 #include #include +#include #include #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 #include #include +#include #include #include #include @@ -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();