From nobody Mon Feb 9 07:25:43 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CB9E346A0A for ; Thu, 11 Sep 2025 14:56:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757602591; cv=none; b=YcfJZHy0njIUPCAqYj2y0F2KEkE2DEM4+rL0s8YqJVnnYjuLOLLgI2d6cLsWKmLXEPpc/IyeTJyZWtlvvqZOhsh+7ZH3yF/Szuyyhhl+ar/ZNWZjlvkAkqd/knUEYNVlfHfcZyGCMu4v57LA1yk9Scts2PWNW8XIDsqza4378IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757602591; c=relaxed/simple; bh=wXS/j3wmI7/itl+1AHpADAOwiZSv4uoaae+ybvM0UTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AnxVlFvjJATglxX6wGN1EAJVUjXC68MtFfXmgpPoZMNhC7LlaBNIggMdO8xCP3JHOSauODRo8PelWlrnAM/4l478U1mYPXuRfJOwSLZZwzgyW76Q7FmW66B01E5J3HEwYjLMNdDeXDv2HaawJI9Hky8nWNFhxTBVZp9e8D21DLI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=o2L8cMjE; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="o2L8cMjE" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 58BB1jpP026249 for ; Thu, 11 Sep 2025 14:56:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= Bg3qQvwoP3SWONP7gjOEVlyQsKwbeeB3wM67/xr3xVM=; b=o2L8cMjEV+/XWE1j MtloVniBYJMh4VUY9vHlC7kQ/kYihWShTFJkItBSoIlJkorMZUOcv/ctDvGcY51L hn9N30ycbCsZJoQll8C94uba8g7nbV1B2oWlPyp3JdV+1/NwzSoTeS0w7WnbZnnO JrCwbZj7pzGf7roViBGMJL96JnGhTAUVlJ1ompEHlcSHU2CmFxRqaakDR/a7JaFF fuwraBUteNjIsjvf8DmV6oT2jaiL/hPv4Q2sdGMgmXz8H6FetNTqaK2734OL+wmn 40/bjcT0kxTGwinjHHsS1H5WPaOjCQwsk++uiZtMPmTAVhZqLGMdZ2yFqAdWzoEQ oKaUMg== Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 493f6h352n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 11 Sep 2025 14:56:29 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-24b2b18536bso2873395ad.1 for ; Thu, 11 Sep 2025 07:56:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757602588; x=1758207388; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Bg3qQvwoP3SWONP7gjOEVlyQsKwbeeB3wM67/xr3xVM=; b=vgT4dEj2qUm15vv8tk7+KHM2r33IFC7ee79kpUO5TgrNGjiLV2bmxVCUriae022uxG huGub2n4u+jlpvX9NenEhQO2zLNtjI24jAPl642nxYJ4wPiKInCqmeHGOvCKFVNjZATj oCmsjbdYvwvGVUTptZaVpaNOzSSOHB4h/X/cfMv4FX81R7ivyddzRTqKefawLc5eaiAu LmUP/0uBc1gRIloJ+tflvlD4gNroauPHQjGwW8VoK+Yl+2g8HrBCIRFj5LPS7/g/+w7t FN6WvuUDrcDYAGcpoj8CrL7ZEPUY1rEuyOE3f3Kt7rWE52TYAmGEf7mYWExs6griGMXr KXIQ== X-Forwarded-Encrypted: i=1; AJvYcCVjg5+/ymwR5gfsQ4yslqX8Lvvl72TyfFpPR84l7v5EZrcM1zz306d7vDFaPcrOi9I3vvQE6h2OcwioTxA=@vger.kernel.org X-Gm-Message-State: AOJu0Yw0Vp+JrUkIVHQDmKt8/DwrIZcoQMsUoyJnRLHT52h5DM5AbJFI qwpSMx9A/BvM3vy7lU/UNIsy38ECgwPIbE7vbl7GAEGGOMrR5DfwqJxK2wnhBXXt8zj6qs6Qruz dlb6wm7Ey+ahKdSSoxW5mUdwAiB5AMOJc+XBo+OqoDhQFB75+ksHjTJu6qErRdor7As8= X-Gm-Gg: ASbGncu0lhhHso9EBotrUzfdHZUzpxaQTpclTFUydcyEPV6P4nmoy4ec5NrDrYT7xYn np/7Pc3RbZXlzU35xs46uk1R6h7k6g8YIIdiSsoK4LlsJZQlUlfkGAx5WKmZaoKbjZqYaRmHiTc cltDpoJ0cDC89NTMEuAHkfGHmgFtasmffd8+P8HP/GGduy88j0mXwKHbU+7y34V5Wxb/OAH5IUW L9YRVpw9b4LRflkw4HhH0mW17NnROk+1QXcPM/9VMycVoyQB3TJBL/ZRhhqZJlC06Z4k4Jl3/z9 9Qh8FnbbR+l+CQqLO7GxkobdQoYKr5P+c9IqjhfVYtqCcVsurKFByY3lXnAgkzJgGH3OkTGrv05 VuMgNfJCVhQr6AHp8NKNQRdvqRdetkce+r8QpkWJeaAuyOQmQ+YqrFicX X-Received: by 2002:a17:903:1cc:b0:248:a01f:a549 with SMTP id d9443c01a7336-251771d5b61mr145481715ad.11.1757602588165; Thu, 11 Sep 2025 07:56:28 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGzqWHHaC43opRWYJeZ3tGa1tShxSpMb+K5MExfPWf/PvJv9RmrFikMMJ48f+Pi8CYzXF0tfg== X-Received: by 2002:a17:903:1cc:b0:248:a01f:a549 with SMTP id d9443c01a7336-251771d5b61mr145481465ad.11.1757602587638; Thu, 11 Sep 2025 07:56:27 -0700 (PDT) Received: from sziotdisp01-gv.qualcomm.com.ap.qualcomm.com (tpe-colo-wan-fw-bordernet.qualcomm.com. [103.229.16.4]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b54a387cd4bsm2107453a12.35.2025.09.11.07.56.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Sep 2025 07:56:27 -0700 (PDT) From: Xiangxu Yin Date: Thu, 11 Sep 2025 22:55:05 +0800 Subject: [PATCH v4 08/13] phy: qcom: qmp-usbc: Add USB/DP switchable PHY clk register Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250911-add-displayport-support-for-qcs615-platform-v4-8-2702bdda14ed@oss.qualcomm.com> References: <20250911-add-displayport-support-for-qcs615-platform-v4-0-2702bdda14ed@oss.qualcomm.com> In-Reply-To: <20250911-add-displayport-support-for-qcs615-platform-v4-0-2702bdda14ed@oss.qualcomm.com> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Rob Clark , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, fange.zhang@oss.qualcomm.com, yongxing.mou@oss.qualcomm.com, li.liu@oss.qualcomm.com, tingwei.zhang@oss.qualcomm.com, Dmitry Baryshkov , Bjorn Andersson , Konrad Dybcio , Xiangxu Yin X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1757602528; l=8666; i=xiangxu.yin@oss.qualcomm.com; s=20241125; h=from:subject:message-id; bh=wXS/j3wmI7/itl+1AHpADAOwiZSv4uoaae+ybvM0UTw=; b=G5XhJlaCZ4TKhO3hLxoZ839bkwwozIUamKmhlhmyvZxWYmOvz98Q7AsX4iHEqrThg91OZ/TTj ENGhHWVndYfAu/Vqrj4b4lbRYbsm4JNG/FopmFTTCMIDdxl36dQmNkm X-Developer-Key: i=xiangxu.yin@oss.qualcomm.com; a=ed25519; pk=F1TwipJzpywfbt3n/RPi4l/A4AVF+QC89XzCHgZYaOc= X-Proofpoint-ORIG-GUID: 9KmjVWUtu0SPbGiH2JDRWJval2vBSgFA X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwOTEwMDE3NyBTYWx0ZWRfX4Bjk7LFwdvby i9b8E+daHtfOnCHo+23HZf0cJVG9TURkW2TSsosEzJmT6s3ZcXRZMspo0b4/GR4ocJD4RXtbkk+ lR+XvdGj+Pcx2SBYrjZevpMLi3rJaEjPBCtjBZMMnW8eVtVuk5jeTOOxDiKdyubEHTJB6HGjaZG 0IV7EVuoEQTMAxyksx6gXm/KH1IvWGxQpVqJdnc0P3Qxnj3gdP6Yj6kIRFMgyG2B1bcfOc5wibw cNupSGBtmiNbFQpTfzKW7i7TtnntsYh3zGBWMNOdiLCWp1zYwIWg+J9o7LQI1v/bzySEeSFwa/n mKa5rAJ1xZwdPeRQZjqxSCdGavG0GP42BH++sc2bviWKTzKh5+hYqSQSrN4Uj0yYkG8P3LuHIQe 672opHDN X-Authority-Analysis: v=2.4 cv=WPB/XmsR c=1 sm=1 tr=0 ts=68c2e31d cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=nuhDOHQX5FNHPW3J6Bj6AA==:17 a=IkcTkHD0fZMA:10 a=yJojWOMRYYMA:10 a=EUspDBNiAAAA:8 a=LV3rUWBglltBUjuJGHkA:9 a=QEXdDO2ut3YA:10 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-GUID: 9KmjVWUtu0SPbGiH2JDRWJval2vBSgFA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-09-11_01,2025-09-11_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 spamscore=0 clxscore=1015 priorityscore=1501 adultscore=0 bulkscore=0 phishscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2507300000 definitions=main-2509100177 Add USB/DP switchable PHY clock registration and DT parsing for DP offsets. Extend qmp_usbc_register_clocks and clock provider logic to support both USB and DP instances. Signed-off-by: Xiangxu Yin --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 208 +++++++++++++++++++++++++++= ++-- 1 file changed, 195 insertions(+), 13 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcom= m/phy-qcom-qmp-usbc.c index 7b2b47320cbb2d16e4f316b0f52fdc1bd09fe656..95a099de908e7f3478eb1e18326= b21d4014d8da6 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -22,6 +22,7 @@ #include #include #include +#include =20 #include "phy-qcom-qmp-common.h" =20 @@ -1245,9 +1246,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp) return devm_clk_bulk_get_optional(dev, num, qmp->clks); } =20 -static void phy_clk_release_provider(void *res) +static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec= , void *data) { - of_clk_del_provider(res); + struct qmp_usbc *qmp =3D data; + + if (clkspec->args_count =3D=3D 0) + return &qmp->pipe_clk_fixed.hw; + + switch (clkspec->args[0]) { + case QMP_USB43DP_USB3_PIPE_CLK: + return &qmp->pipe_clk_fixed.hw; + case QMP_USB43DP_DP_LINK_CLK: + return &qmp->dp_link_hw; + case QMP_USB43DP_DP_VCO_DIV_CLK: + return &qmp->dp_pixel_hw; + } + + return ERR_PTR(-EINVAL); } =20 /* @@ -1276,8 +1291,11 @@ static int phy_pipe_clk_register(struct qmp_usbc *qm= p, struct device_node *np) =20 ret =3D of_property_read_string(np, "clock-output-names", &init.name); if (ret) { - dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); - return ret; + char name[64]; + + /* Clock name is not mandatory. */ + snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev)); + init.name =3D name; } =20 init.ops =3D &clk_fixed_rate_ops; @@ -1286,19 +1304,176 @@ static int phy_pipe_clk_register(struct qmp_usbc *= qmp, struct device_node *np) fixed->fixed_rate =3D 125000000; fixed->hw.init =3D &init; =20 - ret =3D devm_clk_hw_register(qmp->dev, &fixed->hw); - if (ret) + return devm_clk_hw_register(qmp->dev, &fixed->hw); +} + + +/* + * Display Port PLL driver block diagram for branch clocks + * + * +------------------------------+ + * | DP_VCO_CLK | + * | | + * | +-------------------+ | + * | | (DP PLL/VCO) | | + * | +---------+---------+ | + * | v | + * | +----------+-----------+ | + * | | hsclk_divsel_clk_src | | + * | +----------+-----------+ | + * +------------------------------+ + * | + * +---------<---------v------------>----------+ + * | | + * +--------v----------------+ | + * | dp_phy_pll_link_clk | | + * | link_clk | | + * +--------+----------------+ | + * | | + * | | + * v v + * Input to DISPCC block | + * for link clk, crypto clk | + * and interface clock | + * | + * | + * +--------<------------+-----------------+---<---+ + * | | | + * +----v---------+ +--------v-----+ +--------v------+ + * | vco_divided | | vco_divided | | vco_divided | + * | _clk_src | | _clk_src | | _clk_src | + * | | | | | | + * |divsel_six | | divsel_two | | divsel_four | + * +-------+------+ +-----+--------+ +--------+------+ + * | | | + * v---->----------v-------------<------v + * | + * +----------+-----------------+ + * | dp_phy_pll_vco_div_clk | + * +---------+------------------+ + * | + * v + * Input to DISPCC block + * for DP pixel clock + * + */ +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_r= ate_request *req) +{ + switch (req->rate) { + case 1620000000UL / 2: + case 2700000000UL / 2: + /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */ + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsig= ned long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp =3D container_of(hw, struct qmp_usbc, dp_pixel_hw); + + dp_opts =3D &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + return 1620000000UL / 2; + case 2700: + return 2700000000UL / 2; + case 5400: + return 5400000000UL / 4; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_pixel_clk_ops =3D { + .determine_rate =3D qmp_dp_pixel_clk_determine_rate, + .recalc_rate =3D qmp_dp_pixel_clk_recalc_rate, +}; + +static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_ra= te_request *req) +{ + switch (req->rate) { + case 162000000: + case 270000000: + case 540000000: + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsign= ed long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp =3D container_of(hw, struct qmp_usbc, dp_link_hw); + dp_opts =3D &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + case 2700: + case 5400: + return dp_opts->link_rate * 100000; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_link_clk_ops =3D { + .determine_rate =3D qmp_dp_link_clk_determine_rate, + .recalc_rate =3D qmp_dp_link_clk_recalc_rate, +}; + +static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *= np) +{ + struct clk_init_data init =3D { }; + char name[64]; + int ret; + + snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev)); + init.ops =3D &qmp_dp_link_clk_ops; + init.name =3D name; + qmp->dp_link_hw.init =3D &init; + ret =3D devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw); + if (ret < 0) { + dev_err(qmp->dev, "link clk reg fail ret=3D%d\n", ret); + return ret; + } + + snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev)); + init.ops =3D &qmp_dp_pixel_clk_ops; + init.name =3D name; + qmp->dp_pixel_hw.init =3D &init; + ret =3D devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw); + if (ret) { + dev_err(qmp->dev, "pxl clk reg fail ret=3D%d\n", ret); return ret; + } + + return 0; +} + +static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_no= de *np) +{ + int ret; =20 - ret =3D of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); + ret =3D phy_pipe_clk_register(qmp, np); if (ret) return ret; =20 - /* - * Roll a devm action because the clock provider is the child node, but - * the child node is not actually a device. - */ - return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np); + if (qmp->dp_serdes !=3D 0) { + ret =3D phy_dp_clks_register(qmp, np); + if (ret) + return ret; + } + + return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp); } =20 #if IS_ENABLED(CONFIG_TYPEC) @@ -1429,6 +1604,13 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) if (IS_ERR(base)) return PTR_ERR(base); =20 + if (offs->dp_serdes !=3D 0) { + qmp->dp_serdes =3D base + offs->dp_serdes; + qmp->dp_tx =3D base + offs->dp_txa; + qmp->dp_tx2 =3D base + offs->dp_txb; + qmp->dp_dp_phy =3D base + offs->dp_dp_phy; + } + qmp->serdes =3D base + offs->serdes; qmp->pcs =3D base + offs->pcs; if (offs->pcs_misc) @@ -1537,7 +1719,7 @@ static int qmp_usbc_probe(struct platform_device *pde= v) */ pm_runtime_forbid(dev); =20 - ret =3D phy_pipe_clk_register(qmp, np); + ret =3D qmp_usbc_register_clocks(qmp, np); if (ret) goto err_node_put; =20 --=20 2.34.1