From patchwork Fri Jan 15 07:49:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 73106 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0F7nrw6025098 for ; Fri, 15 Jan 2010 07:49:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751415Ab0AOHtw (ORCPT ); Fri, 15 Jan 2010 02:49:52 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751622Ab0AOHtw (ORCPT ); Fri, 15 Jan 2010 02:49:52 -0500 Received: from mail.gmx.net ([213.165.64.20]:45737 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751415Ab0AOHtw (ORCPT ); Fri, 15 Jan 2010 02:49:52 -0500 Received: (qmail invoked by alias); 15 Jan 2010 07:49:49 -0000 Received: from p57BD1BFB.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.27.251] by mail.gmx.net (mp028) with SMTP; 15 Jan 2010 08:49:49 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX1/vvHgbYL7v8DHgIno+VVonKuzfLPMx2GVRJjxLYg bmC02T/xwgc78d Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1NVgwN-0001Bn-4I for linux-sh@vger.kernel.org; Fri, 15 Jan 2010 08:49:55 +0100 Date: Fri, 15 Jan 2010 08:49:55 +0100 (CET) From: Guennadi Liakhovetski To: linux-sh@vger.kernel.org Subject: [PATCH] sh: support SIU sourcing from external clock on sh7722 Message-ID: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.45000000000000001 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index ea38b55..a6cc9eb 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -172,6 +172,63 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0), }; +static int siu_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk_div_mult_table *table = clk->priv; + u32 value; + int ret; + + if (!strcmp("pll_clk", parent->name)) + value = __raw_readl(clk->enable_reg) & ~(1 << 7); + else if ((!strcmp("siumcka_clk", parent->name) && + !strcmp("siua_clk", clk->name)) || + (!strcmp("siumckb_clk", parent->name) && + !strcmp("siub_clk", clk->name))) + value = __raw_readl(clk->enable_reg) | (1 << 7); + else + return -EINVAL; + + ret = clk_reparent(clk, parent); + if (ret < 0) + return ret; + + __raw_writel(value, clk->enable_reg); + + /* Rebiuld the frequency table */ + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, &clk->arch_flags); + + return 0; +} + +static int siu_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) +{ + unsigned long value; + int idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = __raw_readl(clk->enable_reg); + value &= ~0xf; + value |= idx; + __raw_writel(value, clk->enable_reg); + + return 0; +} + +static int siu_clk_enable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); + return 0; +} + +static void siu_clk_disable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); +} + +static struct clk_ops siu_ops; + int __init arch_clk_init(void) { int k, ret = 0; @@ -187,6 +244,15 @@ int __init arch_clk_init(void) if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + if (!ret) { + siu_ops = *div4_clks[DIV4_SIUA].ops; + siu_ops.enable = siu_clk_enable; + siu_ops.disable = siu_clk_disable; + siu_ops.set_rate = siu_clk_set_rate; + siu_ops.set_parent = siu_clk_set_parent; + div4_clks[DIV4_SIUA].ops = &siu_ops; + div4_clks[DIV4_SIUB].ops = &siu_ops; + } if (!ret) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));