From patchwork Fri May 20 01:58:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 575056 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 34438C43219 for ; Fri, 20 May 2022 01:58:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344624AbiETB6x (ORCPT ); Thu, 19 May 2022 21:58:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344602AbiETB6w (ORCPT ); Thu, 19 May 2022 21:58:52 -0400 Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF63AEC334 for ; Thu, 19 May 2022 18:58:50 -0700 (PDT) Received: by mail-lj1-x22d.google.com with SMTP id e4so7597185ljb.13 for ; Thu, 19 May 2022 18:58:50 -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=E5Gh1ILAKMW/krfK9XLvKTPNo78YRm/rpFUA2qFfucc=; b=PrRAnngSwlX6D6mqDDsgAgMzBeSfhpB6DXkKUSuHT+EB4gSloIlqbwdK39q1cMQJN4 vaS2NfxKLT+MdfYIrBdEDD94tFYgKaw4jO+tuHS8kYVKjmvIPTqGfMNHiikA/JwSO5eW yqvlDPbNkKdF/zdhvgcXTpkrl6VNiEk0xETM6FKSSpZHpnb/YmLuRiseIaAozTG5oMmU Q0/bcwDSeTsTzflcb9CgvLR24fInQenj8P4UCQY1sdAK+q9pAGD3/ViyKC0fMB0df9ht kcSVqz6ctOnslviMN0WPEsuBizFgDVgzuplT6T6upGB6Y1Eqghxu6TuvrThQZz4Pgsz9 Ingg== 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=E5Gh1ILAKMW/krfK9XLvKTPNo78YRm/rpFUA2qFfucc=; b=BOI+hagsFXHXSKVluO609rGxT1rhd1Y7DTdIeRHM7o7Rt1YsyYD1U6Xy1Rz5GxJba6 It/4LoWu/ZXzqrxoSCsbRmftR00ydaJyphgzof+VI2MpKgVS1H/STlo9LArDEoL7O2fV 7Ja8+rGCeXTmSH6+e34A7ek/ig6rQzV7xB+CtMOjKCwM4w5CEmeRks+2UsB9GEEKbl/u Yv5MinTds4nX3P1yjDgOOuuv69mJxScf8UOEkPZaBCQJeIPaNKwghGUjKYHHomWVy6E9 fZCrnTrAqtygUbHa8d445QO29/EI6LWB4W3IB2T6kplkRcPfYo2VzUG2SLpwD4DLfJsL Iq3g== X-Gm-Message-State: AOAM531LczYE9ruDGNs15oRuAfjHZ/ykecjhOJHN5WjSKQuGvoPllXp/ JYt/4yLhMjBUvge3wrwPThKqJw== X-Google-Smtp-Source: ABdhPJzVHp6BUQNcGumdiUbW1R5UPYGdWR6Ct95wy4vMM9zqwfrYwlRw2NRDATNJl7n6qQIykkPNBg== X-Received: by 2002:a2e:944a:0:b0:24f:10bd:b7e8 with SMTP id o10-20020a2e944a000000b0024f10bdb7e8mr4373363ljh.238.1653011930212; Thu, 19 May 2022 18:58:50 -0700 (PDT) Received: from eriador.lan ([2001:470:dd84:abc0::8a5]) by smtp.gmail.com with ESMTPSA id u28-20020ac24c3c000000b0047255d21192sm467370lfq.193.2022.05.19.18.58.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 18:58:49 -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 v7 2/6] clk: qcom: regmap: add PHY clock source implementation Date: Fri, 20 May 2022 04:58:40 +0300 Message-Id: <20220520015844.1190511-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520015844.1190511-1-dmitry.baryshkov@linaro.org> References: <20220520015844.1190511-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 --- drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/clk-regmap-phy-mux.c | 53 +++++++++++++++++++++++++++ drivers/clk/qcom/clk-regmap.h | 17 +++++++++ 3 files changed, 71 insertions(+) create mode 100644 drivers/clk/qcom/clk-regmap-phy-mux.c diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index dff6aeb980e6..6d242f46bd1d 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..dc96714a6175 --- /dev/null +++ b/drivers/clk/qcom/clk-regmap-phy-mux.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, Linaro Ltd. + */ + +#include +#include +#include +#include + +#include "clk-regmap.h" + +#define PHY_MUX_MASK GENMASK(1, 0) +#define PHY_MUX_PHY_SRC 0 +#define PHY_MUX_REF_SRC 2 + +static int phy_mux_is_enabled(struct clk_hw *hw) +{ + struct clk_regmap *clkr = to_clk_regmap(hw); + unsigned int val; + + regmap_read(clkr->regmap, clkr->enable_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); + + return regmap_update_bits(clkr->regmap, clkr->enable_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); + + regmap_update_bits(clkr->regmap, clkr->enable_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.h b/drivers/clk/qcom/clk-regmap.h index 14ec659a3a77..a58cd1d790fe 100644 --- a/drivers/clk/qcom/clk-regmap.h +++ b/drivers/clk/qcom/clk-regmap.h @@ -35,4 +35,21 @@ int clk_enable_regmap(struct clk_hw *hw); void clk_disable_regmap(struct clk_hw *hw); int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); +/* + * 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. + */ +extern const struct clk_ops clk_regmap_phy_mux_ops; + #endif