From patchwork Sun May 12 04:22:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Tang X-Patchwork-Id: 2555151 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 00557DF215 for ; Sun, 12 May 2013 04:25:43 +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 1UbNpv-0002tw-0o; Sun, 12 May 2013 04:24:40 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UbNpb-0008Ok-UF; Sun, 12 May 2013 04:24:19 +0000 Received: from mail-pb0-x233.google.com ([2607:f8b0:400e:c01::233]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UbNpR-0008Ld-36 for linux-arm-kernel@lists.infradead.org; Sun, 12 May 2013 04:24:10 +0000 Received: by mail-pb0-f51.google.com with SMTP id wy7so3652181pbc.10 for ; Sat, 11 May 2013 21:23:47 -0700 (PDT) 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=Nzo/nlZBtumsUDl3NISUwAUwrORlQOgEZgr4onFhegw=; b=UkD/BA8Y6ocWMPAgprfBcWKaCb541U9hgmQdoQuJJRAZIsI78ZS9F0il5yC84d8jEz BYaqDnmWhVp+USow/i3uw/eLPppST75ty4tZ1ozmdqd3sgk4iOyoRVjPOwBce1vzC1I6 rcBn7sQyHl29jC5GIVLQYJ+VdmSwyUtvlV//+1XjE7hhgQ5QMXmdv/vk/xKhm18nwL3k l+3V9+TjjOuer6bT1G9G94cf2DYplOYLXrZbhygorhoY2KunwsQ1L6SZVlCiAqHFr20F gperQqgD5trkRvX984waiScy6cYQ67y5Rff7qnjrHCni0P+gKlEJfK8NQ77JSyYnr4ZP OKlg== X-Received: by 10.66.120.49 with SMTP id kz17mr24158651pab.133.1368332627681; Sat, 11 May 2013 21:23:47 -0700 (PDT) Received: from tangrs.lan (110-175-69-66.static.tpgi.com.au. [110.175.69.66]) by mx.google.com with ESMTPSA id 10sm8737984pbm.0.2013.05.11.21.23.34 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 11 May 2013 21:23:46 -0700 (PDT) From: Daniel Tang To: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk Subject: [RFC PATCHv3 3/6] clk: Add TI-Nspire clock drivers Date: Sun, 12 May 2013 14:22:58 +1000 Message-Id: <1368332581-94691-4-git-send-email-dt.tangr@gmail.com> X-Mailer: git-send-email 1.8.1.3 In-Reply-To: <1368332581-94691-1-git-send-email-dt.tangr@gmail.com> References: <1368332581-94691-1-git-send-email-dt.tangr@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130512_002409_282746_A6E494C0 X-CRM114-Status: GOOD ( 16.60 ) 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 (dt.tangr[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: Arnd Bergmann , Linus Walleij , linux-kernel@vger.kernel.org, "fabian@ritter-vogt.de Vogt" , Daniel Tang , Lionel Debroux 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 Signed-off-by: Daniel Tang --- drivers/clk/Makefile | 1 + drivers/clk/clk-nspire.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 drivers/clk/clk-nspire.c diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 137d3e7..72ebbe1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-composite.o obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o +obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/clk/clk-nspire.c b/drivers/clk/clk-nspire.c new file mode 100644 index 0000000..2a8d14c --- /dev/null +++ b/drivers/clk/clk-nspire.c @@ -0,0 +1,141 @@ +/* + * linux/drivers/clk/clk-nspire.c + * + * Copyright (C) 2013 Daniel Tang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +#define MHZ (1000 * 1000) + +#define BASE_CPU_SHIFT 1 +#define BASE_CPU_MASK 0x7F + +#define CPU_AHB_SHIFT 12 +#define CPU_AHB_MASK 0x07 + +#define FIXED_BASE_SHIFT 8 +#define FIXED_BASE_MASK 0x01 + +#define CLASSIC_BASE_SHIFT 16 +#define CLASSIC_BASE_MASK 0x1F + +#define CX_BASE_SHIFT 15 +#define CX_BASE_MASK 0x3F + +#define CX_UNKNOWN_SHIFT 21 +#define CX_UNKNOWN_MASK 0x03 + +#define EXTRACT(var, prop) (((var)>>prop##_SHIFT) & prop##_MASK) + +struct nspire_clk_info { + u32 base_clock; + u16 base_cpu_ratio; + u16 base_ahb_ratio; +}; + +static int nspire_clk_read(struct device_node *node, + struct nspire_clk_info *clk) +{ + u32 val; + int ret; + void __iomem *io; + const char *type = NULL; + + ret = of_property_read_string(node, "io-type", &type); + if (ret) + return ret; + + io = of_iomap(node, 0); + if (!io) + return -ENOMEM; + val = readl(io); + iounmap(io); + + if (!strcmp(type, "cx")) { + if (EXTRACT(val, FIXED_BASE)) { + clk->base_clock = 48 * MHZ; + } else { + clk->base_clock = 6 * EXTRACT(val, CX_BASE) * MHZ; + } + + clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * + EXTRACT(val, CX_UNKNOWN); + clk->base_ahb_ratio = clk->base_cpu_ratio * + (EXTRACT(val, CPU_AHB) + 1); + } else if (!strcmp(type, "classic")) { + if (EXTRACT(val, FIXED_BASE)) { + clk->base_clock = 27 * MHZ; + } else { + clk->base_clock = (300 - + 6 * EXTRACT(val, CLASSIC_BASE)) * MHZ; + } + + clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * 2; + clk->base_ahb_ratio = clk->base_cpu_ratio * + (EXTRACT(val, CPU_AHB) + 1); + } else { + return -EINVAL; + } + + return 0; +} + +static void __init nspire_ahbdiv_setup(struct device_node *node) +{ + int ret; + struct clk *clk; + const char *clk_name = node->name; + const char *parent_name; + struct nspire_clk_info info; + + ret = nspire_clk_read(node, &info); + if (WARN_ON(ret)) + return; + + of_property_read_string(node, "clock-output-names", &clk_name); + parent_name = of_clk_get_parent_name(node, 0); + + clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, + 1, info.base_ahb_ratio); + if (!IS_ERR(clk)) + of_clk_add_provider(node, of_clk_src_simple_get, clk); +} + +static void __init nspire_clk_setup(struct device_node *node) +{ + int ret; + struct clk *clk; + const char *clk_name = node->name; + struct nspire_clk_info info; + + ret = nspire_clk_read(node, &info); + if (WARN_ON(ret)) + return; + + of_property_read_string(node, "clock-output-names", &clk_name); + + clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, + info.base_clock); + if (!IS_ERR(clk)) + of_clk_add_provider(node, of_clk_src_simple_get, clk); + else + return; + + pr_info("TI-NSPIRE Base: %uMHz CPU: %uMHz AHB: %uMHz\n", + info.base_clock / MHZ, + info.base_clock / info.base_cpu_ratio / MHZ, + info.base_clock / info.base_ahb_ratio / MHZ); +} + +CLK_OF_DECLARE(nspire_clk, "nspire-clock", nspire_clk_setup); +CLK_OF_DECLARE(nspire_ahbdiv, "nspire-ahb-divider", nspire_ahbdiv_setup);