Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2224748/?format=api
{ "id": 2224748, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224748/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260418-kodiak_ss-v4-2-d381670c9d78@oss.qualcomm.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/1.2/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260418-kodiak_ss-v4-2-d381670c9d78@oss.qualcomm.com>", "list_archive_url": null, "date": "2026-04-18T06:35:20", "name": "[v4,2/5] drivers: phy: qcom: Add QMP USB3-DP Combo PHY driver", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "142523d5eba32c22416263dbd018d44d2b9c13fc", "submitter": { "id": 90810, "url": "http://patchwork.ozlabs.org/api/1.2/people/90810/?format=api", "name": "Balaji Selvanathan", "email": "balaji.selvanathan@oss.qualcomm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260418-kodiak_ss-v4-2-d381670c9d78@oss.qualcomm.com/mbox/", "series": [ { "id": 500422, "url": "http://patchwork.ozlabs.org/api/1.2/series/500422/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=500422", "date": "2026-04-18T06:35:18", "name": "Enable USB3 Super-Speed support for QCM6490/SC7280", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/500422/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2224748/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2224748/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=cjZwPKH/;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=Cq8BF6FF;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=oss.qualcomm.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com\n header.b=\"cjZwPKH/\";\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.b=\"Cq8BF6FF\";\n\tdkim-atps=neutral", "phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=oss.qualcomm.com", "phobos.denx.de; spf=pass\n smtp.mailfrom=balaji.selvanathan@oss.qualcomm.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fyMT45c4Jz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 16:35:52 +1000 (AEST)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id E59D184286;\n\tSat, 18 Apr 2026 08:35:48 +0200 (CEST)", "by phobos.denx.de (Postfix, from userid 109)\n id C851D8426E; Sat, 18 Apr 2026 08:35:47 +0200 (CEST)", "from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n [205.220.168.131])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id A62C383B99\n for <u-boot@lists.denx.de>; Sat, 18 Apr 2026 08:35:44 +0200 (CEST)", "from pps.filterd (m0279867.ppops.net [127.0.0.1])\n by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63I4UCDW3440589\n for <u-boot@lists.denx.de>; Sat, 18 Apr 2026 06:35:42 GMT", "from mail-pl1-f199.google.com (mail-pl1-f199.google.com\n [209.85.214.199])\n by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dkyne8hap-1\n (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n for <u-boot@lists.denx.de>; Sat, 18 Apr 2026 06:35:42 +0000 (GMT)", "by mail-pl1-f199.google.com with SMTP id\n d9443c01a7336-2b2d0c1ead1so28628595ad.0\n for <u-boot@lists.denx.de>; Fri, 17 Apr 2026 23:35:42 -0700 (PDT)", "from hu-bselvana-blr.qualcomm.com\n (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19])\n by smtp.gmail.com with ESMTPSA id\n d9443c01a7336-2b5fab20d33sm40542345ad.63.2026.04.17.23.35.34\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 17 Apr 2026 23:35:40 -0700 (PDT)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,\n RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED,\n SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2", "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n cc:content-transfer-encoding:content-type:date:from:in-reply-to\n :message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n FDKnBZAmHBCG6gyF+xcYGlGThyopvsiOLyXR3/3QTGE=; b=cjZwPKH/C1inmLpI\n r2LQusev+/Xl60CAgN5x8Jzac9/kkEwBI9JoRR2W9OS8wL/P7Uc8fv5hNO63VIfn\n SqjvMf6jcZaVM70nq4i6xUc1QxXWVDcT3T4yu3Vlrz9kV8EGwjzFx1t1gwjYMLj3\n jqo/nBN/XbZSLu4DbHgujVDyBabBzbEqTmsiGogrcoj7GzISVE2pjr+3Y6DeeUP0\n DVBdOGw4SZtoqg5Nuj5dEPRaISXHIv0/yieF4ZKX9GakUGak0f7C9nNyjdofttPq\n kJk73twjNMohQa8KFqe9sG0qW3N3Ic6BCkd4sz5pQeMTo0K6OrRU0nEWgn8vwLDU\n d58gvA==", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oss.qualcomm.com; s=google; t=1776494142; x=1777098942; darn=lists.denx.de;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:from:to:cc:subject:date:message-id\n :reply-to; bh=FDKnBZAmHBCG6gyF+xcYGlGThyopvsiOLyXR3/3QTGE=;\n b=Cq8BF6FF6VJvEuq1GcYMXcIoGnHd44MsmgX4A0stjrvojZMCGc/gGEC5/uUCSllhev\n m+kB1ax8gPtzdN/O0XIcR6Hi+q3RdQ6WJ8KD5J11jfNDVoRIzog1k98u5GrTBJztFlLj\n fQYLF3qI4tIjROH2KrzvtsH/r+NWwOWBObQqfAcEbsiU3ZkOy5VnR0cTeKbKhQUx5r+S\n rsSCFlQ/g2TqfxD8m2wzk0185DzgXOCixnxmCdh9qxaoAzjZ6lavSpqGzv5xu6RUj05v\n Arz6sM7z9jSmDg8OCBddMIm6OfnUjXyUa0sCEyO5waXSpiMFLuIsu7XRXdPSR8dvE1HA\n tDWA==" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776494142; x=1777098942;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=FDKnBZAmHBCG6gyF+xcYGlGThyopvsiOLyXR3/3QTGE=;\n b=k/Rm+3QAXuyicMSCcedBHXfy3CG07SGs8ikjK35p7zt4oAISXYMG7VhpSJiSJ0o4Z5\n Kvlpb6rBCDSsghASOAStPKOAXxeE+u2fZWVBZD808KHufaZaLnO/4g/igvwu3rEtLhL4\n VQhiXp0cEaJhBd0kLk72q5i1JOnIDvhcPY54K9d/YE00KVzA03uI56YgfSj3NvuqMXnx\n RJ4JOxKQyzByJWcdsfjGbUokwj/Lgx8vRRAEMJX+JwrKZEHdDay2gPFw5sbFxy/dCOCa\n 1RgfPGrt3J7RwKRjDEeyCtDvYGkDaxE6VsAAhv1erhALf804xXkLkapEbrJfBHETauw+\n WRnA==", "X-Forwarded-Encrypted": "i=1;\n AFNElJ/TFG7gNDQLe4UHI1DKlu1zy/U4H9Y1WMVukmGAs05HqE9HqdjdPTJJ3rokOTV9sxWQlxHCDOQ=@lists.denx.de", "X-Gm-Message-State": "AOJu0Yxun3ES564J2e/a0OyS7WYEGsHTe7WQzaQxR0hNyk3ARgD5P+kv\n +fDt9nvR3Nw2NbTSIjF6lo9qVcfS0IrFhFhQfBIqA/hCduR8MMTVX1mKQWKV4flDq0czEBM/zX+\n lhbJBBqJkJ+Woa/ZN1IdjVwHZ8HO7hosKj/kcV+5KSK+ijbLVPCWXHYiK", "X-Gm-Gg": "AeBDievwMLqMxG6W7/Fmd8R0Ri4ONdXTmkETbzx4OiC9Oy9FLtftrwJmnfIDaPehmjp\n R4jXOHu5tT07EGBOQ/Hzr+e1olXXIwZNRJRMGn4ljvZfIs/AmQXh/pydbGRW0GpWj+K4ebULj1r\n 2jXjc57NBjfl5TURSXNYNJt+/YloB9myNdilNcPp4ukO6eQJIdRTETb8ywTWQyAX1YiN3oL+XsE\n UOUXVDQ78uweCKMpbfI14ps/yhgyH3srELpSg2AB20vQZgqaYa/rdy2o65cYsYDROhpme4R86B1\n 2ELBzFT7Ck6tsNTVvBdC61Q5HsqiqOTm9lxshZR1K3E1FSwNEi4D8bKjD6Eh8ND7sCKw4bZEsSM\n MS6gt8bGa5iBnQ4aPOWpvmS28oNozCRVRMu5jXPCCOdYuzTS55J4g+umS/wsMJoIkOrMLE7Px6q\n PVEHG+fFZU2o64qyHPqZS4u86lHV2MZX0zBEKtxYNYvm6LXmVNWAgOmr4qxauQ", "X-Received": [ "by 2002:a17:902:db10:b0:2b2:9d60:5eaf with SMTP id\n d9443c01a7336-2b5f9e78262mr64570035ad.6.1776494141552;\n Fri, 17 Apr 2026 23:35:41 -0700 (PDT)", "by 2002:a17:902:db10:b0:2b2:9d60:5eaf with SMTP id\n d9443c01a7336-2b5f9e78262mr64569625ad.6.1776494140930;\n Fri, 17 Apr 2026 23:35:40 -0700 (PDT)" ], "From": "Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>", "Date": "Sat, 18 Apr 2026 12:05:20 +0530", "Subject": "[PATCH v4 2/5] drivers: phy: qcom: Add QMP USB3-DP Combo PHY\n driver", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260418-kodiak_ss-v4-2-d381670c9d78@oss.qualcomm.com>", "References": "<20260418-kodiak_ss-v4-0-d381670c9d78@oss.qualcomm.com>", "In-Reply-To": "<20260418-kodiak_ss-v4-0-d381670c9d78@oss.qualcomm.com>", "To": "Sumit Garg <sumit.garg@kernel.org>, u-boot-qcom@groups.io,\n u-boot@lists.denx.de", "Cc": "Lukasz Majewski <lukma@denx.de>,\n Casey Connolly <casey.connolly@linaro.org>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Tom Rini <trini@konsulko.com>, Luca Weiss <luca.weiss@fairphone.com>,\n Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Simon Glass <sjg@chromium.org>, Peng Fan <peng.fan@nxp.com>,\n Yao Zi <me@ziyao.cc>, Kory Maincent <kory.maincent@bootlin.com>,\n Kuan-Wei Chiu <visitorckw@gmail.com>,\n Jerome Forissier <jerome.forissier@arm.com>,\n Raymond Mao <raymond.mao@riscstar.com>,\n Quentin Schulz <quentin.schulz@cherry.de>,\n Stefan Roese <stefan.roese@mailbox.org>,\n Philip Molloy <philip.molloy@analog.com>,\n Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>", "X-Mailer": "b4 0.14.3", "X-Developer-Signature": "v=1; a=ed25519-sha256; t=1776494121; l=28192;\n i=balaji.selvanathan@oss.qualcomm.com; s=20260213; h=from:subject:message-id;\n bh=Pah30YAcyI4Gm/UnqWny5+Cs6FjUhCt4ICFDHVtSpNY=;\n b=hycJIEsqvBg5/NMoAWnn+pRV3fnjE6X28YsBZEJyXNaV6HEAs938/PUrScTby19v/uN0UnUz5\n 2UuV1/u1zEZCiO9Bv6ZfTZl5W8A8t+zf2Huq3uZACH1Krp53/ssVDUE", "X-Developer-Key": "i=balaji.selvanathan@oss.qualcomm.com; a=ed25519;\n pk=CDpYiUU3SH7KGEtsBvY2tBGPiWfMxqWJF0p2LftOfnc=", "X-Authority-Analysis": "v=2.4 cv=HbokiCE8 c=1 sm=1 tr=0 ts=69e3263e cx=c_pps\n a=JL+w9abYAAE89/QcEU+0QA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17\n a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10\n a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22\n a=VwQbUJbxAAAA:8 a=EUspDBNiAAAA:8 a=VVcqUrZN0lOw816XaWQA:9 a=QEXdDO2ut3YA:10\n a=324X-CrmTo6CU4MGRt3R:22", "X-Proofpoint-GUID": "WErM46kzSwVZtkOonqwmHE8qJKSEcdZ_", "X-Proofpoint-ORIG-GUID": "WErM46kzSwVZtkOonqwmHE8qJKSEcdZ_", "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjYwNDE4MDA1OSBTYWx0ZWRfX1DAjl5tQVeqq\n FRhWnorehPK1Ib9DnP6cF3NFP+dqEHT8jeuwkDhNV1nU32hVKBVvhAI3O+h5X1K5OUWlh2vpjHJ\n u2a/2Y/baiOZZyfl1M/7Lk7qsyYh0Rjs09BPiFX6oQOUaIWoXeyx0Mbgf05p3b9CgGWibaSOpEF\n O4w5fJTYMqpJ7Oafe7w3jpBTwnXZ8IE59zFBxmFRRUJeU0VGf8HYpWCAwfmPMvxViq9mBsIHuXC\n id0GrrynG9U59xDsmv1rXobMi6/EiUQ99yMgBQ61r7BwlPEz0pHICP61ndcgak/RfXg3xA+7YNZ\n qHchIaljcPOTPRHR4F/Szmu28blqTS5uIB74OxLne4n/BGWx438hgBptm96gEYrgdUIzm95aL4R\n VF46mObpqtsmAeMhEqNpCMc6lzRvMpO0jYLowRQTCw0gIzgHE4lQQD1Bz/BrET2n/FsnI+HhFRW\n IN/DDgQBYhjKqjY36Tg==", "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-18_02,2026-04-17_04,2025-10-01_01", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n malwarescore=0 lowpriorityscore=0 bulkscore=0 spamscore=0 clxscore=1015\n priorityscore=1501 adultscore=0 phishscore=0 suspectscore=0 impostorscore=0\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604070000 definitions=main-2604180059", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "Add support for the Qualcomm QMP USB3-DP Combo PHY found on\nSC7280 and QCM6490 platforms. This driver currently implements\nUSB3 super-speed functionality of the combo PHY.\n\nThe QMP Combo PHY is a dual-mode PHY\nthat can operate in either USB3 mode or DisplayPort mode. This\ninitial implementation focuses on USB3 mode to enable Super-Speed\nUSB support.\n\nTaken from Linux commit 3d25d46a255a (\"pmdomain: qcom: rpmhpd: Add rpmhpd support for SM8750\")\n\nThis patch is dependent on this patch: https://lore.kernel.org/u-boot/20251112164204.1557934-1-aswin.murugan@oss.qualcomm.com/\n\nEnabled and tested the driver on Qualcomm RB3 Gen2 (QCS6490) board.\n\nReviewed-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>\nSigned-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>\n---\nChanges in v4:\n- No changes\n---\n drivers/phy/qcom/Kconfig | 8 +\n drivers/phy/qcom/Makefile | 1 +\n drivers/phy/qcom/phy-qcom-qmp-combo.c | 644 +++++++++++++++++++++++++++++\n drivers/phy/qcom/phy-qcom-qmp-common.h | 62 +++\n drivers/phy/qcom/phy-qcom-qmp-dp-com-v3.h | 18 +\n drivers/phy/qcom/phy-qcom-qmp-pcs-usb-v4.h | 34 ++\n drivers/phy/qcom/phy-qcom-qmp.h | 17 +\n 7 files changed, 784 insertions(+)", "diff": "diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig\nindex 0dd69f7ffd0..49f830abf01 100644\n--- a/drivers/phy/qcom/Kconfig\n+++ b/drivers/phy/qcom/Kconfig\n@@ -12,6 +12,14 @@ config PHY_QCOM_IPQ4019_USB\n \thelp\n \t Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.\n \n+config PHY_QCOM_QMP_COMBO\n+\tbool \"Qualcomm QMP USB3-DP Combo PHY driver\"\n+\tdepends on PHY && ARCH_SNAPDRAGON\n+\thelp\n+\t Enable this to support the USB3-DP Combo QMP PHY on various Qualcomm\n+\t chipsets. This driver supports the USB3 PHY functionality of the combo\n+\t PHY (USB3 + DisplayPort). Currently only USB3 mode is supported.\n+\n config PHY_QCOM_QMP_PCIE\n \ttristate \"Qualcomm QMP PCIe PHY driver\"\n \tdepends on PHY && ARCH_SNAPDRAGON\ndiff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile\nindex 1c4e7d8d391..714013dc572 100644\n--- a/drivers/phy/qcom/Makefile\n+++ b/drivers/phy/qcom/Makefile\n@@ -1,5 +1,6 @@\n obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o\n obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o\n+obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o\n obj-$(CONFIG_PHY_QCOM_QMP_PCIE) += phy-qcom-qmp-pcie.o\n obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o\n obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp-combo.c b/drivers/phy/qcom/phy-qcom-qmp-combo.c\nnew file mode 100644\nindex 00000000000..0095cbf8b4c\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp-combo.c\n@@ -0,0 +1,644 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.\n+ */\n+\n+#include <clk.h>\n+#include <dm.h>\n+#include <dm/device_compat.h>\n+#include <dm/devres.h>\n+#include <generic-phy.h>\n+#include <reset.h>\n+#include <power/regulator.h>\n+#include <asm/io.h>\n+#include <linux/bitops.h>\n+#include <linux/compat.h>\n+#include <linux/delay.h>\n+#include <linux/iopoll.h>\n+#include <linux/err.h>\n+\n+#include \"phy-qcom-qmp-common.h\"\n+\n+#include \"phy-qcom-qmp.h\"\n+#include \"phy-qcom-qmp-pcs-misc-v3.h\"\n+#include \"phy-qcom-qmp-pcs-usb-v4.h\"\n+#include \"phy-qcom-qmp-dp-com-v3.h\"\n+\n+/* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */\n+/* DP PHY soft reset */\n+#define SW_DPPHY_RESET BIT(0)\n+/* mux to select DP PHY reset control, 0:HW control, 1: software reset */\n+#define SW_DPPHY_RESET_MUX BIT(1)\n+/* USB3 PHY soft reset */\n+#define SW_USB3PHY_RESET BIT(2)\n+/* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */\n+#define SW_USB3PHY_RESET_MUX BIT(3)\n+\n+/* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */\n+#define USB3_MODE BIT(0) /* enables USB3 mode */\n+#define DP_MODE BIT(1) /* enables DP mode */\n+\n+/* QPHY_V3_DP_COM_TYPEC_CTRL register bits */\n+#define SW_PORTSELECT_MUX BIT(1)\n+\n+/* PHY slot identifiers for device tree phandle arguments */\n+#define QMP_USB43DP_USB3_PHY 0\n+#define QMP_USB43DP_DP_PHY 1\n+\n+#define PHY_INIT_COMPLETE_TIMEOUT\t\t10000\n+\n+struct qmp_combo_offsets {\n+\tu16 com;\n+\tu16 txa;\n+\tu16 rxa;\n+\tu16 txb;\n+\tu16 rxb;\n+\tu16 usb3_serdes;\n+\tu16 usb3_pcs_misc;\n+\tu16 usb3_pcs;\n+\tu16 usb3_pcs_usb;\n+};\n+\n+/*\n+ * Initialisation tables\n+ */\n+\n+static const struct qmp_combo_offsets qmp_combo_offsets_v3 = {\n+\t.com\t\t= 0x0000,\n+\t.txa\t\t= 0x1200,\n+\t.rxa\t\t= 0x1400,\n+\t.txb\t\t= 0x1600,\n+\t.rxb\t\t= 0x1800,\n+\t.usb3_serdes\t= 0x1000,\n+\t.usb3_pcs_misc\t= 0x1a00,\n+\t.usb3_pcs\t= 0x1c00,\n+\t.usb3_pcs_usb\t= 0x1f00,\n+};\n+\n+static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xde),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x07),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0xde),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x07),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x14),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x34),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x34),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xea),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0xab),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0xea),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0x24),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xca),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),\n+};\n+\n+static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX, 0x60),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX, 0x60),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xd5),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x40, 1),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL, 0x54, 2),\n+};\n+\n+static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff, 1),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW, 0x7f, 2),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x7f, 1),\n+\tQMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff, 2),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x7f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x97),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xdc),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xdc),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0x5c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x7b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb4),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0xa0),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x1f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE, 0x10),\n+};\n+\n+static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xa9),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME, 0x0a),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1, 0x88),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2, 0x13),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1, 0x4b),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5, 0x10),\n+};\n+\n+static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07),\n+};\n+\n+struct qmp_phy_cfg {\n+\tconst struct qmp_combo_offsets *offsets;\n+\tconst struct qmp_phy_init_tbl *serdes_tbl;\n+\tint serdes_tbl_num;\n+\tconst struct qmp_phy_init_tbl *tx_tbl;\n+\tint tx_tbl_num;\n+\tconst struct qmp_phy_init_tbl *rx_tbl;\n+\tint rx_tbl_num;\n+\tconst struct qmp_phy_init_tbl *pcs_tbl;\n+\tint pcs_tbl_num;\n+\tconst struct qmp_phy_init_tbl *pcs_usb_tbl;\n+\tint pcs_usb_tbl_num;\n+\tconst char * const *vreg_list;\n+\tint num_vregs;\n+\t/* true, if PHY needs delay after POWER_DOWN */\n+\tbool has_pwrdn_delay;\n+};\n+\n+/* list of clocks required by phy */\n+static const char * const qmp_combo_phy_clk_l[] = {\n+\t\"aux\", \"com_aux\",\n+};\n+\n+/* list of regulators */\n+static const char * const qmp_phy_vreg_l[] = {\n+\t\"vdda-phy-supply\",\n+\t\"vdda-pll-supply\",\n+};\n+\n+struct qmp_combo {\n+\tstruct udevice *dev;\n+\tvoid __iomem *com;\n+\tvoid __iomem *serdes;\n+\tvoid __iomem *tx;\n+\tvoid __iomem *rx;\n+\tvoid __iomem *tx2;\n+\tvoid __iomem *rx2;\n+\tvoid __iomem *pcs;\n+\tvoid __iomem *pcs_usb;\n+\tvoid __iomem *pcs_misc;\n+\tstruct clk *clks;\n+\tstruct clk *pipe_clk;\n+\tint num_clks;\n+\tstruct reset_ctl_bulk resets;\n+\tint num_resets;\n+\tstruct udevice **vregs;\n+\tint num_vregs;\n+\tconst struct qmp_phy_cfg *cfg;\n+};\n+\n+static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)\n+{\n+\tu32 reg;\n+\n+\treg = readl(base + offset);\n+\treg |= val;\n+\twritel(reg, base + offset);\n+\n+\t/* ensure that above write is through */\n+\treadl(base + offset);\n+}\n+\n+static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)\n+{\n+\tu32 reg;\n+\n+\treg = readl(base + offset);\n+\treg &= ~val;\n+\twritel(reg, base + offset);\n+\n+\t/* ensure that above write is through */\n+\treadl(base + offset);\n+}\n+\n+static int qmp_combo_com_exit(struct qmp_combo *qmp)\n+{\n+\tint i, ret;\n+\n+\tfor (i = 0; i < qmp->num_clks; i++)\n+\t\tclk_disable(&qmp->clks[i]);\n+\n+\treset_assert_bulk(&qmp->resets);\n+\n+\tfor (i = qmp->num_vregs - 1; i >= 0; i--) {\n+\t\tret = regulator_set_enable(qmp->vregs[i], false);\n+\t\tif (ret)\n+\t\t\tdev_warn(qmp->dev, \"failed to disable %s: %d\\n\",\n+\t\t\t\t qmp->cfg->vreg_list[i], ret);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_com_init(struct qmp_combo *qmp)\n+{\n+\tconst struct qmp_phy_cfg *cfg = qmp->cfg;\n+\tvoid __iomem *com = qmp->com;\n+\tvoid __iomem *pcs = qmp->pcs;\n+\tu32 val;\n+\tint ret, i;\n+\n+\tret = reset_assert_bulk(&qmp->resets);\n+\tif (ret) {\n+\t\tprintf(\"Failed to assert resets: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = reset_deassert_bulk(&qmp->resets);\n+\tif (ret) {\n+\t\tprintf(\"Failed to deassert resets: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tfor (i = 0; i < qmp->num_vregs; i++) {\n+\t\tret = regulator_set_enable(qmp->vregs[i], true);\n+\t\tif (ret) {\n+\t\t\tdev_err(qmp->dev, \"Failed to enable regulator %d: %d\\n\", i, ret);\n+\t\t\twhile (--i >= 0)\n+\t\t\t\tregulator_set_enable(qmp->vregs[i], false);\n+\t\t\treset_assert_bulk(&qmp->resets);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < qmp->num_clks; i++) {\n+\t\tret = clk_enable(&qmp->clks[i]);\n+\t\tif (ret) {\n+\t\t\tprintf(\"Failed to enable clock %d: %d\\n\", i, ret);\n+\t\t\twhile (--i >= 0)\n+\t\t\t\tclk_disable(&qmp->clks[i]);\n+\t\t\tfor (i = qmp->num_vregs - 1; i >= 0; i--)\n+\t\t\t\tregulator_set_enable(qmp->vregs[i], false);\n+\t\t\treset_assert_bulk(&qmp->resets);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Common block register writes */\n+\tqphy_setbits(com, QPHY_V3_DP_COM_POWER_DOWN_CTRL, SW_PWRDN);\n+\tqphy_setbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,\n+\t\t SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |\n+\t\t SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);\n+\n+\tval = SW_PORTSELECT_MUX;\n+\twritel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL);\n+\n+\twritel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);\n+\n+\tqphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL,\n+\t\t SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |\n+\t\t SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);\n+\n+\tqphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);\n+\n+\tqphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);\n+\n+\tqphy_setbits(pcs, QPHY_V4_PCS_POWER_DOWN_CONTROL, SW_PWRDN);\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_usb_power_on(struct qmp_combo *qmp)\n+{\n+\tconst struct qmp_phy_cfg *cfg = qmp->cfg;\n+\tvoid __iomem *serdes = qmp->serdes;\n+\tvoid __iomem *tx = qmp->tx;\n+\tvoid __iomem *rx = qmp->rx;\n+\tvoid __iomem *tx2 = qmp->tx2;\n+\tvoid __iomem *rx2 = qmp->rx2;\n+\tvoid __iomem *pcs = qmp->pcs;\n+\tvoid __iomem *pcs_usb = qmp->pcs_usb;\n+\tu32 val;\n+\tint ret;\n+\n+\t/* Serdes configuration */\n+\tqmp_configure(qmp->dev, serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);\n+\n+\tret = clk_prepare_enable(qmp->pipe_clk);\n+\tif (ret) {\n+\t\tdev_err(qmp->dev, \"pipe_clk enable failed err=%d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Tx, Rx configurations */\n+\tqmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);\n+\tqmp_configure_lane(qmp->dev, tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);\n+\n+\tqmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);\n+\tqmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);\n+\n+\t/* PCS configuration */\n+\tqmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);\n+\n+\tif (pcs_usb) {\n+\t\tqmp_configure(qmp->dev, pcs_usb,\n+\t\t\t cfg->pcs_usb_tbl,\n+\t\t\t cfg->pcs_usb_tbl_num);\n+\t}\n+\n+\tif (cfg->has_pwrdn_delay)\n+\t\tudelay(20);\n+\n+\t/* Pull PHY out of reset */\n+\tqphy_clrbits(pcs, QPHY_V4_PCS_SW_RESET, SW_RESET);\n+\n+\t/* Start SerDes and Phy-Coding-Sublayer */\n+\tqphy_setbits(pcs, QPHY_V4_PCS_START_CONTROL,\n+\t\t SERDES_START | PCS_START);\n+\n+\t/* Wait for PHY initialization */\n+\tret = readl_poll_timeout(pcs + QPHY_V4_PCS_PCS_STATUS1, val,\n+\t\t\t\t !(val & PHYSTATUS), PHY_INIT_COMPLETE_TIMEOUT);\n+\n+\tif (ret) {\n+\t\tprintf(\"QMP USB3 PHY initialization timeout\\n\");\n+\t\tclk_disable(qmp->pipe_clk);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_power_on(struct phy *phy)\n+{\n+\tstruct qmp_combo *qmp = dev_get_priv(phy->dev);\n+\tint ret;\n+\n+\t/* Initialize common block */\n+\tret = qmp_combo_com_init(qmp);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Initialize USB3-specific configuration */\n+\tret = qmp_combo_usb_power_on(qmp);\n+\tif (ret) {\n+\t\tqmp_combo_com_exit(qmp);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_power_off(struct phy *phy)\n+{\n+\tstruct qmp_combo *qmp = dev_get_priv(phy->dev);\n+\tvoid __iomem *com = qmp->com;\n+\n+\tclk_disable(qmp->pipe_clk);\n+\n+\t/* PHY reset */\n+\tqphy_setbits(qmp->pcs, QPHY_V4_PCS_SW_RESET, SW_RESET);\n+\n+\t/* Stop SerDes and Phy-Coding-Sublayer */\n+\tqphy_clrbits(qmp->pcs, QPHY_V4_PCS_START_CONTROL,\n+\t\t SERDES_START | PCS_START);\n+\n+\t/* Put PHY into POWER DOWN state: active low */\n+\tqphy_clrbits(qmp->pcs, QPHY_V4_PCS_POWER_DOWN_CONTROL, SW_PWRDN);\n+\n+\t/* Power down common block */\n+\tqphy_clrbits(com, QPHY_V3_DP_COM_POWER_DOWN_CTRL, SW_PWRDN);\n+\n+\treturn qmp_combo_com_exit(qmp);\n+}\n+\n+static int qmp_combo_reset_init(struct qmp_combo *qmp)\n+{\n+\tstruct udevice *dev = qmp->dev;\n+\tint ret;\n+\n+\tret = reset_get_bulk(dev, &qmp->resets);\n+\tif (ret) {\n+\t\tprintf(\"Failed to get resets: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tqmp->num_resets = qmp->resets.count;\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_clk_init(struct qmp_combo *qmp)\n+{\n+\tstruct udevice *dev = qmp->dev;\n+\tint num = ARRAY_SIZE(qmp_combo_phy_clk_l);\n+\tint i, ret;\n+\n+\tqmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);\n+\tif (!qmp->clks)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\tret = clk_get_by_name(dev, qmp_combo_phy_clk_l[i], &qmp->clks[i]);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"failed to get %s clock: %d\\n\",\n+\t\t\t\tqmp_combo_phy_clk_l[i], ret);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tqmp->num_clks = num;\n+\treturn 0;\n+}\n+\n+static int qmp_combo_vreg_init(struct qmp_combo *qmp)\n+{\n+\tconst struct qmp_phy_cfg *cfg = qmp->cfg;\n+\tstruct udevice *dev = qmp->dev;\n+\tint num = cfg->num_vregs;\n+\tint i, ret;\n+\n+\tif (!num)\n+\t\treturn 0;\n+\n+\tqmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);\n+\tif (!qmp->vregs)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\tret = device_get_supply_regulator(dev, cfg->vreg_list[i],\n+\t\t\t\t\t\t &qmp->vregs[i]);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"failed to get regulator %s: %d\\n\",\n+\t\t\t\tcfg->vreg_list[i], ret);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tqmp->num_vregs = num;\n+\treturn 0;\n+}\n+\n+static int qmp_combo_parse_dt(struct qmp_combo *qmp)\n+{\n+\tconst struct qmp_phy_cfg *cfg = qmp->cfg;\n+\tconst struct qmp_combo_offsets *offs = cfg->offsets;\n+\tstruct udevice *dev = qmp->dev;\n+\tvoid __iomem *base;\n+\tint ret;\n+\n+\tif (!offs)\n+\t\treturn -EINVAL;\n+\n+\tbase = (void __iomem *)dev_read_addr(dev);\n+\tif (IS_ERR(base))\n+\t\treturn PTR_ERR(base);\n+\n+\tqmp->com = base + offs->com;\n+\tqmp->serdes = base + offs->usb3_serdes;\n+\tqmp->tx = base + offs->txa;\n+\tqmp->rx = base + offs->rxa;\n+\tqmp->tx2 = base + offs->txb;\n+\tqmp->rx2 = base + offs->rxb;\n+\tqmp->pcs = base + offs->usb3_pcs;\n+\tqmp->pcs_usb = base + offs->usb3_pcs_usb;\n+\tqmp->pcs_misc = base + offs->usb3_pcs_misc;\n+\n+\tret = qmp_combo_clk_init(qmp);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tqmp->pipe_clk = devm_clk_get(dev, \"usb3_pipe\");\n+\tif (IS_ERR(qmp->pipe_clk)) {\n+\t\tdev_err(dev, \"failed to get pipe clock (%ld)\\n\",\n+\t\t\tPTR_ERR(qmp->pipe_clk));\n+\t\treturn ret;\n+\t}\n+\n+\tret = qmp_combo_reset_init(qmp);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = qmp_combo_vreg_init(qmp);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int qmp_combo_probe(struct udevice *dev)\n+{\n+\tstruct qmp_combo *qmp = dev_get_priv(dev);\n+\tint ret;\n+\n+\tqmp->dev = dev;\n+\tqmp->cfg = (const struct qmp_phy_cfg *)dev_get_driver_data(dev);\n+\tif (!qmp->cfg) {\n+\t\tprintf(\"Failed to get PHY configuration\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = qmp_combo_parse_dt(qmp);\n+\n+\treturn ret;\n+}\n+\n+static const struct qmp_phy_cfg sc7280_usb3dpphy_cfg = {\n+\t.offsets\t\t= &qmp_combo_offsets_v3,\n+\t.serdes_tbl\t\t= sm8150_usb3_serdes_tbl,\n+\t.serdes_tbl_num\t\t= ARRAY_SIZE(sm8150_usb3_serdes_tbl),\n+\t.tx_tbl\t\t\t= sm8250_usb3_tx_tbl,\n+\t.tx_tbl_num\t\t= ARRAY_SIZE(sm8250_usb3_tx_tbl),\n+\t.rx_tbl\t\t\t= sm8250_usb3_rx_tbl,\n+\t.rx_tbl_num\t\t= ARRAY_SIZE(sm8250_usb3_rx_tbl),\n+\t.pcs_tbl\t\t= sm8250_usb3_pcs_tbl,\n+\t.pcs_tbl_num\t\t= ARRAY_SIZE(sm8250_usb3_pcs_tbl),\n+\t.pcs_usb_tbl\t\t= sm8250_usb3_pcs_usb_tbl,\n+\t.pcs_usb_tbl_num\t= ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl),\n+\t.vreg_list\t\t= qmp_phy_vreg_l,\n+\t.num_vregs\t\t= ARRAY_SIZE(qmp_phy_vreg_l),\n+\n+\t.has_pwrdn_delay\t= true,\n+};\n+\n+static int qmp_combo_xlate(struct phy *phy, struct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count != 1) {\n+\t\tdebug(\"Invalid args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* We only support the USB3 phy at slot 0 */\n+\tif (args->args[0] == QMP_USB43DP_DP_PHY)\n+\t\treturn -EINVAL;\n+\n+\tphy->id = QMP_USB43DP_USB3_PHY;\n+\n+\treturn 0;\n+}\n+\n+static struct phy_ops qmp_combo_ops = {\n+\t.init = qmp_combo_power_on,\n+\t.exit = qmp_combo_power_off,\n+\t.of_xlate = qmp_combo_xlate,\n+};\n+\n+static const struct udevice_id qmp_combo_ids[] = {\n+\t{\n+\t\t.compatible = \"qcom,sc7280-qmp-usb3-dp-phy\",\n+\t\t.data = (ulong)&sc7280_usb3dpphy_cfg,\n+\t},\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(qmp_combo) = {\n+\t.name = \"qcom-qmp-usb3-dp-phy\",\n+\t.id = UCLASS_PHY,\n+\t.of_match = qmp_combo_ids,\n+\t.ops = &qmp_combo_ops,\n+\t.probe = qmp_combo_probe,\n+\t.priv_auto = sizeof(struct qmp_combo),\n+};\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp-common.h b/drivers/phy/qcom/phy-qcom-qmp-common.h\nnew file mode 100644\nindex 00000000000..71356fb7dd0\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp-common.h\n@@ -0,0 +1,62 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/*\n+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.\n+ */\n+\n+#ifndef QCOM_PHY_QMP_COMMON_H_\n+#define QCOM_PHY_QMP_COMMON_H_\n+\n+struct qmp_phy_init_tbl {\n+\tunsigned int offset;\n+\tunsigned int val;\n+\tchar *name;\n+\t/*\n+\t * mask of lanes for which this register is written\n+\t * for cases when second lane needs different values\n+\t */\n+\tu8 lane_mask;\n+};\n+\n+#define QMP_PHY_INIT_CFG(o, v)\t\t\\\n+\t{\t\t\t\t\\\n+\t\t.offset = o,\t\t\\\n+\t\t.val = v,\t\t\\\n+\t\t.name = #o,\t\t\\\n+\t\t.lane_mask = 0xff,\t\\\n+\t}\n+\n+#define QMP_PHY_INIT_CFG_LANE(o, v, l)\t\\\n+\t{\t\t\t\t\\\n+\t\t.offset = o,\t\t\\\n+\t\t.val = v,\t\t\\\n+\t\t.name = #o,\t\t\\\n+\t\t.lane_mask = l,\t\t\\\n+\t}\n+\n+static inline void qmp_configure_lane(struct udevice *dev, void __iomem *base,\n+\t\t\t\t const struct qmp_phy_init_tbl tbl[],\n+\t\t\t\t int num, u8 lane_mask)\n+{\n+\tint i;\n+\tconst struct qmp_phy_init_tbl *t = tbl;\n+\n+\tif (!t)\n+\t\treturn;\n+\n+\tfor (i = 0; i < num; i++, t++) {\n+\t\tif (!(t->lane_mask & lane_mask))\n+\t\t\tcontinue;\n+\n+\t\tdev_dbg(dev, \"Writing Reg: %s Offset: 0x%04x Val: 0x%02x\\n\",\n+\t\t\tt->name, t->offset, t->val);\n+\t\twritel(t->val, base + t->offset);\n+\t}\n+}\n+\n+static inline void qmp_configure(struct udevice *dev, void __iomem *base,\n+\t\t\t\t const struct qmp_phy_init_tbl tbl[], int num)\n+{\n+\tqmp_configure_lane(dev, base, tbl, num, 0xff);\n+}\n+\n+#endif\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp-dp-com-v3.h b/drivers/phy/qcom/phy-qcom-qmp-dp-com-v3.h\nnew file mode 100644\nindex 00000000000..396179ef38b\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp-dp-com-v3.h\n@@ -0,0 +1,18 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/*\n+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.\n+ */\n+\n+#ifndef QCOM_PHY_QMP_DP_COM_V3_H_\n+#define QCOM_PHY_QMP_DP_COM_V3_H_\n+\n+/* Only for QMP V3 & V4 PHY - DP COM registers */\n+#define QPHY_V3_DP_COM_PHY_MODE_CTRL\t\t\t0x00\n+#define QPHY_V3_DP_COM_SW_RESET\t\t\t\t0x04\n+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL\t\t\t0x08\n+#define QPHY_V3_DP_COM_SWI_CTRL\t\t\t\t0x0c\n+#define QPHY_V3_DP_COM_TYPEC_CTRL\t\t\t0x10\n+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL\t\t\t0x14\n+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL\t\t\t0x1c\n+\n+#endif\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-usb-v4.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-usb-v4.h\nnew file mode 100644\nindex 00000000000..d7fd4ac0fc5\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-usb-v4.h\n@@ -0,0 +1,34 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/*\n+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.\n+ */\n+\n+#ifndef QCOM_PHY_QMP_PCS_USB_V4_H_\n+#define QCOM_PHY_QMP_PCS_USB_V4_H_\n+\n+/* Only for QMP V4 PHY - USB3 PCS registers */\n+#define QPHY_V4_PCS_USB3_POWER_STATE_CONFIG1\t\t0x000\n+#define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_STATUS\t\t0x004\n+#define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL\t\t0x008\n+#define QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL2\t\t0x00c\n+#define QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_SOURCE_STATUS\t0x010\n+#define QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR\t\t0x014\n+#define QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL\t0x018\n+#define QPHY_V4_PCS_USB3_LFPS_TX_ECSTART\t\t0x01c\n+#define QPHY_V4_PCS_USB3_LFPS_PER_TIMER_VAL\t\t0x020\n+#define QPHY_V4_PCS_USB3_LFPS_TX_END_CNT_U3_START\t0x024\n+#define QPHY_V4_PCS_USB3_RXEQTRAINING_LOCK_TIME\t\t0x028\n+#define QPHY_V4_PCS_USB3_RXEQTRAINING_WAIT_TIME\t\t0x02c\n+#define QPHY_V4_PCS_USB3_RXEQTRAINING_CTLE_TIME\t\t0x030\n+#define QPHY_V4_PCS_USB3_RXEQTRAINING_WAIT_TIME_S2\t0x034\n+#define QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2\t0x038\n+#define QPHY_V4_PCS_USB3_RCVR_DTCT_DLY_U3_L\t\t0x03c\n+#define QPHY_V4_PCS_USB3_RCVR_DTCT_DLY_U3_H\t\t0x040\n+#define QPHY_V4_PCS_USB3_ARCVR_DTCT_EN_PERIOD\t\t0x044\n+#define QPHY_V4_PCS_USB3_ARCVR_DTCT_CM_DLY\t\t0x048\n+#define QPHY_V4_PCS_USB3_TXONESZEROS_RUN_LENGTH\t\t0x04c\n+#define QPHY_V4_PCS_USB3_ALFPS_DEGLITCH_VAL\t\t0x050\n+#define QPHY_V4_PCS_USB3_SIGDET_STARTUP_TIMER_VAL\t0x054\n+#define QPHY_V4_PCS_USB3_TEST_CONTROL\t\t\t0x058\n+\n+#endif\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp.h b/drivers/phy/qcom/phy-qcom-qmp.h\nindex 99f4d447caf..06dac21ddc4 100644\n--- a/drivers/phy/qcom/phy-qcom-qmp.h\n+++ b/drivers/phy/qcom/phy-qcom-qmp.h\n@@ -12,12 +12,17 @@\n #include \"phy-qcom-qmp-qserdes-com-v3.h\"\n #include \"phy-qcom-qmp-qserdes-txrx-v3.h\"\n \n+#include \"phy-qcom-qmp-qserdes-com-v4.h\"\n+#include \"phy-qcom-qmp-qserdes-txrx-v4.h\"\n+\n #include \"phy-qcom-qmp-qserdes-pll.h\"\n \n #include \"phy-qcom-qmp-pcs-v2.h\"\n \n #include \"phy-qcom-qmp-pcs-v3.h\"\n \n+#include \"phy-qcom-qmp-pcs-v4.h\"\n+\n /* Only for QMP V3 & V4 PHY - DP COM registers */\n #define QPHY_V3_DP_COM_PHY_MODE_CTRL\t\t\t0x00\n #define QPHY_V3_DP_COM_SW_RESET\t\t\t\t0x04\n@@ -112,4 +117,16 @@\n #define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS\t\t0x0e0\n #define QSERDES_V6_DP_PHY_STATUS\t\t\t0x0e4\n \n+/* QPHY_SW_RESET bit */\n+#define SW_RESET BIT(0)\n+/* QPHY_POWER_DOWN_CONTROL */\n+#define SW_PWRDN BIT(0)\n+\n+/* QPHY_START_CONTROL bits */\n+#define SERDES_START BIT(0)\n+#define PCS_START BIT(1)\n+\n+/* QPHY_PCS_STATUS bit */\n+#define PHYSTATUS BIT(6)\n+\n #endif\n", "prefixes": [ "v4", "2/5" ] }