From patchwork Wed Apr 19 09:13:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 97614 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp229340qgf; Wed, 19 Apr 2017 02:13:52 -0700 (PDT) X-Received: by 10.84.222.135 with SMTP id x7mr2714386pls.50.1492593232571; Wed, 19 Apr 2017 02:13:52 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k8si1879303pgp.133.2017.04.19.02.13.52; Wed, 19 Apr 2017 02:13:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1761463AbdDSJNv (ORCPT + 9 others); Wed, 19 Apr 2017 05:13:51 -0400 Received: from mail-lf0-f48.google.com ([209.85.215.48]:32902 "EHLO mail-lf0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761433AbdDSJNr (ORCPT ); Wed, 19 Apr 2017 05:13:47 -0400 Received: by mail-lf0-f48.google.com with SMTP id 88so8964501lfr.0 for ; Wed, 19 Apr 2017 02:13:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=B3A96M3zsnI+ptl8KCrRasi/KqVNAC9h2YgbADE6448=; b=h+81WWyuL8KVAMUBTe8nReAkeXIzr06yzxRCYP7mkzS4RT7KTDcs2pFyd5Y+OZlfXk WzwC2mqmd2ZDU6IAmzOh68Z6MuEifFNFE5StneU8R9pM/xR8GvICTQkevUHQLEDLNlNu 2pYsBLzxXhWYaO/P+N2V13I4AZ++/VY41ic6U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=B3A96M3zsnI+ptl8KCrRasi/KqVNAC9h2YgbADE6448=; b=PYmPxgXgWrgrOiFLbmXvZLvI15mYmAVull9KrjFL6KT9TlAULLGgvNnnjQ9+6kSngw ZPwuHPIJmIx/280pdRH+scd+b+Y3SZeFHIUkp9sbxIBUJHwo4ixv8BEy8P+Dyshr1ccP PY3B8urjZgFYQuMvZS476FgLSJxauuW2uVDoHz6APSf0Yy13JnarWc35ESvIlu+2PXsl 1AyNcXKe5w4QbMnY4VFn2lLL2/QjaD+ESK/Hx8oEeD0RbYzlno2Dln4Ky1/VJXaQyOaa iBOC3M32RGtnyNR3Q7ftW+DHd/tN5u4zy/nV9Y40dSBN45jJyt/w8nFcf60tMkgCbTl8 BQSg== X-Gm-Message-State: AN3rC/5zNQisGvh3mm6r+kqVrw9NuqMQy8Bz/ukuzdVNNSrvNSFnmQSO /Ig8qfHaOsebvLSI X-Received: by 10.25.219.84 with SMTP id s81mr757321lfg.110.1492593225316; Wed, 19 Apr 2017 02:13:45 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id q123sm303230ljb.18.2017.04.19.02.13.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Apr 2017 02:13:43 -0700 (PDT) From: Linus Walleij To: Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-arm-msm@vger.kernel.org, Linus Walleij Subject: [PATCH 3/5 v2] clk: qcom: Implement RPM clocks for MSM8660/APQ8060 Date: Wed, 19 Apr 2017 11:13:24 +0200 Message-Id: <20170419091326.11226-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170419091326.11226-1-linus.walleij@linaro.org> References: <20170419091326.11226-1-linus.walleij@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The RPM clocks were missing for MSM8660/APQ8060. For this to be completed we need to add a special fixed rate RPM clock that is used for the PLL4 on these SoCs. The rest of the clocks are pretty similar to the other supported platforms. The "active" clock pattern is mirrored in all the clocks. I guess that the PLL4 that clocks the LPASS is actually never used as "active only" since the low-power audio subsystem should be left on when the system suspends, so it can be used as a stand-alone MP3 player type of device. As we do not have firmware for the LPASS we will probably only use this clock when the system is up and running (not suspended) for now, so that will be using the "active" clock. Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Add the small hunk to the clk_rpm_handoff() function that just skip over this for the fixed PLL4 clock. This accidentally ended up in another patch. --- drivers/clk/qcom/clk-rpm.c | 106 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index df3e5fe8442a..61c67e93bea3 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -56,6 +56,30 @@ }, \ } +#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \ + static struct clk_rpm _platform##_##_name = { \ + .rpm_clk_id = (r_id), \ + .rate = (r), \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_rpm_fixed_ops, \ + .name = #_name, \ + .parent_names = (const char *[]){ "pxo_board" }, \ + .num_parents = 1, \ + }, \ + }; \ + static struct clk_rpm _platform##_##_active = { \ + .rpm_clk_id = (r_id), \ + .peer = &_platform##_##_name, \ + .active_only = true, \ + .rate = (r), \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_rpm_fixed_ops, \ + .name = #_active, \ + .parent_names = (const char *[]){ "pxo_board" }, \ + .num_parents = 1, \ + }, \ + } + #define DEFINE_CLK_RPM_PXO_BRANCH(_platform, _name, _active, r_id, r) \ static struct clk_rpm _platform##_##_active; \ static struct clk_rpm _platform##_##_name = { \ @@ -143,6 +167,13 @@ static int clk_rpm_handoff(struct clk_rpm *r) int ret; u32 value = INT_MAX; + /* + * The vendor tree simply reads the status for this + * RPM clock. + */ + if (r->rpm_clk_id == QCOM_RPM_PLL_4) + return 0; + ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, r->rpm_clk_id, &value, 1); if (ret) @@ -269,6 +300,32 @@ static void clk_rpm_unprepare(struct clk_hw *hw) mutex_unlock(&rpm_clk_lock); } +static int clk_rpm_fixed_prepare(struct clk_hw *hw) +{ + struct clk_rpm *r = to_clk_rpm(hw); + u32 value = 1; + int ret; + + ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, + r->rpm_clk_id, &value, 1); + if (!ret) + r->enabled = true; + + return ret; +} + +static void clk_rpm_fixed_unprepare(struct clk_hw *hw) +{ + struct clk_rpm *r = to_clk_rpm(hw); + u32 value = 0; + int ret; + + ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, + r->rpm_clk_id, &value, 1); + if (!ret) + r->enabled = false; +} + static int clk_rpm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -333,6 +390,13 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw, return r->rate; } +static const struct clk_ops clk_rpm_fixed_ops = { + .prepare = clk_rpm_fixed_prepare, + .unprepare = clk_rpm_fixed_unprepare, + .round_rate = clk_rpm_round_rate, + .recalc_rate = clk_rpm_recalc_rate, +}; + static const struct clk_ops clk_rpm_ops = { .prepare = clk_rpm_prepare, .unprepare = clk_rpm_unprepare, @@ -348,6 +412,46 @@ static const struct clk_ops clk_rpm_branch_ops = { .recalc_rate = clk_rpm_recalc_rate, }; +/* MSM8660/APQ8060 */ +DEFINE_CLK_RPM_FIXED(msm8660, pll4_clk, pll4_a_clk, QCOM_RPM_PLL_4, 540672000); +DEFINE_CLK_RPM(msm8660, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK); +DEFINE_CLK_RPM(msm8660, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); +DEFINE_CLK_RPM(msm8660, mmfab_clk, mmfab_a_clk, QCOM_RPM_MM_FABRIC_CLK); +DEFINE_CLK_RPM(msm8660, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK); +DEFINE_CLK_RPM(msm8660, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); +DEFINE_CLK_RPM(msm8660, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK); +DEFINE_CLK_RPM(msm8660, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK); +DEFINE_CLK_RPM(msm8660, smi_clk, smi_a_clk, QCOM_RPM_SMI_CLK); +DEFINE_CLK_RPM(msm8660, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK); + +static struct clk_rpm *msm8660_clks[] = { + [RPM_PLL4_CLK] = &msm8660_pll4_clk, + [RPM_PLL4_A_CLK] = &msm8660_pll4_a_clk, + [RPM_APPS_FABRIC_CLK] = &msm8660_afab_clk, + [RPM_APPS_FABRIC_A_CLK] = &msm8660_afab_a_clk, + [RPM_SYS_FABRIC_CLK] = &msm8660_sfab_clk, + [RPM_SYS_FABRIC_A_CLK] = &msm8660_sfab_a_clk, + [RPM_MM_FABRIC_CLK] = &msm8660_mmfab_clk, + [RPM_MM_FABRIC_A_CLK] = &msm8660_mmfab_a_clk, + [RPM_DAYTONA_FABRIC_CLK] = &msm8660_daytona_clk, + [RPM_DAYTONA_FABRIC_A_CLK] = &msm8660_daytona_a_clk, + [RPM_SFPB_CLK] = &msm8660_sfpb_clk, + [RPM_SFPB_A_CLK] = &msm8660_sfpb_a_clk, + [RPM_CFPB_CLK] = &msm8660_cfpb_clk, + [RPM_CFPB_A_CLK] = &msm8660_cfpb_a_clk, + [RPM_MMFPB_CLK] = &msm8660_mmfpb_clk, + [RPM_MMFPB_A_CLK] = &msm8660_mmfpb_a_clk, + [RPM_SMI_CLK] = &msm8660_smi_clk, + [RPM_SMI_A_CLK] = &msm8660_smi_a_clk, + [RPM_EBI1_CLK] = &msm8660_ebi1_clk, + [RPM_EBI1_A_CLK] = &msm8660_ebi1_a_clk, +}; + +static const struct rpm_clk_desc rpm_clk_msm8660 = { + .clks = msm8660_clks, + .num_clks = ARRAY_SIZE(msm8660_clks), +}; + /* apq8064 */ DEFINE_CLK_RPM(apq8064, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK); DEFINE_CLK_RPM(apq8064, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK); @@ -386,6 +490,8 @@ static const struct rpm_clk_desc rpm_clk_apq8064 = { }; static const struct of_device_id rpm_clk_match_table[] = { + { .compatible = "qcom,rpmcc-msm8660", .data = &rpm_clk_msm8660 }, + { .compatible = "qcom,rpmcc-apq8060", .data = &rpm_clk_msm8660 }, { .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 }, { } }; From patchwork Wed Apr 19 09:13:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 97615 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp229381qgf; Wed, 19 Apr 2017 02:13:57 -0700 (PDT) X-Received: by 10.99.38.196 with SMTP id m187mr1970241pgm.195.1492593237234; Wed, 19 Apr 2017 02:13:57 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k8si1879303pgp.133.2017.04.19.02.13.56; Wed, 19 Apr 2017 02:13:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933612AbdDSJN4 (ORCPT + 9 others); Wed, 19 Apr 2017 05:13:56 -0400 Received: from mail-lf0-f41.google.com ([209.85.215.41]:32919 "EHLO mail-lf0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761392AbdDSJNt (ORCPT ); Wed, 19 Apr 2017 05:13:49 -0400 Received: by mail-lf0-f41.google.com with SMTP id 88so8965107lfr.0 for ; Wed, 19 Apr 2017 02:13:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GfhPzbe4vib9MtsL77IGpSl2BLNU5TQsi/Ublt1KNG0=; b=NswZj41HjVV6Lwpa9AatXPlxVHH39OSnxhXp1W45FkcFd/X5rjC4rsm02GOIiuHas2 7Fr3K5pPDb9NzFdJBn2KytTLOB/n5a+IQn5zjQZrVh3Y3QfmlEnr/4/eZ75fofeOQ9bW B2AK0hP5AWx2soWFeka3JGwy/CqHO+eD46+b4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GfhPzbe4vib9MtsL77IGpSl2BLNU5TQsi/Ublt1KNG0=; b=IKSk87rDwrI36ylHUR894pq+6PgZiyGwf02kEWD710MxImiVUUjHWAYBQCxE7Yxf8K NjH2XknXoTK8Cv5L1bJhVICvJwV2XyRmXqw1wmmRp+cTsVDJoVwmrqT+d0Qs/DuO/o0j NxPYC1DofBlpNZb1BqcSz3IfIaWEVmuXLr0XthrsmAzYVm3KgTL7OZKMTrMi1v3w9tzh N2vN0217Q1qeJsiRWiymfMLITbxD/4NVEEqS3eT5RTBI+A2IideqhQMj9ComTnZgXI8f xdiwx6j4cKqXKkSOnwy8kQlaV5D1oi/FNNE03wTqBg1O8U3s6IGBxf1Esx/o7kltFr3T fXtg== X-Gm-Message-State: AN3rC/5O0tsDuZsRNO3PIPtcIbHNpABZGl5e4j7+Vip/f9hMARNW/WvT t1bsclkLvW/Ij2ps X-Received: by 10.25.228.209 with SMTP id x78mr586812lfi.145.1492593228296; Wed, 19 Apr 2017 02:13:48 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id q123sm303230ljb.18.2017.04.19.02.13.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Apr 2017 02:13:47 -0700 (PDT) From: Linus Walleij To: Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-arm-msm@vger.kernel.org, Linus Walleij , devicetree@vger.kernel.org Subject: [PATCH 4/5 v2] clk: qcom: Update DT bindings for MSM8660 LCC Date: Wed, 19 Apr 2017 11:13:25 +0200 Message-Id: <20170419091326.11226-4-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170419091326.11226-1-linus.walleij@linaro.org> References: <20170419091326.11226-1-linus.walleij@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This adds the right compatible string and header for the MSM8660 LCC and some new defines to the dt-bindings header. Take this opportunity to spell out the acronym LPASS for Low-power Audio Subsystem. Cc: devicetree@vger.kernel.org Acked-by: Rob Herring Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Add Rob's ACK. --- .../devicetree/bindings/clock/qcom,lcc.txt | 5 +-- include/dt-bindings/clock/qcom,lcc-msm8660.h | 40 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/clock/qcom,lcc-msm8660.h -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/clock/qcom,lcc.txt b/Documentation/devicetree/bindings/clock/qcom,lcc.txt index a3c78aa88038..4de51df37f1a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,lcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,lcc.txt @@ -1,10 +1,11 @@ -Qualcomm LPASS Clock & Reset Controller Binding ------------------------------------------------- +Qualcomm Low-power Audio Subsystem (LPASS) Clock & Reset Controller Binding +--------------------------------------------------------------------------- Required properties : - compatible : shall contain only one of the following: "qcom,lcc-msm8960" + "qcom,lcc-msm8660" "qcom,lcc-apq8064" "qcom,lcc-ipq8064" "qcom,lcc-mdm9615" diff --git a/include/dt-bindings/clock/qcom,lcc-msm8660.h b/include/dt-bindings/clock/qcom,lcc-msm8660.h new file mode 100644 index 000000000000..7cddcbd6b1ee --- /dev/null +++ b/include/dt-bindings/clock/qcom,lcc-msm8660.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Linus Walleij + * Qualcomm MSM8660 Low-power Audio Subsystem (LPASS) Clock Controller + * devicetree definitions + */ + +#ifndef _DT_BINDINGS_CLK_LCC_MSM8660_H +#define _DT_BINDINGS_CLK_LCC_MSM8660_H + +#define LPA_PLL0 0 +#define MI2S_OSR_SRC 1 +#define MI2S_OSR_CLK 2 +#define MI2S_DIV_CLK 3 +#define MI2S_BIT_DIV_CLK 4 +#define MI2S_BIT_CLK 5 +#define CODEC_I2S_MIC_OSR_SRC 6 +#define CODEC_I2S_MIC_OSR_CLK 7 +#define CODEC_I2S_MIC_DIV_CLK 8 +#define CODEC_I2S_MIC_BIT_DIV_CLK 9 +#define CODEC_I2S_MIC_BIT_CLK 10 +#define SPARE_I2S_MIC_OSR_SRC 11 +#define SPARE_I2S_MIC_OSR_CLK 12 +#define SPARE_I2S_MIC_DIV_CLK 13 +#define SPARE_I2S_MIC_BIT_DIV_CLK 14 +#define SPARE_I2S_MIC_BIT_CLK 15 +#define CODEC_I2S_SPKR_OSR_SRC 16 +#define CODEC_I2S_SPKR_OSR_CLK 17 +#define CODEC_I2S_SPKR_DIV_CLK 18 +#define CODEC_I2S_SPKR_BIT_DIV_CLK 19 +#define CODEC_I2S_SPKR_BIT_CLK 20 +#define SPARE_I2S_SPKR_OSR_SRC 21 +#define SPARE_I2S_SPKR_OSR_CLK 22 +#define SPARE_I2S_SPKR_DIV_CLK 23 +#define SPARE_I2S_SPKR_BIT_DIV_CLK 24 +#define SPARE_I2S_SPKR_BIT_CLK 25 +#define PCM_SRC 26 +#define PCM_CLK_OUT 27 +#define PCM_CLK 28 + +#endif From patchwork Wed Apr 19 09:13:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 97616 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp229406qgf; Wed, 19 Apr 2017 02:14:01 -0700 (PDT) X-Received: by 10.84.222.135 with SMTP id x7mr2715262pls.50.1492593241509; Wed, 19 Apr 2017 02:14:01 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k8si1879303pgp.133.2017.04.19.02.14.01; Wed, 19 Apr 2017 02:14:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933650AbdDSJOA (ORCPT + 9 others); Wed, 19 Apr 2017 05:14:00 -0400 Received: from mail-lf0-f54.google.com ([209.85.215.54]:36442 "EHLO mail-lf0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761438AbdDSJNw (ORCPT ); Wed, 19 Apr 2017 05:13:52 -0400 Received: by mail-lf0-f54.google.com with SMTP id c80so8903464lfh.3 for ; Wed, 19 Apr 2017 02:13:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=w/A9grQ/ACQtNl4NBJcENC7AyA1mua5ulF9+nwK8xho=; b=Lo5Yvplw1cDSHn2EClp1VzKk1RAmpUk4nOodROLVqrmLP32ku2OHMmXqgORh/TQO2r bTvfy5yxrpwJtkUYUg+DhBbS6jq6kWhlDt4KeGQ8WWnpdI/Yv+Cfn1Kz3EMKY+LMoSfu Whzo116lptX3Seo4lhG6QXwNLJTVxVrkWp7Ls= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=w/A9grQ/ACQtNl4NBJcENC7AyA1mua5ulF9+nwK8xho=; b=N5K5Zvq4h9S1iugwiYb0GTEy1y8NSqV5Hp8QggwQm7KXEO6r78S2X3zrVmA28lS7vJ VCs6oqOIKi/HzNzsoKGoZ8beNAjd1z41PevWqVwsAMuSQt+XXC6h8t7zWbfU/AFNPEeu o/NRc0bShXk1t0dqePjoFNtfC2vyDRlX9Yu3Xw7zOHZXMWK2fsSeKPGjDjFI+MJSCkVx amcvCnGMA7T5MLxtSB5jr0jcVpcDTMGEGPrw7h7YAOApm+O+f3x+tXbN2ujpxTOez96A OhH6SYqBQ1rwcvbG1Lwb02vfi9n6oHrFhMHPGZAEXkkFHVIcIB01YYCFTus71cxdteeF xKfQ== X-Gm-Message-State: AN3rC/7B6qe71GWP0k78ypxRR7R28icnBvyc84lNyY3uaBUIJRZ8Z3y6 wv2B0YO9xfs1fLs5 X-Received: by 10.25.89.75 with SMTP id n72mr705234lfb.163.1492593230785; Wed, 19 Apr 2017 02:13:50 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id q123sm303230ljb.18.2017.04.19.02.13.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Apr 2017 02:13:49 -0700 (PDT) From: Linus Walleij To: Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-arm-msm@vger.kernel.org, Linus Walleij Subject: [PATCH 5/5 v2] clk: qcom: Add support for MSM8660 LCC Date: Wed, 19 Apr 2017 11:13:26 +0200 Message-Id: <20170419091326.11226-5-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170419091326.11226-1-linus.walleij@linaro.org> References: <20170419091326.11226-1-linus.walleij@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This adds support for the MSM8660 Low-power audio subsystem (LPASS) clock controller (LCC). This is nice when you want to have audio from the system. We currently only support using the PLL4 (which is an RPM clock) as the parent, however the LPASS has its own PLL named LPA_PLL0 that we can experiment with enabling later on, so for this reason the code contains a few hints on how to enable the LPA_PLL0. Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - No changes. --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/lcc-msm8660.c | 418 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 428 insertions(+) create mode 100644 drivers/clk/qcom/lcc-msm8660.c -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 5fb8d7430908..d657d94d372f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -90,6 +90,15 @@ config MSM_GCC_8660 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, SD/eMMC, etc. +config MSM_LCC_8660 + tristate "MSM8660 LPASS Clock Controller" + select MSM_GCC_8660 + depends on COMMON_CLK_QCOM + help + Support for the Low-power Audio Subsystem (LPASS) clock controller + on MSM8660 devices. + Say Y if you want to use audio devices such as I2S and PCM. + config MSM_GCC_8916 tristate "MSM8916 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 1c3e222b917b..d6d5ab178522 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o +obj-$(CONFIG_MSM_LCC_8660) += lcc-msm8660.o obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o diff --git a/drivers/clk/qcom/lcc-msm8660.c b/drivers/clk/qcom/lcc-msm8660.c new file mode 100644 index 000000000000..73dc8ede6a2a --- /dev/null +++ b/drivers/clk/qcom/lcc-msm8660.c @@ -0,0 +1,418 @@ +/* + * Qualcomm MSM8660/APQ8060 Low-power Audio Subsystem (LPASS) Clock Controller + * Copyright (c) 2017 Linus Walleij + * + * Based on a copy of the IPQ806x driver + * (C) 2014 Rajendra Nayak + * and portions of the MDM9615 driver + * (C) 2014 Neil Armstrong. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" + +/* + * The vendor tree calls this "PLL0" but we are going to refer to it as + * LPA_PLL0 so as not to confuse it with the PLL0 on the GCC. + */ +static struct clk_pll lpa_pll0 = { + .l_reg = 0x4, + .m_reg = 0x8, + .n_reg = 0xc, + .config_reg = 0x14, + .mode_reg = 0x0, + .status_reg = 0x18, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "lpa_pll0", + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +/* + * The l/m/n values were read out of the registers after a cold boot. + * The config register read 00c22080 and the mode register 0x00000007. + */ +static const struct pll_config lpa_pll0_config = { + .l = 0xf, + .m = 0x1c, + .n = 0x465, + .vco_val = BIT(17), + .vco_mask = BIT(17) | BIT(16), + .pre_div_val = 0x0, + .pre_div_mask = BIT(19), + .post_div_val = 0x0, + .post_div_mask = BIT(21) | BIT(20), + .mn_ena_mask = BIT(22), + .main_output_mask = BIT(23), +}; + +enum { + P_PXO, + P_CXO, + P_PLL4_LPA_PLL0, + P_GND, +}; + +/* The vendor code uses PLL4 as parent everywhere */ +static const struct parent_map lcc_parent_map[] = { + { P_PXO, 0 }, + { P_CXO, 1 }, + /* Select RPM PLL4, but also used for selecting LPA PLL0 */ + { P_PLL4_LPA_PLL0, 2 }, + /* Will just ground the line */ + { P_GND, 6 }, +}; + +static const char * const lcc_parent_tbl[] = { + "pxo", + "cxo", + /* + * PLL4 is an RPM clock on MSM8660/APQ8060, set to "pll4" for this + * If we enable and mux in the LPA_PLL0 on this platform, we can + * set this to "lpa_pll0" instead + */ + "pll4_clk", + "gnd", /* This is a very inactive parent */ +}; + +/* + * This table is evidently for using PLL4 as parent, if we start using + * LPA_PLL0 we need to provide a second table. + */ +static struct freq_tbl clk_tbl_aif_osr_pll4[] = { + { 768000, P_PLL4_LPA_PLL0, 4, 1, 176 }, + { 1024000, P_PLL4_LPA_PLL0, 4, 1, 132 }, + { 1536000, P_PLL4_LPA_PLL0, 4, 1, 88 }, + { 2048000, P_PLL4_LPA_PLL0, 4, 1, 66 }, + { 3072000, P_PLL4_LPA_PLL0, 4, 1, 44 }, + { 4096000, P_PLL4_LPA_PLL0, 4, 1, 33 }, + { 6144000, P_PLL4_LPA_PLL0, 4, 1, 22 }, + { 8192000, P_PLL4_LPA_PLL0, 2, 1, 33 }, + { 12288000, P_PLL4_LPA_PLL0, 4, 1, 11 }, + { 24576000, P_PLL4_LPA_PLL0, 2, 1, 11 }, + { 27000000, P_PXO, 1, 0, 0 }, + { } +}; + +/* + * This macro is modified from lcc-mdm9516.c, it's used for all the + * AIF clocks, all of them have an OSR clock and a bit clock derived + * from the OSR clock. + * + * These clocks differ from many other platforms by using + * BRANCH_HALT_DELAY for the *_bit_div_clk + */ +#define CLK_AIF_OSR_DIV(prefix, _ns, _md, _hr) \ +static struct clk_rcg prefix##_osr_src = { \ + .ns_reg = _ns, \ + .md_reg = _md, \ + .mn = { \ + .mnctr_en_bit = 8, \ + .mnctr_reset_bit = 7, \ + .mnctr_mode_shift = 5, \ + .n_val_shift = 24, \ + .m_val_shift = 8, \ + .width = 8, \ + }, \ + .p = { \ + .pre_div_shift = 3, \ + .pre_div_width = 2, \ + }, \ + .s = { \ + .src_sel_shift = 0, \ + .parent_map = lcc_parent_map, \ + }, \ + .freq_tbl = clk_tbl_aif_osr_pll4, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(9), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_osr_src", \ + .parent_names = lcc_parent_tbl, \ + .num_parents = 4, \ + .ops = &clk_rcg_ops, \ + .flags = CLK_SET_RATE_GATE, \ + }, \ + }, \ +}; \ + \ +static const char * const lcc_##prefix##_parents[] = { \ + #prefix "_osr_src", \ +}; \ + \ +static struct clk_branch prefix##_osr_clk = { \ + .halt_reg = _hr, \ + .halt_bit = 1, \ + .halt_check = BRANCH_HALT_ENABLE, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(17), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_osr_clk", \ + .parent_names = lcc_##prefix##_parents, \ + .num_parents = 1, \ + .ops = &clk_branch_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + \ +static struct clk_regmap_div prefix##_div_clk = { \ + .reg = _ns, \ + .shift = 10, \ + .width = 4, \ + .clkr = { \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_div_clk", \ + .parent_names = lcc_##prefix##_parents, \ + .num_parents = 1, \ + .ops = &clk_regmap_div_ops, \ + }, \ + }, \ +}; \ + \ +static struct clk_branch prefix##_bit_div_clk = { \ + .halt_reg = _hr, \ + .halt_bit = 0, \ + .halt_check = BRANCH_HALT_DELAY, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(15), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_bit_div_clk", \ + .parent_names = (const char *[]){ \ + #prefix "_div_clk" \ + }, \ + .num_parents = 1, \ + .ops = &clk_branch_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + \ +static struct clk_regmap_mux prefix##_bit_clk = { \ + .reg = _ns, \ + .shift = 14, \ + .width = 1, \ + .clkr = { \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_bit_clk", \ + .parent_names = (const char *[]){ \ + #prefix "_bit_div_clk", \ + #prefix "_codec_clk", \ + }, \ + .num_parents = 2, \ + .ops = &clk_regmap_mux_closest_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +} + +CLK_AIF_OSR_DIV(mi2s, 0x48, 0x4c, 0x50); +CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68); +CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80); +CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74); +CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c); + +/* + * PCM clock + * This table is evidently for using PLL4 as parent, if we start using + * LPA_PLL0 we need to provide a second table. + */ +static struct freq_tbl clk_tbl_pcm_pll4[] = { + { 512000, P_PLL4_LPA_PLL0, 4, 1, 264 }, + { 768000, P_PLL4_LPA_PLL0, 4, 1, 176 }, + { 1024000, P_PLL4_LPA_PLL0, 4, 1, 132 }, + { 1536000, P_PLL4_LPA_PLL0, 4, 1, 88 }, + { 2048000, P_PLL4_LPA_PLL0, 4, 1, 66 }, + { 3072000, P_PLL4_LPA_PLL0, 4, 1, 44 }, + { 4096000, P_PLL4_LPA_PLL0, 4, 1, 33 }, + { 6144000, P_PLL4_LPA_PLL0, 4, 1, 22 }, + { 8192000, P_PLL4_LPA_PLL0, 2, 1, 33 }, + { 12288000, P_PLL4_LPA_PLL0, 4, 1, 11 }, + { 24580000, P_PLL4_LPA_PLL0, 2, 1, 11 }, + { 27000000, P_PXO, 1, 0, 0 }, + { }, +}; + +static struct clk_rcg pcm_src = { + .ns_reg = 0x54, + .md_reg = 0x58, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = lcc_parent_map, + }, + .freq_tbl = clk_tbl_pcm_pll4, + .clkr = { + .enable_reg = 0x54, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "pcm_src", + .parent_names = lcc_parent_tbl, + .num_parents = 4, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + }, +}; + +static struct clk_branch pcm_clk_out = { + .halt_reg = 0x5c, + .halt_bit = 0, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0x54, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "pcm_clk_out", + .parent_names = (const char *[]){ "pcm_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_mux pcm_clk = { + .reg = 0x54, + .shift = 10, + .width = 1, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "pcm_clk", + .parent_names = (const char *[]){ + "pcm_clk_out", + "pcm_codec_clk", + }, + .num_parents = 2, + .ops = &clk_regmap_mux_closest_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap *lcc_msm8660_clks[] = { + [LPA_PLL0] = &lpa_pll0.clkr, + [MI2S_OSR_SRC] = &mi2s_osr_src.clkr, + [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr, + [MI2S_DIV_CLK] = &mi2s_div_clk.clkr, + [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr, + [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr, + [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr, + [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr, + [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr, + [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr, + [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr, + [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr, + [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr, + [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr, + [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr, + [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr, + [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr, + [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr, + [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr, + [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr, + [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr, + [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr, + [PCM_SRC] = &pcm_src.clkr, + [PCM_CLK_OUT] = &pcm_clk_out.clkr, + [PCM_CLK] = &pcm_clk.clkr, +}; + +static const struct regmap_config lcc_msm8660_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xfc, + .fast_io = true, +}; + +static const struct qcom_cc_desc lcc_msm8660_desc = { + .config = &lcc_msm8660_regmap_config, + .clks = lcc_msm8660_clks, + .num_clks = ARRAY_SIZE(lcc_msm8660_clks), +}; + +static const struct of_device_id lcc_msm8660_match_table[] = { + { .compatible = "qcom,lcc-msm8660" }, + { } +}; +MODULE_DEVICE_TABLE(of, lcc_msm8660_match_table); + +static int lcc_msm8660_probe(struct platform_device *pdev) +{ + u32 val; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &lcc_msm8660_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Configure the rate of LPA_PLL0 if the bootloader hasn't already */ + regmap_read(regmap, 0x0, &val); + if (!val) { + dev_info(&pdev->dev, "configuring LPA_PLL0\n"); + clk_pll_configure_sr(&lpa_pll0, regmap, &lpa_pll0_config, true); + } else { + dev_info(&pdev->dev, + "LPA_PLL0 already configured\n"); + } + + /* + * Enable LPA_PLL0 source on the LPASS Primary PLL Mux. Incidentally + * this is set to 0x00000001 at boot. + * 0x01 = LPA_PLL0 + */ + regmap_write(regmap, 0xc4, 0x1); + + return qcom_cc_really_probe(pdev, &lcc_msm8660_desc, regmap); +} + +static struct platform_driver lcc_msm8660_driver = { + .probe = lcc_msm8660_probe, + .driver = { + .name = "lcc-msm8660", + .of_match_table = lcc_msm8660_match_table, + }, +}; +module_platform_driver(lcc_msm8660_driver); + +MODULE_DESCRIPTION("QCOM LCC MSM8660 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:lcc-msm8660");