From patchwork Mon Nov 19 18:45:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1768341 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 4BED5DF264 for ; Mon, 19 Nov 2012 19:20:10 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TaWn2-00028k-04; Mon, 19 Nov 2012 19:13:56 +0000 Received: from mail.df.lth.se ([194.47.250.12]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TaWLX-0003C6-7E for linux-arm-kernel@lists.infradead.org; Mon, 19 Nov 2012 18:45:34 +0000 Received: from mer.df.lth.se (mer.df.lth.se [194.47.250.37]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.df.lth.se (Postfix) with ESMTPS id 76EDF65D4F; Mon, 19 Nov 2012 19:45:19 +0100 (CET) Received: from mer.df.lth.se (triad@localhost.localdomain [127.0.0.1]) by mer.df.lth.se (8.14.3/8.14.3/Debian-9.4) with ESMTP id qAJIjIuP030044; Mon, 19 Nov 2012 19:45:18 +0100 Received: (from triad@localhost) by mer.df.lth.se (8.14.3/8.14.3/Submit) id qAJIjHuo029943; Mon, 19 Nov 2012 19:45:17 +0100 From: Linus Walleij To: Mike Turquette , Mike Turquette Subject: [PATCH] clk: move IM-PD1 clocks to drivers/clk Date: Mon, 19 Nov 2012 19:45:11 +0100 Message-Id: <1353350711-29916-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.7.2.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121119_134530_192510_4A5C85E2 X-CRM114-Status: GOOD ( 23.06 ) X-Spam-Score: -3.3 (---) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-3.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [194.47.250.12 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.7 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: Linus Walleij , arm@kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The ARM IM-PD1 add-on module has a few clock of its own, let's move also these down to the drivers/clk/versatile driver dir and get rid of any remaining oldschool Integrator clocks. Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/impd1.c | 68 +------------------- drivers/clk/versatile/Makefile | 1 + drivers/clk/versatile/clk-impd1.c | 96 ++++++++++++++++++++++++++++ drivers/clk/versatile/clk-integrator.c | 3 +- include/linux/platform_data/clk-integrator.h | 1 + 5 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 drivers/clk/versatile/clk-impd1.c diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index e428f3a..1ddfb38 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -21,10 +21,9 @@ #include #include #include +#include #include -#include -#include #include #include #include @@ -36,45 +35,6 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); struct impd1_module { void __iomem *base; - struct clk vcos[2]; - struct clk_lookup *clks[3]; -}; - -static const struct icst_params impd1_vco_params = { - .ref = 24000000, /* 24 MHz */ - .vco_max = ICST525_VCO_MAX_3V, - .vco_min = ICST525_VCO_MIN, - .vd_min = 12, - .vd_max = 519, - .rd_min = 3, - .rd_max = 120, - .s2div = icst525_s2div, - .idx2s = icst525_idx2s, -}; - -static void impd1_setvco(struct clk *clk, struct icst_vco vco) -{ - struct impd1_module *impd1 = clk->data; - u32 val = vco.v | (vco.r << 9) | (vco.s << 16); - - writel(0xa05f, impd1->base + IMPD1_LOCK); - writel(val, clk->vcoreg); - writel(0, impd1->base + IMPD1_LOCK); - -#ifdef DEBUG - vco.v = val & 0x1ff; - vco.r = (val >> 9) & 0x7f; - vco.s = (val >> 16) & 7; - - pr_debug("IM-PD1: VCO%d clock is %ld Hz\n", - vconr, icst525_hz(&impd1_vco_params, vco)); -#endif -} - -static const struct clk_ops impd1_clk_ops = { - .round = icst_clk_round, - .set = icst_clk_set, - .setvco = impd1_setvco, }; void impd1_tweak_control(struct device *dev, u32 mask, u32 val) @@ -344,10 +304,6 @@ static struct impd1_device impd1_devs[] = { } }; -static struct clk fixed_14745600 = { - .rate = 14745600, -}; - static int impd1_probe(struct lm_device *dev) { struct impd1_module *impd1; @@ -376,23 +332,7 @@ static int impd1_probe(struct lm_device *dev) printk("IM-PD1 found at 0x%08lx\n", (unsigned long)dev->resource.start); - for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { - impd1->vcos[i].ops = &impd1_clk_ops, - impd1->vcos[i].owner = THIS_MODULE, - impd1->vcos[i].params = &impd1_vco_params, - impd1->vcos[i].data = impd1; - } - impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; - impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; - - impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000", - dev->id); - impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100", - dev->id); - impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200", - dev->id); - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) - clkdev_add(impd1->clks[i]); + integrator_impd1_clk_init(impd1->base, dev->id); for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { struct impd1_device *idev = impd1_devs + i; @@ -431,13 +371,9 @@ static int impd1_remove_one(struct device *dev, void *data) static void impd1_remove(struct lm_device *dev) { struct impd1_module *impd1 = lm_get_drvdata(dev); - int i; device_for_each_child(&dev->dev, NULL, impd1_remove_one); - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) - clkdev_drop(impd1->clks[i]); - lm_set_drvdata(dev, NULL); iounmap(impd1->base); diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index c0a0f64..884e362 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -1,4 +1,5 @@ # Makefile for Versatile-specific clocks obj-$(CONFIG_ICST) += clk-icst.o obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o +obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c new file mode 100644 index 0000000..28ac702 --- /dev/null +++ b/drivers/clk/versatile/clk-impd1.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-icst.h" + +static void __iomem *impd1_base; + +/* + * There are two VCO's on the IM-PD1 but only one is used by the + * kernel, that is why we are only implementing the control of + * IMPD1_OSC1 here. + */ + +/** + * cp_auxvco_get() - get ICST VCO settings for the Integrator/IM-PD1 + * @vco: ICST VCO parameters to update with hardware status + */ +static struct icst_vco impd1_vco_get(void) +{ + u32 val; + struct icst_vco vco; + + val = readl(impd1_base + IMPD1_OSC1); + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 03; + return vco; +} + +/** + * impd1_vco_set() - commit changes to Integrator/IM-PD1 ICST VCO + * @vco: ICST VCO parameters to commit + */ +static void impd1_vco_set(struct icst_vco vco) +{ + u32 val; + + val = readl(impd1_base + IMPD1_OSC1) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + /* This magic unlocks the IM-PD1 VCO so it can be controlled */ + writel(0xa05f, impd1_base + IMPD1_LOCK); + writel(val, impd1_base + IMPD1_OSC1); + /* This locks the IM-PD1 again */ + writel(0, impd1_base + IMPD1_LOCK); +} + +static const struct icst_params impd1_vco_params = { + .ref = 24000000, /* 24 MHz */ + .vco_max = ICST525_VCO_MAX_3V, + .vco_min = ICST525_VCO_MIN, + .vd_min = 12, + .vd_max = 519, + .rd_min = 3, + .rd_max = 120, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + +static const struct clk_icst_desc __initdata impd1_icst_desc = { + .params = &impd1_vco_params, + .getvco = impd1_vco_get, + .setvco = impd1_vco_set, +}; + +static struct clk_lookup *clks[3]; + +/* + * integrator_clk_init() - set up the integrator clock tree + * @is_cp: pass true if it's the Integrator/CP else AP is assumed + */ +void __init integrator_impd1_clk_init(void __iomem *base, unsigned int id) +{ + struct clk *clk; + int i; + + impd1_base = base; + + clk = icst_clk_register(NULL, &impd1_icst_desc); + clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); + + /* UART reference clock */ + clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, + 14745600); + clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); + clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); + + for (i = 0; i < ARRAY_SIZE(clks); i++) + clkdev_add(clks[i]); +} diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index a505392..5aa6ab9 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c @@ -1,8 +1,9 @@ +#include #include #include #include #include -#include +#include #include #include diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h index 83fe9c2..a8a704d 100644 --- a/include/linux/platform_data/clk-integrator.h +++ b/include/linux/platform_data/clk-integrator.h @@ -1 +1,2 @@ void integrator_clk_init(bool is_cp); +void integrator_impd1_clk_init(void __iomem *base, unsigned int id);