From patchwork Sun Mar 18 14:44:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 10291191 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 95D4A600F6 for ; Sun, 18 Mar 2018 14:46:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8586628F60 for ; Sun, 18 Mar 2018 14:46:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A33228F73; Sun, 18 Mar 2018 14:46:19 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0090D28F60 for ; Sun, 18 Mar 2018 14:46:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754276AbeCROqP (ORCPT ); Sun, 18 Mar 2018 10:46:15 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:34949 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754223AbeCROqO (ORCPT ); Sun, 18 Mar 2018 10:46:14 -0400 Received: by mail-wm0-f68.google.com with SMTP id r82so359124wme.0 for ; Sun, 18 Mar 2018 07:46:13 -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; bh=fDS2oGSPevSb6g5TUmmRIgjYQ+ictsbWIsLiuZlrdxY=; b=Te5MS1wQe31+3uBIBZv/3qShpWrijJ+ZJWLtSBcDM/j4NTimRVMt+HF/X2kaO29z3w L+c+JKBKO//y0qoqsu1CpSqXZe4JRd78o0/B9Uh0yoa8NSw2RJvlXmEIlZzdsri0wbST fONn+yir+cuI9bp9Wa4VWNl637crycL7QjdQs= 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; bh=fDS2oGSPevSb6g5TUmmRIgjYQ+ictsbWIsLiuZlrdxY=; b=gd69gjMQcjh7UiJw8vy+cNmS4UqjQ4bkqkgDgevWBFBpsu7WB98L2LLwragQZ6hX5p QE1PNsK1CYbC+gEwaQewabksjVQwKM1SGs9xo+7C4im7X6iNrh5FOMGKzN4JMhWo6wMG AgVI57LOsGpDBEKScZpLrIHCfbgHFetMQynnh34bdiTx/0s3OEcLELCk/gqfweEcnrK9 NRVz7ch+XVaU5oVPUwvJaty9QUOIfiU4MZz1x9lQbj/y1Mz/+SHHBWiDcn/I2pf+ZRjC cSmzngLLIAN2OfTIYmi4WxBVbokEkoT6rj+lRAY56N3gG46MdqADKYPBMzUqKkF5r3C9 pvkg== X-Gm-Message-State: AElRT7GX4Iu+qeWYreA0WcoBCYbY7SpAxbqQmnXh0zs/F+vUayU833zE QBUaNWUk4nI4CyEmECc17Z8jfQ== X-Google-Smtp-Source: AG47ELui924T8EpW7mieuhQJayfwjDTSfovPProH+2HEdwoUFNJ9LbJ6L/h0l3t4hDONkb7FK06BvQ== X-Received: by 10.28.92.208 with SMTP id q199mr5969824wmb.91.1521384372904; Sun, 18 Mar 2018 07:46:12 -0700 (PDT) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id w134sm10257528wmd.45.2018.03.18.07.46.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 18 Mar 2018 07:46:11 -0700 (PDT) From: srinivas.kandagatla@linaro.org To: Stephen Boyd , andy.gross@linaro.org, linux-clk@vger.kernel.org, linux-arm-msm@vger.kernel.org Cc: david.brown@linaro.org, mturquette@baylibre.com, robh+dt@kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, georgi.djakov@linaro.org, Srinivas Kandagatla Subject: [PATCH v2] clk: qcom: rpmcc: Add support to XO buffered clocks Date: Sun, 18 Mar 2018 14:44:01 +0000 Message-Id: <20180318144401.21904-1-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.16.2 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Srinivas Kandagatla XO is onchip buffer clock to generate 19.2MHz. This patch adds support to 5 XO buffer clocks found on PMIC8921, these buffer clocks can be controlled from external pin or in manual mode. Signed-off-by: Srinivas Kandagatla --- Changes since v1: - Made buffer clk word global and protected it by mutex, suggested by S Boyd. - removed rate from clock define as it can be derived from parent clk rate, suggested by S Boyd. drivers/clk/qcom/clk-rpm.c | 79 +++++++++++++++++++++++++++++++++- include/dt-bindings/clock/qcom,rpmcc.h | 5 +++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rpm.c b/drivers/clk/qcom/clk-rpm.c index c60f61b10c7f..b94981447664 100644 --- a/drivers/clk/qcom/clk-rpm.c +++ b/drivers/clk/qcom/clk-rpm.c @@ -29,6 +29,7 @@ #define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63 #define QCOM_RPM_SCALING_ENABLE_ID 0x2 +#define QCOM_RPM_XO_MODE_ON 0x2 #define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \ static struct clk_rpm _platform##_##_active; \ @@ -56,6 +57,18 @@ }, \ } +#define DEFINE_CLK_RPM_XO_BUFFER(_platform, _name, _active, offset) \ + static struct clk_rpm _platform##_##_name = { \ + .rpm_clk_id = QCOM_RPM_CXO_BUFFERS, \ + .xo_offset = (offset), \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_rpm_xo_ops, \ + .name = #_name, \ + .parent_names = (const char *[]){ "cxo_board" }, \ + .num_parents = 1, \ + }, \ + } + #define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \ static struct clk_rpm _platform##_##_name = { \ .rpm_clk_id = (r_id), \ @@ -126,8 +139,11 @@ #define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw) +struct rpm_cc; + struct clk_rpm { const int rpm_clk_id; + const int xo_offset; const bool active_only; unsigned long rate; bool enabled; @@ -135,12 +151,15 @@ struct clk_rpm { struct clk_rpm *peer; struct clk_hw hw; struct qcom_rpm *rpm; + struct rpm_cc *rpm_cc; }; struct rpm_cc { struct qcom_rpm *rpm; struct clk_rpm **clks; size_t num_clks; + u32 xo_buffer_value; + struct mutex xo_lock; }; struct rpm_clk_desc { @@ -159,7 +178,8 @@ static int clk_rpm_handoff(struct clk_rpm *r) * The vendor tree simply reads the status for this * RPM clock. */ - if (r->rpm_clk_id == QCOM_RPM_PLL_4) + if (r->rpm_clk_id == QCOM_RPM_PLL_4 || + r->rpm_clk_id == QCOM_RPM_CXO_BUFFERS) return 0; ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, @@ -288,6 +308,46 @@ static void clk_rpm_unprepare(struct clk_hw *hw) mutex_unlock(&rpm_clk_lock); } +static int clk_rpm_xo_prepare(struct clk_hw *hw) +{ + struct clk_rpm *r = to_clk_rpm(hw); + struct rpm_cc *rcc = r->rpm_cc; + int ret, clk_id = r->rpm_clk_id; + u32 value; + + mutex_lock(&rcc->xo_lock); + + value = rcc->xo_buffer_value | (QCOM_RPM_XO_MODE_ON << r->xo_offset); + ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1); + if (!ret) { + r->enabled = true; + rcc->xo_buffer_value = value; + } + + mutex_unlock(&rcc->xo_lock); + + return ret; +} + +static void clk_rpm_xo_unprepare(struct clk_hw *hw) +{ + struct clk_rpm *r = to_clk_rpm(hw); + struct rpm_cc *rcc = r->rpm_cc; + int ret, clk_id = r->rpm_clk_id; + u32 value; + + mutex_lock(&rcc->xo_lock); + + value = rcc->xo_buffer_value & ~(QCOM_RPM_XO_MODE_ON << r->xo_offset); + ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1); + if (!ret) { + r->enabled = false; + rcc->xo_buffer_value = value; + } + + mutex_unlock(&rcc->xo_lock); +} + static int clk_rpm_fixed_prepare(struct clk_hw *hw) { struct clk_rpm *r = to_clk_rpm(hw); @@ -378,6 +438,11 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw, return r->rate; } +static const struct clk_ops clk_rpm_xo_ops = { + .prepare = clk_rpm_xo_prepare, + .unprepare = clk_rpm_xo_unprepare, +}; + static const struct clk_ops clk_rpm_fixed_ops = { .prepare = clk_rpm_fixed_prepare, .unprepare = clk_rpm_fixed_unprepare, @@ -449,6 +514,11 @@ DEFINE_CLK_RPM(apq8064, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK); DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK); DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK); DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK); +DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d0_clk, xo_d0_a_clk, 0); +DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d1_clk, xo_d1_a_clk, 8); +DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a0_clk, xo_a0_a_clk, 16); +DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a1_clk, xo_a1_a_clk, 24); +DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a2_clk, xo_a2_a_clk, 28); static struct clk_rpm *apq8064_clks[] = { [RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk, @@ -469,6 +539,11 @@ static struct clk_rpm *apq8064_clks[] = { [RPM_SFPB_A_CLK] = &apq8064_sfpb_a_clk, [RPM_QDSS_CLK] = &apq8064_qdss_clk, [RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk, + [RPM_XO_D0] = &apq8064_xo_d0_clk, + [RPM_XO_D1] = &apq8064_xo_d1_clk, + [RPM_XO_A0] = &apq8064_xo_a0_clk, + [RPM_XO_A1] = &apq8064_xo_a1_clk, + [RPM_XO_A2] = &apq8064_xo_a2_clk, }; static const struct rpm_clk_desc rpm_clk_apq8064 = { @@ -526,12 +601,14 @@ static int rpm_clk_probe(struct platform_device *pdev) rcc->clks = rpm_clks; rcc->num_clks = num_clks; + mutex_init(&rcc->xo_lock); for (i = 0; i < num_clks; i++) { if (!rpm_clks[i]) continue; rpm_clks[i]->rpm = rpm; + rpm_clks[i]->rpm_cc = rcc; ret = clk_rpm_handoff(rpm_clks[i]); if (ret) diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h index b8337a5fa347..c585b82b9c05 100644 --- a/include/dt-bindings/clock/qcom,rpmcc.h +++ b/include/dt-bindings/clock/qcom,rpmcc.h @@ -40,6 +40,11 @@ #define RPM_SMI_CLK 22 #define RPM_SMI_A_CLK 23 #define RPM_PLL4_CLK 24 +#define RPM_XO_D0 25 +#define RPM_XO_D1 26 +#define RPM_XO_A0 27 +#define RPM_XO_A1 28 +#define RPM_XO_A2 29 /* SMD RPM clocks */ #define RPM_SMD_XO_CLK_SRC 0