Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp932931pxb; Fri, 22 Apr 2022 14:42:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyUNZTXLTH0SAUp5/lnI4RdfsGLrtd1XCw5w5y5hnbM/CrcH/2YLqzC8rvKNZzjbjayoc58 X-Received: by 2002:a17:902:a588:b0:156:599c:6278 with SMTP id az8-20020a170902a58800b00156599c6278mr6362690plb.109.1650663727516; Fri, 22 Apr 2022 14:42:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650663727; cv=none; d=google.com; s=arc-20160816; b=sKeTFKUvM/nLMRGDPzw6necCfRMH2Ckop6PnxclRfhiakQM+gdzW3LEiby6e01QYdi wjBQHTZdwhS3K0FxVfQdlF5+NYaJ7Huh1sg3efRe1/rN6BbsuVV9iEHxf3HISt2a2T4V exTO/ivw1Qyb04+kcQyeM1Vtw+LwukzEu87OHZMT9y/oWAoSTfm9JMtOlZlybvL1VqDH lWDlA2l6LlEYIAvRHAC8gQ9lfa7c6YEMM4c46JdjImHXnFsVCBSXxIFrs1ypBZCh1ywV bV1982U8k5lVRgYCfPXyccapsKctOcgUppJZRvnI9ftxdbmqvhiWHgYaUFtqNQhAC3CF G5VA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7UbU+DYbuNhYDPrXotXpIgXmv+ftsrdtd0xaVlpQWR8=; b=r9gu8bTPD9y5PSEOhlovFaEpHcdUULHe/H9ZmweUiflKnb01lJrlHLWkMvmHalqxkj 4T9zTocnYF6Y68hfxIbWeo9sRw+v0b2MnkytRS/64cpskAVnGToqCsK2OiTZDdcKraQz HmsGLtoUXG3DSDhK9Mq3YHM1jHbVWFgdAbZu06KwDTK1tmwRI4GECF1NrHq4fuCMcczJ ynExeaWyuji7AyijdQzbBAYzLJPSToKlkz8gdTxlbqx3WX3U5UM5Ci67/rnrKTrEr2W9 gxsiw3ztGKMqBkO8JnJVFqJmiXS8OYrLil2qP1qYHAGxGH/S/Zo72tASMtdIWDFqhBFl qWkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Sjhfo6VN; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id y19-20020a170902b49300b00158b60545dcsi8766692plr.207.2022.04.22.14.42.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Apr 2022 14:42:07 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Sjhfo6VN; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6C22631D428; Fri, 22 Apr 2022 12:50:15 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230060AbiDUK0z (ORCPT + 99 others); Thu, 21 Apr 2022 06:26:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1388293AbiDUK0Y (ORCPT ); Thu, 21 Apr 2022 06:26:24 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9A3822284; Thu, 21 Apr 2022 03:23:34 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6930061A22; Thu, 21 Apr 2022 10:23:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE0D7C385AA; Thu, 21 Apr 2022 10:23:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1650536613; bh=T0g7oH9T8F9azL6LKlPOPO75OxevOofYsR6P8ncZbYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Sjhfo6VNTDpkzhkc2Up1PFcDw/DHSTsVHcJ4Ll3Z0zChECKHpksxcfRah1WmZ2Cv3 wBVTslcHLypYztFiNr/1xnoGX62XZqBgSn5eKYYoRFvPmyC6vRR49UP0ftyJJbsOPg UubAggDvpqrckUnFtkcbuZEnf9kV0wpzauNvZVd+5sd5drZdqgdbEE5Taks3MCTP5D d/CXS55dTSWACW73Jgm9w2567n9igwW90RtIQr7aPo3JVSZJe2ClDhRg8W6VgZ+VFZ YYZ/4p0KY8vbwVvWoSWTbRed2fj6+hGQVqUX5s+1OJMQDJT8QufOPf6Buzl8SZ5xSv AiNa6gq5W4j6A== Received: from johan by xi.lan with local (Exim 4.94.2) (envelope-from ) id 1nhTyB-0004Xe-9v; Thu, 21 Apr 2022 12:23:27 +0200 From: Johan Hovold To: Andy Gross , Bjorn Andersson , Lorenzo Pieralisi , Kishon Vijay Abraham I , Vinod Koul , "Stephen Boyd" Cc: Rob Herring , Krzysztof Kozlowski , Stanimir Varbanov , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , Bjorn Helgaas , Dmitry Baryshkov , Prasad Malisetty , linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-phy@lists.infradead.org, Johan Hovold Subject: [PATCH RFC 1/5] phy: qcom-qmp: add support for pipe clock muxing Date: Thu, 21 Apr 2022 12:20:37 +0200 Message-Id: <20220421102041.17345-2-johan+linaro@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220421102041.17345-1-johan+linaro@kernel.org> References: <20220421102041.17345-1-johan+linaro@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RDNS_NONE,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some QMP PHYs need to remux to their pipe clock input to the pipe clock output generated by the PHY before powering on the PHY and restore the default source during power down. Add support for an optional pipe clock mux which will be reparented to the generated pipe clock before powering on the PHY and restored to the default reference source on power off. Signed-off-by: Johan Hovold --- drivers/phy/qualcomm/phy-qcom-qmp.c | 71 ++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 7d2d1ab061f7..bc6db9670291 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -3292,6 +3292,8 @@ struct qmp_phy_combo_cfg { * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs) * @pcs_misc: iomapped memory space for lane's pcs_misc * @pipe_clk: pipe clock + * @pipemux_clk: pipe clock source mux + * @piperef_clk: pipe clock default reference source * @index: lane index * @qmp: QMP phy to which this lane belongs * @lane_rst: lane's reset controller @@ -3311,6 +3313,8 @@ struct qmp_phy { void __iomem *rx2; void __iomem *pcs_misc; struct clk *pipe_clk; + struct clk *pipemux_clk; + struct clk *piperef_clk; unsigned int index; struct qcom_qmp *qmp; struct reset_control *lane_rst; @@ -3346,6 +3350,7 @@ struct qcom_qmp { void __iomem *dp_com; struct clk_bulk_data *clks; + struct clk *pipe_clksrc; struct reset_control **resets; struct regulator_bulk_data *vregs; @@ -5355,6 +5360,42 @@ static int qcom_qmp_phy_init(struct phy *phy) return 0; } +static int qcom_qmp_phy_pipe_clk_enable(struct qmp_phy *qphy) +{ + struct qcom_qmp *qmp = qphy->qmp; + int ret; + + ret = clk_set_parent(qphy->pipemux_clk, qmp->pipe_clksrc); + if (ret) + dev_err(qmp->dev, "failed to reparent pipe clock: %d\n", ret); + + + ret = clk_prepare_enable(qphy->pipe_clk); + if (ret) { + dev_err(qmp->dev, "failed to enable pipe clock: %d\n", ret); + goto err_restore_parent; + } + + return 0; + +err_restore_parent: + clk_set_parent(qphy->pipemux_clk, qphy->piperef_clk); + + return ret; +} + +static void qcom_qmp_phy_pipe_clk_disable(struct qmp_phy *qphy) +{ + struct qcom_qmp *qmp = qphy->qmp; + int ret; + + clk_disable_unprepare(qphy->pipe_clk); + + ret = clk_set_parent(qphy->pipemux_clk, qphy->piperef_clk); + if (ret) + dev_err(qmp->dev, "failed to reparent pipe clock: %d\n", ret); +} + static int qcom_qmp_phy_power_on(struct phy *phy) { struct qmp_phy *qphy = phy_get_drvdata(phy); @@ -5379,11 +5420,9 @@ static int qcom_qmp_phy_power_on(struct phy *phy) } } - ret = clk_prepare_enable(qphy->pipe_clk); - if (ret) { - dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret); + ret = qcom_qmp_phy_pipe_clk_enable(qphy); + if (ret) goto err_reset_lane; - } /* Tx, Rx, and PCS configurations */ qcom_qmp_phy_configure_lane(tx, cfg->regs, @@ -5478,7 +5517,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy) return 0; err_disable_pipe_clk: - clk_disable_unprepare(qphy->pipe_clk); + qcom_qmp_phy_pipe_clk_disable(qphy); err_reset_lane: if (cfg->has_lane_rst) reset_control_assert(qphy->lane_rst); @@ -5491,7 +5530,7 @@ static int qcom_qmp_phy_power_off(struct phy *phy) struct qmp_phy *qphy = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qphy->cfg; - clk_disable_unprepare(qphy->pipe_clk); + qcom_qmp_phy_pipe_clk_disable(qphy); if (cfg->type == PHY_TYPE_DP) { /* Assert DP PHY power down */ @@ -5777,6 +5816,8 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np) if (ret) return ret; + qmp->pipe_clksrc = fixed->hw.clk; + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); if (ret) return ret; @@ -6091,6 +6132,24 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id, qphy->pipe_clk = NULL; } + /* Get optional pipe clock mux and default reference source clock. */ + qphy->pipemux_clk = of_clk_get_by_name(np, "mux"); + if (IS_ERR(qphy->pipemux_clk)) { + ret = PTR_ERR(qphy->pipemux_clk); + if (ret == -EPROBE_DEFER) + return ret; + + qphy->pipemux_clk = NULL; + } else { + qphy->piperef_clk = of_clk_get_by_name(np, "ref"); + if (IS_ERR(qphy->piperef_clk)) { + ret = PTR_ERR(qphy->piperef_clk); + return dev_err_probe(dev, ret, + "failed to get lane%d piperef_clk\n", + id); + } + } + /* Get lane reset, if any */ if (cfg->has_lane_rst) { snprintf(prop_name, sizeof(prop_name), "lane%d", id); -- 2.35.1