From patchwork Fri Apr 12 19:17:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 2437841 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork2.kernel.org (Postfix) with ESMTP id 37327DF2A1 for ; Fri, 12 Apr 2013 20:07:12 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UQjXL-00059K-EL; Fri, 12 Apr 2013 19:21:29 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UQjWA-0002Su-Mc; Fri, 12 Apr 2013 19:20:14 +0000 Received: from mailout2.samsung.com ([203.254.224.25]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UQjVH-0002OT-IJ for linux-arm-kernel@lists.infradead.org; Fri, 12 Apr 2013 19:19:22 +0000 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0ML5002KYPO6Z420@mailout2.samsung.com> for linux-arm-kernel@lists.infradead.org; Sat, 13 Apr 2013 04:19:18 +0900 (KST) X-AuditID: cbfee61b-b7f076d0000034b6-14-51685e36a203 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 74.BC.13494.63E58615; Sat, 13 Apr 2013 04:19:18 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0ML500CT6PL8T090@mmp2.samsung.com>; Sat, 13 Apr 2013 04:19:18 +0900 (KST) From: Tomasz Figa To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v5 11/14] clocksource: samsung-pwm: Configure dividers directly Date: Fri, 12 Apr 2013 21:17:27 +0200 Message-id: <1365794250-14436-12-git-send-email-t.figa@samsung.com> X-Mailer: git-send-email 1.7.10 In-reply-to: <1365794250-14436-1-git-send-email-t.figa@samsung.com> References: <1365794250-14436-1-git-send-email-t.figa@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrAIsWRmVeSWpSXmKPExsVy+t9jQV2zuIxAg/XvRC3+TjrGbrH37T9G i3+zT7FZ3Pr8iN1i48qPbBYHZj9ktTjaY2fx/9FrVovTl64xWhxct5TV4sxvXYveBVfZLFZs vcBicbbpDbvFpsfXWC1mnN/HZHH7Mq/F722NLBZrj9xlt1h6/SKTxaV5TSwW3799Y7OY93kn k8X6Ga9ZLDZvmspssWrXH0YHKY8189YwerQ097B5/P41idFj56y77B53ru1h83h37hy7x+Yl 9R7nZyxk9Hg58TebR9+WVYwe599MZfHYfm0es8e01+fZPD5vkvN4fWM2YwB/FJdNSmpOZllq kb5dAlfG45vTWQq+aFecm93O3sD4SKWLkYNDQsBEYsJ6iy5GTiBTTOLCvfVsXYxcHEIC0xkl vvQ8Y4JwupgkltydyAxSxSagJvG54REbiC0ioCExpesxO0gRs8AnFomN/6awgUwVFvCXOP/B CKSGRUBV4sP5ZSwgNq+As8SvS49YIbbJSzy93wc2hxMoPvnuMzBbSMBJon9jP+MERt4FjAyr GEVTC5ILipPSc430ihNzi0vz0vWS83M3MYLj7Zn0DsZVDRaHGAU4GJV4eDOkMgKFWBPLiitz DzFKcDArifDG7E0LFOJNSaysSi3Kjy8qzUktPsQozcGiJM57sNU6UEggPbEkNTs1tSC1CCbL xMEp1cBoufbWlMvzNd3utOssqb4w+dj61w0dGiVr99s+rw8y6Tu4LSLiqN6PBYxu7StsdHlz WSa/ZNg7K3dtRcJhwayoyZYH/wvtYD/w5vpjloWidgnbH4dvyOV+Ok/wifXtWCddo6MXunPT edxSFHIn/hSI+Nbk/Gbl1lJjB7ktIkWPg0sOLZ/93ddZiaU4I9FQi7moOBEAz/MNxrMCAAA= X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130412_151920_186971_0C1F9F91 X-CRM114-Status: GOOD ( 11.75 ) X-Spam-Score: -7.5 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [203.254.224.25 listed in list.dnswl.org] 1.7 KHOP_BIG_TO_CC Sent to 10+ recipients instaed of Bcc or a list -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -2.4 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: mark.rutland@arm.com, heiko@sntech.de, Tomasz Figa , tomasz.figa@gmail.com, buserror@gmail.com, jacmet@sunsite.dk, augulis.darius@gmail.com, christer@weinigel.se, sylvester.nawrocki@gmail.com, m.szyprowski@samsung.com, kgene.kim@samsung.com, linux@arm.linux.org.uk, kwangwoo.lee@gmail.com, mcuelenaere@gmail.com, arnd@arndb.de, devicetree-discuss@lists.ozlabs.org, linux-samsung-soc@vger.kernel.org, john.stultz@linaro.org, ghcstop@gmail.com, linux@simtec.co.uk, broonie@opensource.wolfsonmicro.com, jekhor@gmail.com, kyungmin.park@samsung.com, tglx@linutronix.de 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 Clock dividers present in the PWM blocks are used to generate signal for PWM timers internally, so there is no need to export them using clock API. This patch moves handling of those dividers to the clocksource driver to not use the clock API anymore. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park --- drivers/clocksource/samsung_pwm.c | 111 ++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/drivers/clocksource/samsung_pwm.c b/drivers/clocksource/samsung_pwm.c index 3219ecc..29b480a 100644 --- a/drivers/clocksource/samsung_pwm.c +++ b/drivers/clocksource/samsung_pwm.c @@ -277,6 +277,15 @@ EXPORT_SYMBOL(samsung_pwm_get); * Clocksource driver */ +#define REG_TCFG0 0x00 +#define REG_TCFG1 0x04 + +#define TCFG0_PRESCALER_MASK 0xff +#define TCFG0_PRESCALER1_SHIFT 8 + +#define TCFG1_SHIFT(x) ((x) * 4) +#define TCFG1_MUX_MASK 0xf + struct samsung_timer_source { unsigned int event_id; unsigned int source_id; @@ -286,16 +295,51 @@ struct samsung_timer_source { }; static struct samsung_pwm *pwm; - -static struct clk *tin_event; -static struct clk *tin_source; -static struct clk *tdiv_event; -static struct clk *tdiv_source; static struct clk *timerclk; static struct samsung_timer_source timer_source; static unsigned long clock_count_per_tick; static void samsung_timer_resume(void); +static void samsung_timer_set_prescale(struct samsung_pwm *pwm, + unsigned int channel, u16 prescale) +{ + unsigned long flags; + u8 shift = 0; + u32 reg; + + if (channel >= 2) + shift = TCFG0_PRESCALER1_SHIFT; + + spin_lock_irqsave(&pwm->slock, flags); + + reg = readl(pwm->base + REG_TCFG0); + reg &= ~(TCFG0_PRESCALER_MASK << shift); + reg |= (prescale - 1) << shift; + writel(reg, pwm->base + REG_TCFG0); + + spin_unlock_irqrestore(&pwm->slock, flags); +} + +static void samsung_timer_set_divisor(struct samsung_pwm *pwm, + unsigned int channel, u8 divisor) +{ + u8 shift = TCFG1_SHIFT(channel); + unsigned long flags; + u32 reg; + u8 bits; + + bits = (fls(divisor) - 1) - pwm->variant.div_base; + + spin_lock_irqsave(&pwm->slock, flags); + + reg = readl(pwm->base + REG_TCFG1); + reg &= ~(TCFG1_MUX_MASK << shift); + reg |= bits << shift; + writel(reg, pwm->base + REG_TCFG1); + + spin_unlock_irqrestore(&pwm->slock, flags); +} + static void samsung_time_stop(enum samsung_timer_mode mode) { unsigned long tcon; @@ -531,18 +575,15 @@ static void __init samsung_clockevent_init(void) unsigned long pclk; unsigned long clock_rate; unsigned int irq_number; - struct clk *tscaler; pclk = clk_get_rate(timerclk); - tscaler = clk_get_parent(tdiv_event); - - clk_set_rate(tscaler, pclk / timer_source.tscaler_div); - clk_set_rate(tdiv_event, - pclk / (timer_source.tdiv * timer_source.tscaler_div)); - clk_set_parent(tin_event, tdiv_event); + samsung_timer_set_prescale(pwm, timer_source.event_id, + timer_source.tscaler_div); + samsung_timer_set_divisor(pwm, timer_source.event_id, + timer_source.tdiv); - clock_rate = clk_get_rate(tin_event); + clock_rate = pclk / (timer_source.tscaler_div * timer_source.tdiv); clock_count_per_tick = clock_rate / HZ; time_event_device.cpumask = cpumask_of(0); @@ -607,11 +648,12 @@ static void __init samsung_clocksource_init(void) pclk = clk_get_rate(timerclk); - clk_set_rate(tdiv_source, - pclk / (timer_source.tdiv * timer_source.tscaler_div)); - clk_set_parent(tin_source, tdiv_source); + samsung_timer_set_prescale(pwm, timer_source.source_id, + timer_source.tscaler_div); + samsung_timer_set_divisor(pwm, timer_source.source_id, + timer_source.tdiv); - clock_rate = clk_get_rate(tin_source); + clock_rate = pclk / (timer_source.tscaler_div * timer_source.tdiv); samsung_time_setup(timer_source.source_id, timer_source.tcnt_max); samsung_time_start(timer_source.source_id, true); @@ -628,44 +670,11 @@ static void __init samsung_clocksource_init(void) static void __init samsung_timer_resources(void) { - - unsigned long event_id = timer_source.event_id; - unsigned long source_id = timer_source.source_id; - char devname[15]; - timerclk = clk_get(NULL, "timers"); if (IS_ERR(timerclk)) panic("failed to get timers clock for timer"); - clk_enable(timerclk); - - sprintf(devname, "s3c24xx-pwm.%lu", event_id); - s3c_device_timer[event_id].id = event_id; - s3c_device_timer[event_id].dev.init_name = devname; - - tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin"); - if (IS_ERR(tin_event)) - panic("failed to get pwm-tin clock for event timer"); - - tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv"); - if (IS_ERR(tdiv_event)) - panic("failed to get pwm-tdiv clock for event timer"); - - clk_enable(tin_event); - - sprintf(devname, "s3c24xx-pwm.%lu", source_id); - s3c_device_timer[source_id].id = source_id; - s3c_device_timer[source_id].dev.init_name = devname; - - tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin"); - if (IS_ERR(tin_source)) - panic("failed to get pwm-tin clock for source timer"); - - tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv"); - if (IS_ERR(tdiv_source)) - panic("failed to get pwm-tdiv clock for source timer"); - - clk_enable(tin_source); + clk_prepare_enable(timerclk); timer_source.tcnt_max = (1UL << pwm->variant.bits) - 1; if (pwm->variant.bits == 16) {