From patchwork Thu Nov 1 16:30:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianxin Pan X-Patchwork-Id: 10664225 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A9F18157A for ; Thu, 1 Nov 2018 16:31:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 953462C1DD for ; Thu, 1 Nov 2018 16:31:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 891482C1E4; Thu, 1 Nov 2018 16:31:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 227662C1DD for ; Thu, 1 Nov 2018 16:31:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=2hpqUq6dkSOQ0m8Xhjc1mP0D6QCQjVYhlJqikomxo0Q=; b=ZEIui56UhCfsnY LFBUgW7NdEk/XU0VIenDG2z9GkS/wv9f75EhhC4smfRphqDX7940uN1I2CexWGSt0L1IztsvnLQIH HQZw7vJ3tkm/Js2dN1s+g/FT11Q1VPc1XzScW/jxutqUAtF5eh6ptUJyOR1fwpw4qU5qnrBpJyYo+ lGeDhLYXCrCXrH4bryXnpBlCZOHZOuEKf9cAM+zJNct2EjahgNGxG88eTrBjck4D/VGrauuWu+93e +iQZLGQSbl2kAzA4SqTqJ7wnyAXe2cbBPDBAruvKdiMpXczByFy1dhSGhQWYS2bG49by1U3WPzBTc Awz3qC6coJRbg7H1/f9w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFsr-0001t0-Rr; Thu, 01 Nov 2018 16:31:49 +0000 Received: from mail-sh2.amlogic.com ([58.32.228.45]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFsm-0001bd-TB; Thu, 01 Nov 2018 16:31:46 +0000 Received: from localhost.localdomain (10.18.11.217) by mail-sh2.amlogic.com (10.18.11.6) with Microsoft SMTP Server id 15.0.1320.4; Fri, 2 Nov 2018 00:31:06 +0800 From: Jianxin Pan To: Jerome Brunet , Neil Armstrong Subject: [PATCH v6 1/3] clk: meson: add emmc sub clock phase delay driver Date: Fri, 2 Nov 2018 00:30:53 +0800 Message-ID: <1541089855-19356-2-git-send-email-jianxin.pan@amlogic.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> References: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.18.11.217] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181101_093145_030210_7AB4DEA1 X-CRM114-Status: GOOD ( 13.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Hanjie Lin , Victor Wan , Jianxin Pan , devicetree@vger.kernel.org, Stephen Boyd , Kevin Hilman , Michael Turquette , Yixun Lan , linux-kernel@vger.kernel.org, Boris Brezillon , Liang Yang , Jian Hu , Miquel Raynal , Carlo Caione , linux-amlogic@lists.infradead.org, Martin Blumenstingl , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Qiufang Dai Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Yixun Lan Export the emmc sub clock phase delay ops which will be used by the emmc sub clock driver itself. Signed-off-by: Yixun Lan Signed-off-by: Jianxin Pan --- drivers/clk/meson/Makefile | 2 +- drivers/clk/meson/clk-phase-delay.c | 66 +++++++++++++++++++++++++++++++++++++ drivers/clk/meson/clkc.h | 13 ++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/meson/clk-phase-delay.c diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 72ec8c4..39ce566 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -2,7 +2,7 @@ # Makefile for Meson specific clk # -obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o +obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o clk-phase-delay.o obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c new file mode 100644 index 0000000..83e74ed --- /dev/null +++ b/drivers/clk/meson/clk-phase-delay.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Amlogic Meson MMC Sub Clock Controller Driver + * + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Yixun Lan + * Author: Jianxin Pan + */ + +#include +#include "clkc.h" + +static int meson_clk_phase_delay_get_phase(struct clk_hw *hw) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_phase_delay_data *ph = + meson_clk_get_phase_delay_data(clk); + unsigned long period_ps, p, d; + int degrees; + + p = meson_parm_read(clk->map, &ph->phase); + degrees = p * 360 / (1 << (ph->phase.width)); + + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000, + clk_hw_get_rate(hw)); + + d = meson_parm_read(clk->map, &ph->delay); + degrees += d * ph->delay_step_ps * 360 / period_ps; + degrees %= 360; + + return degrees; +} + +static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_phase_delay_data *ph = + meson_clk_get_phase_delay_data(clk); + unsigned long period_ps, d = 0, r; + u64 p; + + p = degrees % 360; + period_ps = DIV_ROUND_UP((unsigned long)NSEC_PER_SEC * 1000, + clk_hw_get_rate(hw)); + + /* First compute the phase index (p), the remainder (r) is the + * part we'll try to acheive using the delays (d). + */ + r = do_div(p, 360 / (1 << (ph->phase.width))); + d = DIV_ROUND_CLOSEST(r * period_ps, + 360 * ph->delay_step_ps); + d = min(d, PMASK(ph->delay.width)); + + meson_parm_write(clk->map, &ph->phase, p); + meson_parm_write(clk->map, &ph->delay, d); + return 0; +} + +const struct clk_ops meson_clk_phase_delay_ops = { + .get_phase = meson_clk_phase_delay_get_phase, + .set_phase = meson_clk_phase_delay_set_phase, +}; +EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops); diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 6b96d55..30470c6 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -105,6 +105,18 @@ struct clk_regmap _name = { \ }, \ }; +struct meson_clk_phase_delay_data { + struct parm phase; + struct parm delay; + unsigned int delay_step_ps; +}; + +static inline struct meson_clk_phase_delay_data * +meson_clk_get_phase_delay_data(struct clk_regmap *clk) +{ + return clk->data; +} + /* clk_ops */ extern const struct clk_ops meson_clk_pll_ro_ops; extern const struct clk_ops meson_clk_pll_ops; @@ -112,5 +124,6 @@ struct clk_regmap _name = { \ extern const struct clk_ops meson_clk_mpll_ro_ops; extern const struct clk_ops meson_clk_mpll_ops; extern const struct clk_ops meson_clk_phase_ops; +extern const struct clk_ops meson_clk_phase_delay_ops; #endif /* __CLKC_H */ From patchwork Thu Nov 1 16:30:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianxin Pan X-Patchwork-Id: 10664227 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5A157157A for ; Thu, 1 Nov 2018 16:32:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4655B2C1E4 for ; Thu, 1 Nov 2018 16:32:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3988B2C1E7; Thu, 1 Nov 2018 16:32:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D58FB2C1E4 for ; Thu, 1 Nov 2018 16:32:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=KAbS1Sq7+w16NhZilLI6L3myaPAPxG+jJgM3ZrVNwsA=; b=pY3gJq0hI8+ZSW MjdR+nbP9Q84QKG2d9yYkFOlOBBhXreAXSbu+lZvTlkUj7qmCg1VhZIVl4oy5sq1ep8oeDSFKe0lW 5ROFngQdouJQFWxPeoVFnROEyqipdIVfoOeICHdDinBLgvqmTipe8ldT4u0QGqaunRl0T2ozyLsEf 7uYjxVcvk0ExPUhX+fMI9L1qPcY9S3MBgYrt2KBE1KpW5+MQziU4lAQl0NPF5gGZiFvarq5hlt+B5 t1+xl+193JqQG/KTqFDdqNVQxS0U/e2v2FIRGgBe4LSBbneHRHXOBnvt66whp/S41nVCDFyhbKkBR xArkaKqf1e4p8jr2CiYA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFt8-0002DA-KN; Thu, 01 Nov 2018 16:32:06 +0000 Received: from mail-sh2.amlogic.com ([58.32.228.45]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFt0-0001qp-CH; Thu, 01 Nov 2018 16:32:04 +0000 Received: from localhost.localdomain (10.18.11.217) by mail-sh2.amlogic.com (10.18.11.6) with Microsoft SMTP Server id 15.0.1320.4; Fri, 2 Nov 2018 00:31:06 +0800 From: Jianxin Pan To: Jerome Brunet , Neil Armstrong Subject: [PATCH v6 2/3] clk: meson: add DT documentation for emmc clock controller Date: Fri, 2 Nov 2018 00:30:54 +0800 Message-ID: <1541089855-19356-3-git-send-email-jianxin.pan@amlogic.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> References: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.18.11.217] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181101_093158_863656_2396653B X-CRM114-Status: GOOD ( 10.99 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Hanjie Lin , Victor Wan , Jianxin Pan , Stephen Boyd , Kevin Hilman , Michael Turquette , Yixun Lan , linux-kernel@vger.kernel.org, Boris Brezillon , Liang Yang , Jian Hu , Miquel Raynal , Carlo Caione , linux-amlogic@lists.infradead.org, Martin Blumenstingl , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Qiufang Dai Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Yixun Lan Document the MMC sub clock controller driver, the potential consumer of this driver is MMC or NAND. Also add four clock bindings IDs which provided by this driver. Reviewed-by: Rob Herring Signed-off-by: Yixun Lan Signed-off-by: Jianxin Pan --- .../devicetree/bindings/clock/amlogic,mmc-clkc.txt | 39 ++++++++++++++++++++++ include/dt-bindings/clock/amlogic,mmc-clkc.h | 17 ++++++++++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.txt create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.txt new file mode 100644 index 0000000..0f518e6 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.txt @@ -0,0 +1,39 @@ +* Amlogic MMC Sub Clock Controller Driver + +The Amlogic MMC clock controller generates and supplies clock to support +MMC and NAND controller + +Required Properties: + +- compatible: should be: + "amlogic,gx-mmc-clkc" + "amlogic,axg-mmc-clkc" + +- #clock-cells: should be 1. +- clocks: phandles to clocks corresponding to the clock-names property +- clock-names: list of parent clock names + - "clkin0", "clkin1" + +- reg: address of emmc sub clock register + +Example: Clock controller node: + +sd_mmc_c_clkc: clock-controller@7000 { + compatible = "amlogic,axg-mmc-clkc", "syscon"; + reg = <0x0 0x7000 0x0 0x4>; + #clock-cells = <1>; + + clock-names = "clkin0", "clkin1"; + clocks = <&clkc CLKID_SD_MMC_C_CLK0>, + <&clkc CLKID_FCLK_DIV2>; +}; + +sd_emmc_b_clkc: clock-controller@5000 { + compatible = "amlogic,axg-mmc-clkc", "syscon"; + reg = <0x0 0x5000 0x0 0x4>; + + #clock-cells = <1>; + clock-names = "clkin0", "clkin1"; + clocks = <&clkc CLKID_SD_EMMC_B_CLK0>, + <&clkc CLKID_FCLK_DIV2>; +}; diff --git a/include/dt-bindings/clock/amlogic,mmc-clkc.h b/include/dt-bindings/clock/amlogic,mmc-clkc.h new file mode 100644 index 0000000..162b949 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,mmc-clkc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Meson MMC sub clock tree IDs + * + * Copyright (c) 2018 Amlogic, Inc. All rights reserved. + * Author: Yixun Lan + */ + +#ifndef __MMC_CLKC_H +#define __MMC_CLKC_H + +#define CLKID_MMC_DIV 1 +#define CLKID_MMC_PHASE_CORE 2 +#define CLKID_MMC_PHASE_TX 3 +#define CLKID_MMC_PHASE_RX 4 + +#endif From patchwork Thu Nov 1 16:30:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianxin Pan X-Patchwork-Id: 10664231 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7358A14BD for ; Thu, 1 Nov 2018 16:32:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BC592C1E0 for ; Thu, 1 Nov 2018 16:32:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D2902C1E9; Thu, 1 Nov 2018 16:32:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2BE612C1E0 for ; Thu, 1 Nov 2018 16:32:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=te3Mzy/mRuKaooCDEv505zuWQZ1iKjbxYjyXR1NTTwU=; b=N5QPE1rxi7fOgn BYtwfK8Yn/Byl4Sj41S59ObozgAx1tvOp8hJ5iyCF9jcTHrwXLaOW7fTFd/k6ZFxYM5+ohxp1ZjQw SzYl7snPDt0XLi7z67hMLCcDdOTGgPCkJX6XjSHXDK/hK7GR3ACAySJt/rWTHCeKlLqLKX8vCu9Zi TNT+7odERH3A5pWLMAA74A+LOkw8FYXFPO1abnnU7T2QvHVc/qAWAunYTufy5lS6JWozU8JmAzYX1 bCfugrYLjuKgi8mGde695VkmjG1gsbO90wbQGRnWt0iKkas+ZDeME+oYMiYn2/pRoTi7P+DQXjSHg /kdnTQIRqnFZ9kI8XyYA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFtU-0002Xr-Vr; Thu, 01 Nov 2018 16:32:29 +0000 Received: from mail-sh2.amlogic.com ([58.32.228.45]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gIFtI-0002Ci-AR; Thu, 01 Nov 2018 16:32:27 +0000 Received: from localhost.localdomain (10.18.11.217) by mail-sh2.amlogic.com (10.18.11.6) with Microsoft SMTP Server id 15.0.1320.4; Fri, 2 Nov 2018 00:31:07 +0800 From: Jianxin Pan To: Jerome Brunet , Neil Armstrong Subject: [PATCH v6 3/3] clk: meson: add sub MMC clock controller driver Date: Fri, 2 Nov 2018 00:30:55 +0800 Message-ID: <1541089855-19356-4-git-send-email-jianxin.pan@amlogic.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> References: <1541089855-19356-1-git-send-email-jianxin.pan@amlogic.com> MIME-Version: 1.0 X-Originating-IP: [10.18.11.217] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181101_093217_506150_CAA06E7A X-CRM114-Status: GOOD ( 18.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Hanjie Lin , Victor Wan , Jianxin Pan , Stephen Boyd , Kevin Hilman , Michael Turquette , Yixun Lan , linux-kernel@vger.kernel.org, Boris Brezillon , Liang Yang , Jian Hu , Miquel Raynal , Carlo Caione , linux-amlogic@lists.infradead.org, Martin Blumenstingl , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Qiufang Dai Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Yixun Lan The patch will add a MMC clock controller driver which used by MMC or NAND, It provide a mux and divider clock, and three phase clocks - core, tx, tx. Two clocks are provided as the parent of MMC clock controller from upper layer clock controller - eg "amlogic,axg-clkc" in AXG platform. To specify which clock the MMC or NAND driver may consume, the preprocessor macros in the dt-bindings/clock/amlogic,mmc-clkc.h header can be used in the device tree sources. Signed-off-by: Yixun Lan Signed-off-by: Jianxin Pan --- drivers/clk/meson/Kconfig | 10 ++ drivers/clk/meson/Makefile | 1 + drivers/clk/meson/clk-regmap.c | 1 - drivers/clk/meson/mmc-clkc.c | 310 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/meson/mmc-clkc.c diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index efaa70f..6bb0d44 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -15,6 +15,16 @@ config COMMON_CLK_MESON_AO select COMMON_CLK_REGMAP_MESON select RESET_CONTROLLER +config COMMON_CLK_MMC_MESON + tristate "Meson MMC Sub Clock Controller Driver" + select MFD_SYSCON + select COMMON_CLK_AMLOGIC + select COMMON_CLK_AMLOGIC_AUDIO + help + Support for the MMC sub clock controller on Amlogic Meson Platform, + which include S905 (GXBB, GXL), A113D/X (AXG) devices. + Say Y if you want this clock enabled. + config COMMON_CLK_REGMAP_MESON bool select REGMAP diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 39ce566..31c16d5 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o +obj-$(CONFIG_COMMON_CLK_MMC_MESON) += mmc-clkc.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c index 305ee30..89cee4a 100644 --- a/drivers/clk/meson/clk-regmap.c +++ b/drivers/clk/meson/clk-regmap.c @@ -114,7 +114,6 @@ static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, }; /* Would prefer clk_regmap_div_ro_ops but clashes with qcom */ - const struct clk_ops clk_regmap_divider_ops = { .recalc_rate = clk_regmap_div_recalc_rate, .round_rate = clk_regmap_div_round_rate, diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c new file mode 100644 index 0000000..a3e4c91 --- /dev/null +++ b/drivers/clk/meson/mmc-clkc.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Amlogic Meson MMC Sub Clock Controller Driver + * + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Yixun Lan + * Author: Jianxin Pan + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clkc.h" +#include "clkc-audio.h" + +/* clock ID used by internal driver */ +#define CLKID_MMC_MUX 0 + +#define SD_EMMC_CLOCK 0 +#define CLK_DELAY_STEP_PS 200 +#define CLK_PHASE_STEP 30 +#define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) + +#define MUX_CLK_NUM_PARENTS 2 +#define MMC_MAX_CLKS 5 + +struct mmc_clkc_data { + struct meson_clk_phase_delay_data tx; + struct meson_clk_phase_delay_data rx; +}; + +static struct clk_regmap_mux_data mmc_clkc_mux_data = { + .offset = SD_EMMC_CLOCK, + .mask = 0x3, + .shift = 6, +}; + +struct meson_sclk_div_data mmc_clkc_div_data = { + .div = { + .reg_off = SD_EMMC_CLOCK, + .shift = (0), + .width = (6), + }, + .hi = { + .reg_off = 0, + .shift = 0, + .width = 0, + }, +}; + +static struct meson_clk_phase_data mmc_clkc_core_phase = { + .ph = { + .reg_off = SD_EMMC_CLOCK, + .shift = 8, + .width = 2, + } +}; + +static const struct mmc_clkc_data mmc_clkc_gx_data = { + .tx = { + .phase = { + .reg_off = SD_EMMC_CLOCK, + .shift = 10, + .width = 2, + }, + .delay = { + .reg_off = SD_EMMC_CLOCK, + .shift = 16, + .width = 4, + }, + .delay_step_ps = CLK_DELAY_STEP_PS, + }, + .rx = { + .phase = { + .reg_off = SD_EMMC_CLOCK, + .shift = 12, + .width = 2, + }, + .delay = { + .reg_off = SD_EMMC_CLOCK, + .shift = 20, + .width = 4, + }, + .delay_step_ps = CLK_DELAY_STEP_PS, + }, +}; + +static const struct mmc_clkc_data mmc_clkc_axg_data = { + .tx = { + .phase = { + .reg_off = SD_EMMC_CLOCK, + .shift = 10, + .width = 2, + }, + .delay = { + .reg_off = SD_EMMC_CLOCK, + .shift = 16, + .width = 6, + }, + .delay_step_ps = CLK_DELAY_STEP_PS, + }, + .rx = { + .phase = { + .reg_off = SD_EMMC_CLOCK, + .shift = 12, + .width = 2, + }, + .delay = { + .reg_off = SD_EMMC_CLOCK, + .shift = 22, + .width = 6, + }, + .delay_step_ps = CLK_DELAY_STEP_PS, + }, +}; + +static const struct of_device_id mmc_clkc_match_table[] = { + { + .compatible = "amlogic,gx-mmc-clkc", + .data = &mmc_clkc_gx_data + }, + { + .compatible = "amlogic,axg-mmc-clkc", + .data = &mmc_clkc_axg_data + }, + {} +}; +MODULE_DEVICE_TABLE(of, mmc_clkc_match_table); + +static struct clk_regmap * +mmc_clkc_register_clk(struct device *dev, struct regmap *map, + struct clk_init_data *init, + const char *suffix, void *data) +{ + struct clk_regmap *clk; + char *name; + int ret; + + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return ERR_PTR(-ENOMEM); + + name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix); + if (!name) + return ERR_PTR(-ENOMEM); + + init->name = name; + + clk->map = map; + clk->data = data; + clk->hw.init = init; + + ret = devm_clk_hw_register(dev, &clk->hw); + if (ret) + clk = ERR_PTR(ret); + + kfree(name); + return clk; +} + +static struct clk_regmap *mmc_clkc_register_mux(struct device *dev, + struct regmap *map) +{ + const char *parent_names[MUX_CLK_NUM_PARENTS]; + struct clk_init_data init; + struct clk_regmap *mux; + struct clk *clk; + int i; + + for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { + char name[8]; + + snprintf(name, sizeof(name), "clkin%d", i); + clk = devm_clk_get(dev, name); + if (IS_ERR(clk)) { + if (clk != ERR_PTR(-EPROBE_DEFER)) + dev_err(dev, "Missing clock %s\n", name); + return ERR_PTR((long)clk); + } + + parent_names[i] = __clk_get_name(clk); + } + + init.ops = &clk_regmap_mux_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = parent_names; + init.num_parents = MUX_CLK_NUM_PARENTS; + + mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data); + if (IS_ERR(mux)) + dev_err(dev, "Mux clock registration failed\n"); + + return mux; +} + +static struct clk_regmap * +mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map, + char *suffix, const struct clk_hw *hw, + unsigned long flags, + const struct clk_ops *ops, void *data) +{ + struct clk_init_data init; + struct clk_regmap *clk; + const char *parent_name = clk_hw_get_name(hw); + + init.ops = ops; + init.flags = flags; + init.parent_names = &parent_name; + init.num_parents = 1; + + clk = mmc_clkc_register_clk(dev, map, &init, suffix, data); + if (IS_ERR(clk)) + dev_err(dev, "Core %s clock registration failed\n", suffix); + + return clk; +} + +static int mmc_clkc_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *onecell_data; + struct device *dev = &pdev->dev; + struct mmc_clkc_data *data; + struct regmap *map; + struct clk_regmap *clk, *core; + + /*cast to drop the const in match->data*/ + data = (struct mmc_clkc_data *)of_device_get_match_data(dev); + if (!data) + return -ENODEV; + + map = syscon_node_to_regmap(dev->of_node); + if (IS_ERR(map)) { + dev_err(dev, "could not find mmc clock controller\n"); + return PTR_ERR(map); + } + + onecell_data = devm_kzalloc(dev, sizeof(*onecell_data) + + sizeof(*onecell_data->hws) * MMC_MAX_CLKS, + GFP_KERNEL); + if (!onecell_data) + return -ENOMEM; + + clk = mmc_clkc_register_mux(dev, map); + if (IS_ERR(clk)) + return PTR_ERR(clk); + onecell_data->hws[CLKID_MMC_MUX] = &clk->hw, + + clk = mmc_clkc_register_clk_with_parent(dev, map, "div", + &clk->hw, + CLK_SET_RATE_PARENT, + &meson_sclk_div_ops, + &mmc_clkc_div_data); + if (IS_ERR(clk)) + return PTR_ERR(clk); + onecell_data->hws[CLKID_MMC_DIV] = &clk->hw, + + core = mmc_clkc_register_clk_with_parent(dev, map, "core", + &clk->hw, + CLK_SET_RATE_PARENT, + &meson_clk_phase_ops, + &mmc_clkc_core_phase); + if (IS_ERR(core)) + return PTR_ERR(core); + onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw, + + clk = mmc_clkc_register_clk_with_parent(dev, map, "rx", + &core->hw, 0, + &meson_clk_phase_delay_ops, + &data->rx); + if (IS_ERR(clk)) + return PTR_ERR(clk); + onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw, + + clk = mmc_clkc_register_clk_with_parent(dev, map, "tx", + &core->hw, 0, + &meson_clk_phase_delay_ops, + &data->tx); + if (IS_ERR(clk)) + return PTR_ERR(clk); + onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw, + + onecell_data->num = MMC_MAX_CLKS; + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + onecell_data); +} + +static struct platform_driver mmc_clkc_driver = { + .probe = mmc_clkc_probe, + .driver = { + .name = "meson-mmc-clkc", + .of_match_table = of_match_ptr(mmc_clkc_match_table), + }, +}; + +module_platform_driver(mmc_clkc_driver); + +MODULE_DESCRIPTION("Amlogic AXG MMC clock driver"); +MODULE_AUTHOR("Jianxin Pan "); +MODULE_LICENSE("GPL v2");