get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1821141/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1821141,
    "url": "http://patchwork.ozlabs.org/api/patches/1821141/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20230814215457.4075025-5-bhupesh.sharma@linaro.org/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/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": "<20230814215457.4075025-5-bhupesh.sharma@linaro.org>",
    "list_archive_url": null,
    "date": "2023-08-14T21:54:44",
    "name": "[04/17] phy: qcom: Add QMP UFS PHY driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "192761691f2165b31cd5347c25fddd919389dd3e",
    "submitter": {
        "id": 81316,
        "url": "http://patchwork.ozlabs.org/api/people/81316/?format=api",
        "name": "Bhupesh Sharma",
        "email": "bhupesh.sharma@linaro.org"
    },
    "delegate": {
        "id": 3651,
        "url": "http://patchwork.ozlabs.org/api/users/3651/?format=api",
        "username": "trini",
        "first_name": "Tom",
        "last_name": "Rini",
        "email": "trini@ti.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20230814215457.4075025-5-bhupesh.sharma@linaro.org/mbox/",
    "series": [
        {
            "id": 368803,
            "url": "http://patchwork.ozlabs.org/api/series/368803/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=368803",
            "date": "2023-08-14T21:54:40",
            "name": "Enable UFS on DragonBoard845c",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/368803/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1821141/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1821141/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 spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)",
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=A4Cn6KEy;\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=linaro.org",
            "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=linaro.org header.i=@linaro.org header.b=\"A4Cn6KEy\";\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=linaro.org",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=bhupesh.sharma@linaro.org"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (P-384))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4RPpB70pqSz1yfS\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 15 Aug 2023 07:55:59 +1000 (AEST)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 40CAF8699C;\n\tMon, 14 Aug 2023 23:55:33 +0200 (CEST)",
            "by phobos.denx.de (Postfix, from userid 109)\n id 72BB78699B; Mon, 14 Aug 2023 23:55:32 +0200 (CEST)",
            "from mail-pl1-x633.google.com (mail-pl1-x633.google.com\n [IPv6:2607:f8b0:4864:20::633])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 480918699B\n for <u-boot@lists.denx.de>; Mon, 14 Aug 2023 23:55:28 +0200 (CEST)",
            "by mail-pl1-x633.google.com with SMTP id\n d9443c01a7336-1bc83a96067so29659995ad.0\n for <u-boot@lists.denx.de>; Mon, 14 Aug 2023 14:55:28 -0700 (PDT)",
            "from localhost.localdomain\n ([2401:4900:1f3b:3924:6581:8508:2ecb:b5dd])\n by smtp.gmail.com with ESMTPSA id\n n4-20020a170903110400b001bba373919bsm9872075plh.261.2023.08.14.14.55.21\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Mon, 14 Aug 2023 14:55:25 -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,SPF_HELO_NONE,SPF_PASS\n autolearn=ham autolearn_force=no version=3.4.2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1692050126; x=1692654926;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=ZbYaAINPG+KPVlYn0lX6k6c8pTEWv2MjXb6Dk0aqY2Q=;\n b=A4Cn6KEy5qvwAiL96I41daW3Tw4etnJdIgEY9JxFEjNrqWe4HF9KVdwBp0fHu0WpSz\n fRTsQGlG3TODjiJnUrVAcnDkWwzgUBBLetuRoNPFZYcPt3ZOenT3KnzWMt1DkMjSx/s3\n +0iS3tPJMm6fAKfWdRnJoTjAMTQzk7MvWgLHv/L6uJgbyTAg7KLwD1iWXbufqGV1p+AS\n dDdGk8mqK4Zmo0YjUMYYvyUSrkaSFGb100xwWhoVjv6KiRBAB+MjmrM0v+e7gePrlfom\n yROyMvwQzG/RxeSKAGdjv2a1OsYqCcOgJQ6VO7lLHxEpV1YMINC5v0INfj5YAIvviiZk\n ORhQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20221208; t=1692050126; x=1692654926;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=ZbYaAINPG+KPVlYn0lX6k6c8pTEWv2MjXb6Dk0aqY2Q=;\n b=LDd/5PZFt+xzddyQ70KQG1cXLPKJ48g9wRzyglqO+I17+OeTJcHnofVM5AFuZHeR7i\n 1q8xITRgKDNl85jaFxCGkExnGYiu2jKw4tENHUlszFXqyeu/PcNhiWUaVUyfxFywFLOf\n W1AMi8UhLHY/0mLhpc426DmPtGe9bfk64Ji93mQSGR4htI5rUT3wJ/Nefipna7sEBqvm\n Kj8/nmBoKElAk2x+iEjZqPflJIMFqYFMgt8UfbiDX8zqQAMsbeWOxnZWYZujcrPdvTnc\n wk9RdxlTpK+6O2So8jem1pI0dv++GQUoOUPUj2CpurWsvZc4Hzj4kIMURScxVURUgWvX\n NSJA==",
        "X-Gm-Message-State": "AOJu0Yxx77C96IRnvGtTvG9lyzlBB4/9k12KXWoVZqPNH4B6hqmGbzaI\n Y/S0XWYkG/PQ5C6hQTru+kyyimqiBgp9VKK7qu4=",
        "X-Google-Smtp-Source": "\n AGHT+IEhF92gAkgPcShPsDLiAK3cg3czte7QxFjZQqJpiNdS/q1eu4dEP59UzoEuXexozIciVSd/4g==",
        "X-Received": "by 2002:a17:903:1c9:b0:1bc:afa:95a6 with SMTP id\n e9-20020a17090301c900b001bc0afa95a6mr10558527plh.40.1692050126011;\n Mon, 14 Aug 2023 14:55:26 -0700 (PDT)",
        "From": "Bhupesh Sharma <bhupesh.sharma@linaro.org>",
        "To": "u-boot@lists.denx.de",
        "Cc": "sjg@chromium.org, trini@konsulko.com, bhupesh.sharma@linaro.org,\n bhupesh.linux@gmail.com, marek.vasut+renesas@mailbox.org,\n sumit.garg@linaro.org, rfried.dev@gmail.com, patrice.chotard@foss.st.com,\n jbx6244@gmail.com, kever.yang@rock-chips.com, eugen.hristev@collabora.com",
        "Subject": "[PATCH 04/17] phy: qcom: Add QMP UFS PHY driver",
        "Date": "Tue, 15 Aug 2023 03:24:44 +0530",
        "Message-Id": "<20230814215457.4075025-5-bhupesh.sharma@linaro.org>",
        "X-Mailer": "git-send-email 2.38.1",
        "In-Reply-To": "<20230814215457.4075025-1-bhupesh.sharma@linaro.org>",
        "References": "<20230814215457.4075025-1-bhupesh.sharma@linaro.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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 Qualcomm QMP UFS PHY driver which is available on the following\nSnapdragon SoCs - SDM845, SM6115 and SM8250 SoCs.\n\nSigned-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>\n---\n drivers/phy/qcom/Kconfig            |   6 +\n drivers/phy/qcom/Makefile           |   1 +\n drivers/phy/qcom/phy-qcom-qmp-ufs.c | 996 ++++++++++++++++++++++++++++\n drivers/phy/qcom/phy-qcom-qmp.h     | 115 ++++\n 4 files changed, 1118 insertions(+)\n create mode 100644 drivers/phy/qcom/phy-qcom-qmp-ufs.c\n create mode 100644 drivers/phy/qcom/phy-qcom-qmp.h",
    "diff": "diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig\nindex f4ca174805..38536566ca 100644\n--- a/drivers/phy/qcom/Kconfig\n+++ b/drivers/phy/qcom/Kconfig\n@@ -12,6 +12,12 @@ 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_UFS\n+\ttristate \"Qualcomm QMP UFS PHY driver\"\n+\tdepends on PHY && ARCH_SNAPDRAGON\n+\thelp\n+\t  Enable this to support the UFS QMP PHY on various Qualcomm chipsets.\n+\n config PHY_QCOM_USB_HS_28NM\n \ttristate \"Qualcomm 28nm High-Speed PHY\"\n \tdepends on PHY && ARCH_SNAPDRAGON\ndiff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile\nindex 2113f178c0..e804f127b0 100644\n--- a/drivers/phy/qcom/Makefile\n+++ b/drivers/phy/qcom/Makefile\n@@ -1,4 +1,5 @@\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_UFS) += phy-qcom-qmp-ufs.o\n obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o\n obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp-ufs.c b/drivers/phy/qcom/phy-qcom-qmp-ufs.c\nnew file mode 100644\nindex 0000000000..16e95175bb\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp-ufs.c\n@@ -0,0 +1,996 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * Copyright (C) 2023 Bhupesh Sharma <bhupesh.sharma@linaro.org>\n+ *\n+ * Based on Linux driver\n+ */\n+\n+#include <clk.h>\n+#include <clk-uclass.h>\n+#include <common.h>\n+#include <dm.h>\n+#include <dm/device_compat.h>\n+#include <dm/devres.h>\n+#include <generic-phy.h>\n+#include <malloc.h>\n+#include <reset.h>\n+\n+#include <asm/io.h>\n+#include <linux/bitops.h>\n+#include <linux/clk-provider.h>\n+#include <linux/delay.h>\n+#include <linux/iopoll.h>\n+#include <linux/ioport.h>\n+\n+#include <dt-bindings/clock/qcom,gcc-sm6115.h>\n+\n+#include \"phy-qcom-qmp.h\"\n+#include \"phy-qcom-qmp-pcs-ufs-v2.h\"\n+#include \"phy-qcom-qmp-pcs-ufs-v3.h\"\n+#include \"phy-qcom-qmp-pcs-ufs-v4.h\"\n+#include \"phy-qcom-qmp-pcs-ufs-v5.h\"\n+#include \"phy-qcom-qmp-pcs-ufs-v6.h\"\n+\n+#include \"phy-qcom-qmp-qserdes-com-v4.h\"\n+#include \"phy-qcom-qmp-qserdes-txrx-v4.h\"\n+#include \"phy-qcom-qmp-qserdes-txrx-ufs-v6.h\"\n+\n+/* QPHY_SW_RESET bit */\n+#define SW_RESET\t\t\t\tBIT(0)\n+/* QPHY_POWER_DOWN_CONTROL */\n+#define SW_PWRDN\t\t\t\tBIT(0)\n+/* QPHY_START_CONTROL bits */\n+#define SERDES_START\t\t\t\tBIT(0)\n+#define PCS_START\t\t\t\tBIT(1)\n+/* QPHY_PCS_READY_STATUS bit */\n+#define PCS_READY\t\t\t\tBIT(0)\n+\n+#define PHY_INIT_COMPLETE_TIMEOUT\t\t(200 * 10000)\n+\n+struct qmp_ufs_init_tbl {\n+\tunsigned int offset;\n+\tunsigned int val;\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.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.lane_mask = l,\t\t\\\n+\t}\n+\n+enum ufs_hs_gear_tag {\n+\tUFS_HS_DONT_CHANGE,\t/* Don't change Gear */\n+\tUFS_HS_G1,\t\t/* HS Gear 1 (default for reset) */\n+\tUFS_HS_G2,\t\t/* HS Gear 2 */\n+\tUFS_HS_G3,\t\t/* HS Gear 3 */\n+\tUFS_HS_G4,\t\t/* HS Gear 4 */\n+\tUFS_HS_G5\t\t/* HS Gear 5 */\n+};\n+\n+/* set of registers with offsets different per-PHY */\n+enum qphy_reg_layout {\n+\t/* PCS registers */\n+\tQPHY_SW_RESET,\n+\tQPHY_START_CTRL,\n+\tQPHY_PCS_READY_STATUS,\n+\tQPHY_PCS_POWER_DOWN_CONTROL,\n+\t/* Keep last to ensure regs_layout arrays are properly initialized */\n+\tQPHY_LAYOUT_SIZE\n+};\n+\n+static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {\n+\t[QPHY_START_CTRL]\t\t= QPHY_V2_PCS_UFS_PHY_START,\n+\t[QPHY_PCS_READY_STATUS]\t\t= QPHY_V2_PCS_UFS_READY_STATUS,\n+\t[QPHY_PCS_POWER_DOWN_CONTROL]\t= QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL,\n+};\n+\n+static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {\n+\t[QPHY_START_CTRL]\t\t= QPHY_V3_PCS_UFS_PHY_START,\n+\t[QPHY_PCS_READY_STATUS]\t\t= QPHY_V3_PCS_UFS_READY_STATUS,\n+\t[QPHY_PCS_POWER_DOWN_CONTROL]\t= QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL,\n+};\n+\n+static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {\n+\t[QPHY_START_CTRL]\t\t= QPHY_V4_PCS_UFS_PHY_START,\n+\t[QPHY_PCS_READY_STATUS]\t\t= QPHY_V4_PCS_UFS_READY_STATUS,\n+\t[QPHY_SW_RESET]\t\t\t= QPHY_V4_PCS_UFS_SW_RESET,\n+\t[QPHY_PCS_POWER_DOWN_CONTROL]\t= QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,\n+};\n+\n+static const struct qmp_ufs_init_tbl sdm845_ufsphy_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),\n+};\n+\n+static const struct qmp_ufs_init_tbl sdm845_ufsphy_hs_b_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),\n+};\n+\n+static const struct qmp_ufs_init_tbl sdm845_ufsphy_tx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),\n+};\n+\n+static const struct qmp_ufs_init_tbl sdm845_ufsphy_rx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),\n+};\n+\n+static const struct qmp_ufs_init_tbl sdm845_ufsphy_pcs[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),\n+\tQMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm6115_ufsphy_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm6115_ufsphy_hs_b_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm6115_ufsphy_tx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),\n+\tQMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm6115_ufsphy_rx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm6115_ufsphy_pcs[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),\n+\tQMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_b_serdes[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_tx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_rx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),\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_MODE_00_LOW, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_pcs[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),\n+\tQMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_tx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),\n+};\n+\n+static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_rx[] = {\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),\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, 0x2c),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),\n+\tQMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),\n+};\n+\n+struct qmp_ufs_offsets {\n+\tu16 serdes;\n+\tu16 pcs;\n+\tu16 tx;\n+\tu16 rx;\n+\t/* for PHYs with >= 2 lanes */\n+\tu16 tx2;\n+\tu16 rx2;\n+};\n+\n+struct qmp_ufs_cfg_tbls {\n+\t/* Init sequence for PHY blocks - serdes, tx, rx, pcs */\n+\tconst struct qmp_ufs_init_tbl *serdes;\n+\tint serdes_num;\n+\tconst struct qmp_ufs_init_tbl *tx;\n+\tint tx_num;\n+\tconst struct qmp_ufs_init_tbl *rx;\n+\tint rx_num;\n+\tconst struct qmp_ufs_init_tbl *pcs;\n+\tint pcs_num;\n+};\n+\n+/* struct qmp_ufs_cfg - per-PHY initialization config */\n+struct qmp_ufs_cfg {\n+\tint lanes;\n+\n+\tconst struct qmp_ufs_offsets *offsets;\n+\n+\t/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */\n+\tconst struct qmp_ufs_cfg_tbls tbls;\n+\t/* Additional sequence for HS Series B */\n+\tconst struct qmp_ufs_cfg_tbls tbls_hs_b;\n+\t/* Additional sequence for HS G4 */\n+\tconst struct qmp_ufs_cfg_tbls tbls_hs_g4;\n+\n+\t/* clock ids to be requested */\n+\tconst char * const *clk_list;\n+\tint num_clks;\n+\t/* regulators to be requested */\n+\tconst char * const *vreg_list;\n+\tint num_vregs;\n+\t/* resets to be requested */\n+\tconst char * const *reset_list;\n+\tint num_resets;\n+\n+\t/* array of registers with different offsets */\n+\tconst unsigned int *regs;\n+\n+\t/* true, if PCS block has no separate SW_RESET register */\n+\tbool no_pcs_sw_reset;\n+};\n+\n+struct qmp_ufs_priv {\n+\tstruct phy *phy;\n+\n+\tvoid __iomem *serdes;\n+\tvoid __iomem *pcs;\n+\tvoid __iomem *pcs_misc;\n+\tvoid __iomem *tx;\n+\tvoid __iomem *rx;\n+\tvoid __iomem *tx2;\n+\tvoid __iomem *rx2;\n+\n+\tstruct clk *clks;\n+\tunsigned int clk_count;\n+\n+\tstruct reset_ctl *resets;\n+\tunsigned int reset_count;\n+\n+\tconst struct qmp_ufs_cfg *cfg;\n+\n+\tstruct udevice *dev;\n+\n+\tu32 mode;\n+\tu32 submode;\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+/* list of clocks required by phy */\n+static const char * const sdm845_ufs_phy_clk_l[] = {\n+\t\"ref\", \"ref_aux\",\n+};\n+\n+/* list of regulators */\n+static const char * const qmp_ufs_vreg_l[] = {\n+\t\"vdda-phy\", \"vdda-pll\",\n+};\n+\n+/* list of resets */\n+static const char * const qmp_ufs_reset_l[] = {\n+\t\"ufsphy\",\n+};\n+\n+static const struct qmp_ufs_offsets qmp_ufs_offsets = {\n+\t.serdes\t\t= 0,\n+\t.pcs\t\t= 0xc00,\n+\t.tx\t\t= 0x400,\n+\t.rx\t\t= 0x600,\n+\t.tx2\t\t= 0x800,\n+\t.rx2\t\t= 0xa00,\n+};\n+\n+static const struct qmp_ufs_cfg sdm845_ufsphy_cfg = {\n+\t.lanes\t\t\t= 2,\n+\n+\t.tbls = {\n+\t\t.serdes\t\t= sdm845_ufsphy_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sdm845_ufsphy_serdes),\n+\t\t.tx\t\t= sdm845_ufsphy_tx,\n+\t\t.tx_num\t\t= ARRAY_SIZE(sdm845_ufsphy_tx),\n+\t\t.rx\t\t= sdm845_ufsphy_rx,\n+\t\t.rx_num\t\t= ARRAY_SIZE(sdm845_ufsphy_rx),\n+\t\t.pcs\t\t= sdm845_ufsphy_pcs,\n+\t\t.pcs_num\t= ARRAY_SIZE(sdm845_ufsphy_pcs),\n+\t},\n+\t.tbls_hs_b = {\n+\t\t.serdes\t\t= sdm845_ufsphy_hs_b_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),\n+\t},\n+\t.clk_list\t\t= sdm845_ufs_phy_clk_l,\n+\t.num_clks\t\t= ARRAY_SIZE(sdm845_ufs_phy_clk_l),\n+\t.vreg_list\t\t= qmp_ufs_vreg_l,\n+\t.num_vregs\t\t= ARRAY_SIZE(qmp_ufs_vreg_l),\n+\t.regs\t\t\t= ufsphy_v3_regs_layout,\n+\n+\t.no_pcs_sw_reset\t= true,\n+};\n+\n+static const struct qmp_ufs_cfg sm6115_ufsphy_cfg = {\n+\t.lanes\t\t\t= 1,\n+\n+\t.offsets\t\t= &qmp_ufs_offsets,\n+\n+\t.tbls = {\n+\t\t.serdes\t\t= sm6115_ufsphy_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sm6115_ufsphy_serdes),\n+\t\t.tx\t\t= sm6115_ufsphy_tx,\n+\t\t.tx_num\t\t= ARRAY_SIZE(sm6115_ufsphy_tx),\n+\t\t.rx\t\t= sm6115_ufsphy_rx,\n+\t\t.rx_num\t\t= ARRAY_SIZE(sm6115_ufsphy_rx),\n+\t\t.pcs\t\t= sm6115_ufsphy_pcs,\n+\t\t.pcs_num\t= ARRAY_SIZE(sm6115_ufsphy_pcs),\n+\t},\n+\t.tbls_hs_b = {\n+\t\t.serdes\t\t= sm6115_ufsphy_hs_b_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes),\n+\t},\n+\t.clk_list\t\t= sdm845_ufs_phy_clk_l,\n+\t.num_clks\t\t= ARRAY_SIZE(sdm845_ufs_phy_clk_l),\n+\t.vreg_list\t\t= qmp_ufs_vreg_l,\n+\t.num_vregs\t\t= ARRAY_SIZE(qmp_ufs_vreg_l),\n+\t.reset_list\t\t= qmp_ufs_reset_l,\n+\t.num_resets\t\t= ARRAY_SIZE(qmp_ufs_reset_l),\n+\t.regs\t\t\t= ufsphy_v2_regs_layout,\n+\n+\t.no_pcs_sw_reset\t= true,\n+};\n+\n+static const struct qmp_ufs_cfg sm8250_ufsphy_cfg = {\n+\t.lanes\t\t\t= 2,\n+\n+\t.tbls = {\n+\t\t.serdes\t\t= sm8150_ufsphy_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sm8150_ufsphy_serdes),\n+\t\t.tx\t\t= sm8150_ufsphy_tx,\n+\t\t.tx_num\t\t= ARRAY_SIZE(sm8150_ufsphy_tx),\n+\t\t.rx\t\t= sm8150_ufsphy_rx,\n+\t\t.rx_num\t\t= ARRAY_SIZE(sm8150_ufsphy_rx),\n+\t\t.pcs\t\t= sm8150_ufsphy_pcs,\n+\t\t.pcs_num\t= ARRAY_SIZE(sm8150_ufsphy_pcs),\n+\t},\n+\t.tbls_hs_b = {\n+\t\t.serdes\t\t= sm8150_ufsphy_hs_b_serdes,\n+\t\t.serdes_num\t= ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),\n+\t},\n+\t.tbls_hs_g4 = {\n+\t\t.tx\t\t= sm8250_ufsphy_hs_g4_tx,\n+\t\t.tx_num\t\t= ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),\n+\t\t.rx\t\t= sm8250_ufsphy_hs_g4_rx,\n+\t\t.rx_num\t\t= ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),\n+\t\t.pcs\t\t= sm8150_ufsphy_hs_g4_pcs,\n+\t\t.pcs_num\t= ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),\n+\t},\n+\t.clk_list\t\t= sdm845_ufs_phy_clk_l,\n+\t.num_clks\t\t= ARRAY_SIZE(sdm845_ufs_phy_clk_l),\n+\t.vreg_list\t\t= qmp_ufs_vreg_l,\n+\t.num_vregs\t\t= ARRAY_SIZE(qmp_ufs_vreg_l),\n+\t.reset_list\t\t= qmp_ufs_reset_l,\n+\t.num_resets\t\t= ARRAY_SIZE(qmp_ufs_reset_l),\n+\t.regs\t\t\t= ufsphy_v4_regs_layout,\n+\n+\t.no_pcs_sw_reset\t= false,\n+};\n+\n+static void qmp_ufs_configure_lane(void __iomem *base,\n+\t\t\t\t\tconst struct qmp_ufs_init_tbl tbl[],\n+\t\t\t\t\tint num,\n+\t\t\t\t\tu8 lane_mask)\n+{\n+\tint i;\n+\tconst struct qmp_ufs_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\twritel(t->val, base + t->offset);\n+\t}\n+}\n+\n+static void qmp_ufs_configure(void __iomem *base,\n+\t\t\t\t   const struct qmp_ufs_init_tbl tbl[],\n+\t\t\t\t   int num)\n+{\n+\tqmp_ufs_configure_lane(base, tbl, num, 0xff);\n+}\n+\n+static void qmp_ufs_serdes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)\n+{\n+\tvoid __iomem *serdes = qmp->serdes;\n+\n+\tqmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);\n+}\n+\n+static void qmp_ufs_lanes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)\n+{\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\tvoid __iomem *tx = qmp->tx;\n+\tvoid __iomem *rx = qmp->rx;\n+\n+\tqmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);\n+\tqmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);\n+\n+\tif (cfg->lanes >= 2) {\n+\t\tqmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);\n+\t\tqmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);\n+\t}\n+}\n+\n+static void qmp_ufs_pcs_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)\n+{\n+\tvoid __iomem *pcs = qmp->pcs;\n+\n+\tqmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);\n+}\n+\n+static void qmp_ufs_init_registers(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg *cfg)\n+{\n+\t/* We support 'PHY_MODE_UFS_HS_B' mode & 'UFS_HS_G3' submode for now. */\n+\tqmp_ufs_serdes_init(qmp, &cfg->tbls);\n+\tqmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);\n+\tqmp_ufs_lanes_init(qmp, &cfg->tbls);\n+\tqmp_ufs_pcs_init(qmp, &cfg->tbls);\n+}\n+\n+static int qmp_ufs_do_reset(struct qmp_ufs_priv *qmp)\n+{\n+\tint i, ret;\n+\n+\tfor (i = 0; i < qmp->reset_count; i++) {\n+\t\tret = reset_assert(&qmp->resets[i]);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tudelay(10);\n+\n+\tfor (i = 0; i < qmp->reset_count; i++) {\n+\t\tret = reset_deassert(&qmp->resets[i]);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tudelay(50);\n+\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_power_on(struct phy *phy)\n+{\n+\tstruct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\tvoid __iomem *pcs = qmp->pcs;\n+\tvoid __iomem *status;\n+\tunsigned int val;\n+\tint ret;\n+\n+\t/* Power down PHY */\n+\tqphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);\n+\n+\tqmp_ufs_init_registers(qmp, cfg);\n+\n+\tif (cfg->no_pcs_sw_reset) {\n+\t\tret = qmp_ufs_do_reset(qmp);\n+\t\tif (ret) {\n+\t\t\tprintf(\"%s: qmp reset failed\\n\", __func__);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\t/* Pull PHY out of reset state */\n+\tif (!cfg->no_pcs_sw_reset)\n+\t\tqphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);\n+\n+\t/* start SerDes */\n+\tqphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);\n+\n+\tstatus = pcs + cfg->regs[QPHY_PCS_READY_STATUS];\n+\tret = readl_poll_timeout(status, val, (val & PCS_READY), PHY_INIT_COMPLETE_TIMEOUT);\n+\tif (ret) {\n+\t\tprintf(\"%s: phy initialization timed-out\\n\", __func__);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_power_off(struct phy *phy)\n+{\n+\tstruct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\n+\t/* PHY reset */\n+\tqphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);\n+\n+\t/* stop SerDes and Phy-Coding-Sublayer */\n+\tqphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],\n+\t\t\tSERDES_START | PCS_START);\n+\n+\t/* Put PHY into POWER DOWN state: active low */\n+\tqphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],\n+\t\t\tSW_PWRDN);\n+\n+\tclk_release_all(qmp->clks, qmp->clk_count);\n+\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_vreg_init(struct udevice *dev, struct qmp_ufs_priv *qmp)\n+{\n+\t// TBD: Add regulator support later - if needed\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_reset_init(struct udevice *dev, struct qmp_ufs_priv *qmp)\n+{\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\tint num = cfg->num_resets;\n+\tint i, ret;\n+\n+\tqmp->reset_count = 0;\n+\tqmp->resets = devm_kcalloc(dev, num, sizeof(*qmp->resets), GFP_KERNEL);\n+\tif (!qmp->resets)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\tret = reset_get_by_index(dev, i, &qmp->resets[i]);\n+\t\tif (ret < 0) {\n+\t\t\tprintf(\"%s: failed to get reset %d\\n\", __func__, i);\n+\t\t\tgoto reset_get_err;\n+\t\t}\n+\n+\t\t++qmp->reset_count;\n+\t}\n+\n+\treturn 0;\n+\n+reset_get_err:\n+\tret = reset_release_all(qmp->resets, qmp->reset_count);\n+\tif (ret)\n+\t\tprintf(\"%s: failed to disable all resets\\n\", __func__);\n+\n+\treturn ret;\n+}\n+\n+static int qmp_ufs_clk_init(struct udevice *dev, struct qmp_ufs_priv *qmp)\n+{\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\tint num = cfg->num_clks;\n+\tint i, ret;\n+\n+\tqmp->clk_count = 0;\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_index(dev, i, &qmp->clks[i]);\n+\t\tif (ret < 0)\n+\t\t\tgoto clk_get_err;\n+\n+\t\tret = clk_enable(&qmp->clks[i]);\n+\t\tif (ret && ret != -ENOSYS) {\n+\t\t\tprintf(\"%s: failed to enable clock %d\\n\", __func__, i);\n+\t\t\tclk_free(&qmp->clks[i]);\n+\t\t\tgoto clk_get_err;\n+\t\t}\n+\n+\t\t++qmp->clk_count;\n+\t}\n+\n+\treturn 0;\n+\n+clk_get_err:\n+\tret = clk_release_all(qmp->clks, qmp->clk_count);\n+\tif (ret)\n+\t\tprintf(\"%s: failed to disable all clocks\\n\", __func__);\n+\n+\treturn ret;\n+}\n+\n+static int qmp_ufs_probe_generic_child(struct udevice *dev,\n+\t\t\t\t       ofnode child)\n+{\n+\tstruct qmp_ufs_priv *qmp = dev_get_priv(dev);\n+\tconst struct qmp_ufs_cfg *cfg = qmp->cfg;\n+\tstruct resource res;\n+\tint ret;\n+\n+\t/*\n+\t * Get memory resources for the PHY:\n+\t * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.\n+\t * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5\n+\t * For single lane PHYs: pcs_misc (optional) -> 3.\n+\t */\n+\tret = ofnode_read_resource(child, 0, &res);\n+\tif (ret) {\n+\t\tdev_err(dev, \"can't get reg property of child %s\\n\",\n+\t\t\tofnode_get_name(child));\n+\t\treturn ret;\n+\t}\n+\n+\tqmp->tx = (void __iomem *)res.start;\n+\n+\tret = ofnode_read_resource(child, 1, &res);\n+\tif (ret) {\n+\t\tdev_err(dev, \"can't get reg property of child %s\\n\",\n+\t\t\tofnode_get_name(child));\n+\t\treturn ret;\n+\t}\n+\n+\tqmp->rx = (void __iomem *)res.start;\n+\n+\tret = ofnode_read_resource(child, 2, &res);\n+\tif (ret) {\n+\t\tdev_err(dev, \"can't get reg property of child %s\\n\",\n+\t\t\tofnode_get_name(child));\n+\t\treturn ret;\n+\t}\n+\n+\tqmp->pcs = (void __iomem *)res.start;\n+\n+\tif (cfg->lanes >= 2) {\n+\t\tret = ofnode_read_resource(child, 3, &res);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"can't get reg property of child %s\\n\",\n+\t\t\t\tofnode_get_name(child));\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tqmp->tx2 = (void __iomem *)res.start;\n+\n+\t\tret = ofnode_read_resource(child, 4, &res);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"can't get reg property of child %s\\n\",\n+\t\t\t\tofnode_get_name(child));\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tqmp->rx2 = (void __iomem *)res.start;\n+\n+\t\tret = ofnode_read_resource(child, 5, &res);\n+\t\tif (ret)\n+\t\t\tqmp->pcs_misc = NULL;\n+\t} else {\n+\t\tret = ofnode_read_resource(child, 3, &res);\n+\t\tif (ret)\n+\t\t\tqmp->pcs_misc = NULL;\n+\t}\n+\n+\tif (!qmp->pcs_misc)\n+\t\tdev_warn(qmp->dev, \"PHY pcs_misc-reg not used\\n\");\n+\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_probe_dt_children(struct udevice *dev)\n+{\n+\tint ret;\n+\tofnode child;\n+\n+\tofnode_for_each_subnode(child, dev_ofnode(dev)) {\n+\t\tret = qmp_ufs_probe_generic_child(dev, child);\n+\t\tif (ret) {\n+\t\t\tdev_err(dev, \"Cannot parse child %s:%d\\n\",\n+\t\t\t\tofnode_get_name(child), ret);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qmp_ufs_probe(struct udevice *dev)\n+{\n+\tstruct qmp_ufs_priv *qmp = dev_get_priv(dev);\n+\tint ret;\n+\n+\tqmp->serdes = (void __iomem *)dev_read_addr(dev);\n+\tif (IS_ERR(qmp->serdes))\n+\t\treturn PTR_ERR(qmp->serdes);\n+\n+\tqmp->cfg = (const struct qmp_ufs_cfg *)dev_get_driver_data(dev);\n+\tif (!qmp->cfg)\n+\t\treturn -EINVAL;\n+\n+\tret = qmp_ufs_clk_init(dev, qmp);\n+\tif (ret) {\n+\t\tprintf(\"%s: failed to get UFS clks\\n\", __func__);\n+\t\treturn ret;\n+\t}\n+\n+\tret = qmp_ufs_vreg_init(dev, qmp);\n+\tif (ret) {\n+\t\tprintf(\"%s: failed to get UFS voltage regulators\\n\", __func__);\n+\t\treturn ret;\n+\t}\n+\n+\tif (qmp->cfg->no_pcs_sw_reset) {\n+\t\tret = qmp_ufs_reset_init(dev, qmp);\n+\t\tif (ret) {\n+\t\t\tprintf(\"%s: failed to get UFS resets\\n\", __func__);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tqmp->dev = dev;\n+\n+\tret = qmp_ufs_probe_dt_children(dev);\n+\tif (ret) {\n+\t\tprintf(\"%s: failed to get UFS dt regs\\n\", __func__);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct phy_ops qmp_ufs_ops = {\n+\t.power_on = qmp_ufs_power_on,\n+\t.power_off = qmp_ufs_power_off,\n+};\n+\n+static const struct udevice_id qmp_ufs_ids[] = {\n+\t{ .compatible = \"qcom,sdm845-qmp-ufs-phy\", .data = (ulong)&sdm845_ufsphy_cfg },\n+\t{ .compatible = \"qcom,sm6115-qmp-ufs-phy\", .data = (ulong)&sm6115_ufsphy_cfg },\n+\t{ .compatible = \"qcom,sm8250-qmp-ufs-phy\", .data = (ulong)&sm8250_ufsphy_cfg },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(qcom_qmp_ufs) = {\n+\t.name\t\t= \"qcom-qmp-ufs\",\n+\t.id\t\t= UCLASS_PHY,\n+\t.of_match\t= qmp_ufs_ids,\n+\t.ops\t\t= &qmp_ufs_ops,\n+\t.probe\t\t= qmp_ufs_probe,\n+\t.priv_auto\t= sizeof(struct qmp_ufs_priv),\n+};\ndiff --git a/drivers/phy/qcom/phy-qcom-qmp.h b/drivers/phy/qcom/phy-qcom-qmp.h\nnew file mode 100644\nindex 0000000000..99f4d447ca\n--- /dev/null\n+++ b/drivers/phy/qcom/phy-qcom-qmp.h\n@@ -0,0 +1,115 @@\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_H_\n+#define QCOM_PHY_QMP_H_\n+\n+#include \"phy-qcom-qmp-qserdes-com.h\"\n+#include \"phy-qcom-qmp-qserdes-txrx.h\"\n+\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-pll.h\"\n+\n+#include \"phy-qcom-qmp-pcs-v2.h\"\n+\n+#include \"phy-qcom-qmp-pcs-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+/* QSERDES V3 COM bits */\n+# define QSERDES_V3_COM_BIAS_EN\t\t\t\t0x0001\n+# define QSERDES_V3_COM_BIAS_EN_MUX\t\t\t0x0002\n+# define QSERDES_V3_COM_CLKBUF_R_EN\t\t\t0x0004\n+# define QSERDES_V3_COM_CLKBUF_L_EN\t\t\t0x0008\n+# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL\t\t0x0010\n+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L\t\t0x0020\n+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R\t\t0x0040\n+\n+/* QSERDES V3 TX bits */\n+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK\t\t0x001f\n+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN\t\t0x0020\n+# define DP_PHY_TXn_TX_DRV_LVL_MASK\t\t\t0x001f\n+# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN\t\t\t0x0020\n+\n+/* QMP PHY - DP PHY registers */\n+#define QSERDES_DP_PHY_REVISION_ID0\t\t\t0x000\n+#define QSERDES_DP_PHY_REVISION_ID1\t\t\t0x004\n+#define QSERDES_DP_PHY_REVISION_ID2\t\t\t0x008\n+#define QSERDES_DP_PHY_REVISION_ID3\t\t\t0x00c\n+#define QSERDES_DP_PHY_CFG\t\t\t\t0x010\n+#define QSERDES_DP_PHY_PD_CTL\t\t\t\t0x018\n+# define DP_PHY_PD_CTL_PWRDN\t\t\t\t0x001\n+# define DP_PHY_PD_CTL_PSR_PWRDN\t\t\t0x002\n+# define DP_PHY_PD_CTL_AUX_PWRDN\t\t\t0x004\n+# define DP_PHY_PD_CTL_LANE_0_1_PWRDN\t\t\t0x008\n+# define DP_PHY_PD_CTL_LANE_2_3_PWRDN\t\t\t0x010\n+# define DP_PHY_PD_CTL_PLL_PWRDN\t\t\t0x020\n+# define DP_PHY_PD_CTL_DP_CLAMP_EN\t\t\t0x040\n+#define QSERDES_DP_PHY_MODE\t\t\t\t0x01c\n+#define QSERDES_DP_PHY_AUX_CFG0\t\t\t\t0x020\n+#define QSERDES_DP_PHY_AUX_CFG1\t\t\t\t0x024\n+#define QSERDES_DP_PHY_AUX_CFG2\t\t\t\t0x028\n+#define QSERDES_DP_PHY_AUX_CFG3\t\t\t\t0x02c\n+#define QSERDES_DP_PHY_AUX_CFG4\t\t\t\t0x030\n+#define QSERDES_DP_PHY_AUX_CFG5\t\t\t\t0x034\n+#define QSERDES_DP_PHY_AUX_CFG6\t\t\t\t0x038\n+#define QSERDES_DP_PHY_AUX_CFG7\t\t\t\t0x03c\n+#define QSERDES_DP_PHY_AUX_CFG8\t\t\t\t0x040\n+#define QSERDES_DP_PHY_AUX_CFG9\t\t\t\t0x044\n+\n+/* Only for QMP V3 PHY - DP PHY registers */\n+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK\t\t0x048\n+# define PHY_AUX_STOP_ERR_MASK\t\t\t\t0x01\n+# define PHY_AUX_DEC_ERR_MASK\t\t\t\t0x02\n+# define PHY_AUX_SYNC_ERR_MASK\t\t\t\t0x04\n+# define PHY_AUX_ALIGN_ERR_MASK\t\t\t\t0x08\n+# define PHY_AUX_REQ_ERR_MASK\t\t\t\t0x10\n+\n+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR\t\t0x04c\n+#define QSERDES_V3_DP_PHY_AUX_BIST_CFG\t\t\t0x050\n+\n+#define QSERDES_V3_DP_PHY_VCO_DIV\t\t\t0x064\n+#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL\t\t0x06c\n+#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL\t\t0x088\n+\n+#define QSERDES_V3_DP_PHY_SPARE0\t\t\t0x0ac\n+#define DP_PHY_SPARE0_MASK\t\t\t\t0x0f\n+#define DP_PHY_SPARE0_ORIENTATION_INFO_SHIFT\t\t0x04(0x0004)\n+\n+#define QSERDES_V3_DP_PHY_STATUS\t\t\t0x0c0\n+\n+/* Only for QMP V4 PHY - DP PHY registers */\n+#define QSERDES_V4_DP_PHY_CFG_1\t\t\t\t0x014\n+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK\t\t0x054\n+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR\t\t0x058\n+#define QSERDES_V4_DP_PHY_VCO_DIV\t\t\t0x070\n+#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL\t\t0x078\n+#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL\t\t0x09c\n+#define QSERDES_V4_DP_PHY_SPARE0\t\t\t0x0c8\n+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS\t\t0x0d8\n+#define QSERDES_V4_DP_PHY_STATUS\t\t\t0x0dc\n+\n+/* Only for QMP V4 PHY - PCS_MISC registers */\n+#define QPHY_V4_PCS_MISC_TYPEC_CTRL\t\t\t0x00\n+#define QPHY_V4_PCS_MISC_TYPEC_PWRDN_CTRL\t\t0x04\n+#define QPHY_V4_PCS_MISC_PCS_MISC_CONFIG1\t\t0x08\n+#define QPHY_V4_PCS_MISC_CLAMP_ENABLE\t\t\t0x0c\n+#define QPHY_V4_PCS_MISC_TYPEC_STATUS\t\t\t0x10\n+#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS\t\t0x14\n+\n+/* Only for QMP V6 PHY - DP PHY registers */\n+#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS\t\t0x0e0\n+#define QSERDES_V6_DP_PHY_STATUS\t\t\t0x0e4\n+\n+#endif\n",
    "prefixes": [
        "04/17"
    ]
}