From patchwork Fri Jun 3 08:44:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 12868811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 050F7CCA47C for ; Fri, 3 Jun 2022 08:45:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242871AbiFCIpB (ORCPT ); Fri, 3 Jun 2022 04:45:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34314 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242865AbiFCIpA (ORCPT ); Fri, 3 Jun 2022 04:45:00 -0400 Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A991436E1D for ; Fri, 3 Jun 2022 01:44:58 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id 1so7745314ljp.8 for ; Fri, 03 Jun 2022 01:44:58 -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 :mime-version:content-transfer-encoding; bh=X0V6BYnaPhxh7sNHV1/VEW9TfsvsIk7K2y2VHazjUm4=; b=pXoogqiEZcsyJZp/nP3rMMWNbxdxW6meN0/jsQS2ZBTrxYZq+mLQKYLh0I3JKAySc+ l7I9/cmFnUv3YEq0jPYolBlpdfBpKFNJq+Kvwukrl/6+1aLLexSc7daOe96GN+ahTKEn YezBbT+86+T5YySxraqom725e9jmey796ti8edrZ8GNv+xahDyZIJ4RzzdzwhT4awTmT i2nZwG4XbvWPSrwT5nAXWkiFXz8l1Ix814OvU4DCXm7Df+0nlDjoypVNbLl+2fBY9m5N GyFyTmx0x0e0pzQYkfU8k1rNIRGDSk15ek89ksZPh0VM8mH/r/WhXsY26Z6yiXWIGDRM IkgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X0V6BYnaPhxh7sNHV1/VEW9TfsvsIk7K2y2VHazjUm4=; b=WJX432l+7UO1nYfCvaSRNvJD8S5VR5r5cioFAqk6EDeSHKDo8zAlgv1Z7KSrsQSgxl 99X3v36CrasQoDgCKXZlxcTectbiJbxAu4h1ourhbnX1xasEi5+AD2mFGva+QjbXVxsy 0pgFAru0JpXdSfWfHXwqBZ7utn8OIY8bi3KQft6VLv+GCZ9J+tcXNem+hBBbSWOuC4x8 XNm+sH6/ylzjzRLFFw0dYEaw97bxklyosL0Ucs3RQDcZV/yVLJPEJ/Ghv+HIMFS9gXGQ 1THK3TvD0wJE2jeEcj8NOI3df09hcOpTdqJJi+QB4RbKIINHkz01fmjDojTziaLwHZRg e/BQ== X-Gm-Message-State: AOAM531b4xP/EBQt3B5HB3350XXW+BphjnRjuBymeeucIugRY50SpLBe FPyNp3lshVcptOqnfqEH+kOv1A== X-Google-Smtp-Source: ABdhPJwMiS4YdG5vMPSOB31RgMvyoDODfczKQcycIlEZPc9n9i5aJ4LR6qYOu0mGPUcMCllEfAMaVw== X-Received: by 2002:a2e:a810:0:b0:253:cb18:9058 with SMTP id l16-20020a2ea810000000b00253cb189058mr44301815ljq.12.1654245896789; Fri, 03 Jun 2022 01:44:56 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id b7-20020a0565120b8700b00478f8c9d402sm1474817lfv.20.2022.06.03.01.44.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Jun 2022 01:44:56 -0700 (PDT) From: Dmitry Baryshkov To: Andy Gross , Bjorn Andersson , Stephen Boyd , Michael Turquette , Taniya Das , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= =?utf-8?q?=C5=84ski?= , Bjorn Helgaas Cc: Johan Hovold , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, linux-pci@vger.kernel.org Subject: [PATCH v10 1/5] clk: qcom: regmap: add PHY clock source implementation Date: Fri, 3 Jun 2022 11:44:50 +0300 Message-Id: <20220603084454.1861142-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220603084454.1861142-1-dmitry.baryshkov@linaro.org> References: <20220603084454.1861142-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org On recent Qualcomm platforms the QMP PIPE clocks feed into a set of muxes which must be parked to the "safe" source (bi_tcxo) when corresponding GDSC is turned off and on again. Currently this is handcoded in the PCIe driver by reparenting the gcc_pipe_N_clk_src clock. However the same code sequence should be applied in the pcie-qcom endpoint, USB3 and UFS drivers. Rather than copying this sequence over and over again, follow the example of clk_rcg2_shared_ops and implement this parking in the enable() and disable() clock operations. Supplement the regmap-mux with the new clk_regmap_phy_mux type, which implements such multiplexers as a simple gate clocks. This is possible since each of these multiplexers has just two clock sources: one coming from the PHY and a reference (XO) one. If the clock is running off the from-PHY source, report it as enabled. Report it as disabled otherwise (if it uses reference source). This way the PHY will disable the pipe clock before turning off the GDSC, which in turn would lead to disabling corresponding pipe_clk_src (and thus it being parked to a safe, reference clock source). And vice versa, after enabling the GDSC the PHY will enable the pipe clock, which would cause pipe_clk_src to be switched from a safe source to the working one. Reviewed-by: Johan Hovold Tested-by: Johan Hovold Signed-off-by: Dmitry Baryshkov Reported-by: kernel test robot --- drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-regmap-phy-mux.c | 62 +++++++++++++++++++++++++++ drivers/clk/qcom/clk-regmap-phy-mux.h | 33 ++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 drivers/clk/qcom/clk-regmap-phy-mux.c create mode 100644 drivers/clk/qcom/clk-regmap-phy-mux.h diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 36789f5233ef..08594230c1c1 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -11,6 +11,7 @@ clk-qcom-y += clk-branch.o clk-qcom-y += clk-regmap-divider.o clk-qcom-y += clk-regmap-mux.o clk-qcom-y += clk-regmap-mux-div.o +clk-qcom-y += clk-regmap-phy-mux.o clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o clk-qcom-y += clk-hfpll.o clk-qcom-y += reset.o diff --git a/drivers/clk/qcom/clk-regmap-phy-mux.c b/drivers/clk/qcom/clk-regmap-phy-mux.c new file mode 100644 index 000000000000..a1adc075b471 --- /dev/null +++ b/drivers/clk/qcom/clk-regmap-phy-mux.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, Linaro Ltd. + */ + +#include +#include +#include +#include + +#include "clk-regmap.h" +#include "clk-regmap-phy-mux.h" + +#define PHY_MUX_MASK GENMASK(1, 0) +#define PHY_MUX_PHY_SRC 0 +#define PHY_MUX_REF_SRC 2 + +static inline struct clk_regmap_phy_mux *to_clk_regmap_phy_mux(struct clk_regmap *clkr) +{ + return container_of(clkr, struct clk_regmap_phy_mux, clkr); +} + +static int phy_mux_is_enabled(struct clk_hw *hw) +{ + struct clk_regmap *clkr = to_clk_regmap(hw); + struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr); + unsigned int val; + + regmap_read(clkr->regmap, phy_mux->reg, &val); + val = FIELD_GET(PHY_MUX_MASK, val); + + WARN_ON(val != PHY_MUX_PHY_SRC && val != PHY_MUX_REF_SRC); + + return val == PHY_MUX_PHY_SRC; +} + +static int phy_mux_enable(struct clk_hw *hw) +{ + struct clk_regmap *clkr = to_clk_regmap(hw); + struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr); + + return regmap_update_bits(clkr->regmap, phy_mux->reg, + PHY_MUX_MASK, + FIELD_PREP(PHY_MUX_MASK, PHY_MUX_PHY_SRC)); +} + +static void phy_mux_disable(struct clk_hw *hw) +{ + struct clk_regmap *clkr = to_clk_regmap(hw); + struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr); + + regmap_update_bits(clkr->regmap, phy_mux->reg, + PHY_MUX_MASK, + FIELD_PREP(PHY_MUX_MASK, PHY_MUX_REF_SRC)); +} + +const struct clk_ops clk_regmap_phy_mux_ops = { + .enable = phy_mux_enable, + .disable = phy_mux_disable, + .is_enabled = phy_mux_is_enabled, +}; +EXPORT_SYMBOL_GPL(clk_regmap_phy_mux_ops); diff --git a/drivers/clk/qcom/clk-regmap-phy-mux.h b/drivers/clk/qcom/clk-regmap-phy-mux.h new file mode 100644 index 000000000000..614dd384695c --- /dev/null +++ b/drivers/clk/qcom/clk-regmap-phy-mux.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022, Linaro Ltd. + */ + +#ifndef __QCOM_CLK_REGMAP_PHY_MUX_H__ +#define __QCOM_CLK_REGMAP_PHY_MUX_H__ + +#include "clk-regmap.h" + +/* + * A clock implementation for PHY pipe and symbols clock muxes. + * + * If the clock is running off the from-PHY source, report it as enabled. + * Report it as disabled otherwise (if it uses reference source). + * + * This way the PHY will disable the pipe clock before turning off the GDSC, + * which in turn would lead to disabling corresponding pipe_clk_src (and thus + * it being parked to a safe, reference clock source). And vice versa, after + * enabling the GDSC the PHY will enable the pipe clock, which would cause + * pipe_clk_src to be switched from a safe source to the working one. + * + * For some platforms this should be used for the UFS symbol_clk_src clocks + * too. + */ +struct clk_regmap_phy_mux { + u32 reg; + struct clk_regmap clkr; +}; + +extern const struct clk_ops clk_regmap_phy_mux_ops; + +#endif