From patchwork Wed Dec 4 22:52:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dinh Nguyen X-Patchwork-Id: 3285691 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 08D569F373 for ; Wed, 4 Dec 2013 22:57:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1A502204EA for ; Wed, 4 Dec 2013 22:57:46 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 053B2204A7 for ; Wed, 4 Dec 2013 22:57:45 +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 1VoLMa-00087u-EY; Wed, 04 Dec 2013 22:56:13 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VoLMF-00040d-BM; Wed, 04 Dec 2013 22:55:51 +0000 Received: from tx2ehsobe002.messaging.microsoft.com ([65.55.88.12] helo=tx2outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VoLLk-0003wa-5q for linux-arm-kernel@lists.infradead.org; Wed, 04 Dec 2013 22:55:23 +0000 Received: from mail56-tx2-R.bigfish.com (10.9.14.238) by TX2EHSOBE003.bigfish.com (10.9.40.23) with Microsoft SMTP Server id 14.1.225.22; Wed, 4 Dec 2013 22:54:53 +0000 Received: from mail56-tx2 (localhost [127.0.0.1]) by mail56-tx2-R.bigfish.com (Postfix) with ESMTP id 67EEE1200FC; Wed, 4 Dec 2013 22:54:53 +0000 (UTC) X-Forefront-Antispam-Report: CIP:66.35.236.232; KIP:(null); UIP:(null); IPV:NLI; H:SJ-ITEXEDGE02.altera.priv.altera.com; RD:none; EFVD:NLI X-SpamScore: 5 X-BigFish: VS5(zz8d0Ic8kzz1f42h208ch1ee6h1de0h1fdah2073h2146h1202h1e76h2189h1d1ah1d2ah1fc6hz70kz1de098h8275bh1de097h84d07hz2fh2a8h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h14ddh1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah224fh1d0ch1d2eh1d3fh1dfeh1dffh1e1dh1e23h1fe8h1ff5h2218h2216h226dh22d0h2327h2336h1155h) Received-SPF: pass (mail56-tx2: domain of altera.com designates 66.35.236.232 as permitted sender) client-ip=66.35.236.232; envelope-from=dinguyen@altera.com; helo=SJ-ITEXEDGE02.altera.priv.altera.com ; v.altera.com ; Received: from mail56-tx2 (localhost.localdomain [127.0.0.1]) by mail56-tx2 (MessageSwitch) id 138619769214462_14268; Wed, 4 Dec 2013 22:54:52 +0000 (UTC) Received: from TX2EHSMHS009.bigfish.com (unknown [10.9.14.225]) by mail56-tx2.bigfish.com (Postfix) with ESMTP id F1ABC20005A; Wed, 4 Dec 2013 22:54:51 +0000 (UTC) Received: from SJ-ITEXEDGE02.altera.priv.altera.com (66.35.236.232) by TX2EHSMHS009.bigfish.com (10.9.99.109) with Microsoft SMTP Server (TLS) id 14.16.227.3; Wed, 4 Dec 2013 22:54:50 +0000 Received: from sj-mail01.altera.com (137.57.1.6) by SJ-ITEXEDGE02.altera.priv.altera.com (66.35.236.232) with Microsoft SMTP Server id 8.3.327.1; Wed, 4 Dec 2013 14:42:57 -0800 Received: from linux-builds1.altera.com (linux-builds1.altera.com [137.57.188.114]) by sj-mail01.altera.com (8.13.7+Sun/8.13.7) with ESMTP id rB4Msjnb002799; Wed, 4 Dec 2013 14:54:47 -0800 (PST) From: To: , , , , , , , , , Subject: [PATCHv3 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager Date: Wed, 4 Dec 2013 16:52:53 -0600 Message-ID: <1386197576-3825-2-git-send-email-dinguyen@altera.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1386197576-3825-1-git-send-email-dinguyen@altera.com> References: <1386197576-3825-1-git-send-email-dinguyen@altera.com> MIME-Version: 1.0 X-OriginatorOrg: altera.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131204_175520_554410_5146B0E7 X-CRM114-Status: GOOD ( 18.38 ) X-Spam-Score: -4.2 (----) Cc: devicetree@vger.kernel.org, linux-mmc@vger.kernel.org, Dinh Nguyen , linux-arm-kernel@lists.infradead.org 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Dinh Nguyen The system manager is an IP block on the SOCFPGA platform. The system manager contains registers that control other IPs on the platform. One of the IPs that the system manager has control over is the SD/MMC, by way of controlling the clock phase on the SD/MMC Card Interface Unit. This patch adds a clock driver that the SD/MMC driver can use by calling the common clock API in order to set the appropriate register in the system manager by way of a syscon driver. This clock driver can also be re-used for other IPs that need to poke the system manager. Signed-off-by: Dinh Nguyen --- v3: Not use the syscon driver because as of 3.13-rc1, the syscon driver is loaded after the clock driver. v2: Use the syscon driver --- drivers/clk/socfpga/Makefile | 2 +- drivers/clk/socfpga/clk-sysmgr.c | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/socfpga/clk-sysmgr.c diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile index 0303c0b..cfceabc 100644 --- a/drivers/clk/socfpga/Makefile +++ b/drivers/clk/socfpga/Makefile @@ -1 +1 @@ -obj-y += clk.o +obj-y += clk.o clk-sysmgr.o diff --git a/drivers/clk/socfpga/clk-sysmgr.c b/drivers/clk/socfpga/clk-sysmgr.c new file mode 100644 index 0000000..7538b22 --- /dev/null +++ b/drivers/clk/socfpga/clk-sysmgr.c @@ -0,0 +1,88 @@ +/* + * Copyright 2013 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include + +/* SDMMC Group for System Manager defines */ +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ + ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0)) + +extern void __iomem *sys_manager_base_addr; + +struct socfpga_sysmgr { + struct clk_hw hw; + u32 reg; +}; +#define to_sysmgr_clk(p) container_of(p, struct socfpga_sysmgr, hw) + +static int sysmgr_set_dwmmc_drvsel_smpsel(struct clk_hw *hwclk) +{ + struct device_node *np; + struct socfpga_sysmgr *socfpga_sysmgr = to_sysmgr_clk(hwclk); + u32 timing[2]; + u32 hs_timing; + + np = of_find_compatible_node(NULL, NULL, "altr,socfpga-dw-mshc"); + of_property_read_u32_array(np, "samsung,dw-mshc-sdr-timing", timing, 2); + hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[1], timing[0]); + writel(hs_timing, sys_manager_base_addr + socfpga_sysmgr->reg); + return 0; +} + +static const struct clk_ops clk_sysmgr_sdmmc_ops = { + .enable = sysmgr_set_dwmmc_drvsel_smpsel, +}; + +static void __init socfpga_sysmgr_init(struct device_node *node, const struct clk_ops *ops) +{ + u32 reg; + struct clk *clk; + struct socfpga_sysmgr *socfpga_sysmgr; + const char *clk_name = node->name; + struct clk_init_data init; + int rc; + + socfpga_sysmgr = kzalloc(sizeof(*socfpga_sysmgr), GFP_KERNEL); + if (WARN_ON(!socfpga_sysmgr)) + return; + + rc = of_property_read_u32(node, "reg", ®); + if (WARN_ON(rc)) + return; + + socfpga_sysmgr->reg = reg; + + init.name = clk_name; + init.ops = ops; + init.flags = 0; + init.num_parents = 0; + + socfpga_sysmgr->hw.init = &init; + clk = clk_register(NULL, &socfpga_sysmgr->hw); + if (WARN_ON(IS_ERR(clk))) { + kfree(socfpga_sysmgr); + return; + } + rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (WARN_ON(rc)) + return; +} + +static void __init sysmgr_init(struct device_node *node) +{ + socfpga_sysmgr_init(node, &clk_sysmgr_sdmmc_ops); +} +CLK_OF_DECLARE(sysmgr, "altr,sysmgr-sdmmc-sdr", sysmgr_init);