summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/qcom_defconfig2
-rw-r--r--drivers/clk/qcom/Kconfig9
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clock-qcom.c119
-rw-r--r--drivers/clk/qcom/clock-qcom.h6
-rw-r--r--drivers/clk/qcom/clock-sdm845.c93
-rw-r--r--drivers/clk/qcom/clock-sm6115.c63
-rw-r--r--drivers/clk/qcom/clock-sm8150.c319
-rw-r--r--drivers/clk/qcom/clock-sm8250.c115
-rw-r--r--drivers/gpio/msm_gpio.c97
-rw-r--r--drivers/gpio/qcom_pmic_gpio.c27
-rw-r--r--drivers/phy/qcom/Kconfig6
-rw-r--r--drivers/phy/qcom/Makefile1
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v2.h25
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v3.h21
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v4.h31
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v5.h32
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v6.h38
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-v2.h43
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-v3.h145
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-pcs-v4.h135
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v3.h111
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v4.h123
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v6.h89
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-com.h140
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-pll.h69
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-ufs-v6.h52
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v3.h68
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v4.h233
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx.h205
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-ufs.c1116
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp.h115
-rw-r--r--drivers/pinctrl/qcom/Kconfig8
-rw-r--r--drivers/pinctrl/qcom/Makefile1
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8150.c156
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm8250.c42
36 files changed, 3822 insertions, 34 deletions
diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index 2a2253f766d..e7ed03ff0f2 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -48,6 +48,7 @@ CONFIG_CLK_QCOM_QCS404=y
CONFIG_CLK_QCOM_SC7280=y
CONFIG_CLK_QCOM_SDM845=y
CONFIG_CLK_QCOM_SM6115=y
+CONFIG_CLK_QCOM_SM8150=y
CONFIG_CLK_QCOM_SM8250=y
CONFIG_CLK_QCOM_SM8550=y
CONFIG_CLK_QCOM_SM8650=y
@@ -86,6 +87,7 @@ CONFIG_PINCTRL_QCOM_QCM2290=y
CONFIG_PINCTRL_QCOM_QCS404=y
CONFIG_PINCTRL_QCOM_SDM845=y
CONFIG_PINCTRL_QCOM_SM6115=y
+CONFIG_PINCTRL_QCOM_SM8150=y
CONFIG_PINCTRL_QCOM_SM8250=y
CONFIG_PINCTRL_QCOM_SM8550=y
CONFIG_PINCTRL_QCOM_SM8650=y
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0d2c0ac225c..d76fca5dba4 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -63,12 +63,21 @@ config CLK_QCOM_SM6115
on the Snapdragon SM6115 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_SM8150
+ bool "Qualcomm SM8150 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon 8150 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_SM8250
bool "Qualcomm SM8250 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon SM8250 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
config CLK_QCOM_SM8550
bool "Qualcomm SM8550 GCC"
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index e223c131ee4..ab33f1c5faf 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
obj-$(CONFIG_CLK_QCOM_SC7280) += clock-sc7280.o
obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
+obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
obj-$(CONFIG_CLK_QCOM_SM8250) += clock-sm8250.o
obj-$(CONFIG_CLK_QCOM_SM8550) += clock-sm8550.o
obj-$(CONFIG_CLK_QCOM_SM8650) += clock-sm8650.o
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 79c7606a225..25ca67e537d 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -13,6 +13,7 @@
*/
#include <clk-uclass.h>
+#include <linux/clk-provider.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
@@ -215,9 +216,127 @@ static int msm_clk_enable(struct clk *clk)
return 0;
}
+static void dump_gplls(struct udevice *dev, phys_addr_t base)
+{
+ struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
+ u32 i;
+ bool locked;
+ u64 l, a, xo_rate = 19200000;
+ struct clk *clk = NULL;
+ struct udevice *xodev;
+ const phys_addr_t *gplls = data->dbg_pll_addrs;
+
+ uclass_foreach_dev_probe(UCLASS_CLK, xodev) {
+ if (!strcmp(xodev->name, "xo-board") || !strcmp(xodev->name, "xo_board")) {
+ clk = dev_get_clk_ptr(xodev);
+ break;
+ }
+ }
+
+ if (clk) {
+ xo_rate = clk_get_rate(clk);
+
+ /* On SDM845 this needs to be divided by 2 for some reason */
+ if (xo_rate && of_machine_is_compatible("qcom,sdm845"))
+ xo_rate /= 2;
+ } else {
+ printf("Can't find XO clock, XO_BOARD rate may be wrong\n");
+ }
+
+ printf("GPLL clocks:\n");
+ printf("| GPLL | LOCKED | XO_BOARD | PLL_L | ALPHA |\n");
+ printf("+--------+--------+-----------+------------+----------------+\n");
+ for (i = 0; i < data->num_plls; i++) {
+ locked = !!(readl(gplls[i]) & BIT(31));
+ l = readl(gplls[i] + 4) & (BIT(16) - 1);
+ a = readq(gplls[i] + 40) & (BIT(16) - 1);
+ printf("| GPLL%-2d | %-6s | %9llu * (%#-9llx + %#-13llx * 2 ** -40 ) / 1000000\n",
+ i, locked ? "X" : "", xo_rate, l, a);
+ }
+}
+
+static void dump_rcgs(struct udevice *dev)
+{
+ struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
+ int i;
+ u32 cmd;
+ u32 cfg;
+ u32 not_n_minus_m;
+ u32 src, m, n, div;
+ bool root_on, d_odd;
+
+ printf("\nRCGs:\n");
+
+ /*
+ * Which GPLL SRC corresponds to depends on the parent map, see gcc-<soc>.c in Linux
+ * and find the parent map associated with the clock. Note that often there are multiple
+ * outputs from a single GPLL where one is actually half the rate of the other (_EVEN).
+ * intput_freq = associated GPLL output freq (potentially divided depending on SRC).
+ */
+ printf("| NAME | ON | SRC | OUT_FREQ = input_freq * (m/n) * (1/d) | [CMD REG ] |\n");
+ printf("+----------------------------------+----+-----+---------------------------------------+--------------+\n");
+ for (i = 0; i < data->num_rcgs; i++) {
+ cmd = readl(data->dbg_rcg_addrs[i]);
+ cfg = readl(data->dbg_rcg_addrs[i] + 0x4);
+ m = readl(data->dbg_rcg_addrs[i] + 0x8);
+ n = 0;
+ not_n_minus_m = readl(data->dbg_rcg_addrs[i] + 0xc);
+
+ root_on = !(cmd & BIT(31)); // ROOT_OFF
+ src = (cfg >> 8) & 7;
+
+ if (not_n_minus_m) {
+ n = (~not_n_minus_m & 0xffff);
+
+ /* A clumsy assumption that this is an 8-bit MND RCG */
+ if ((n & 0xff00) == 0xff00)
+ n = n & 0xff;
+
+ n += m;
+ }
+
+ div = ((cfg & 0b11111) + 1) / 2;
+ d_odd = ((cfg & 0b11111) + 1) % 2 == 1;
+ printf("%-34s | %-2s | %3d | input_freq * (%4d/%5d) * (1/%1d%-2s) | [%#010x]\n",
+ data->dbg_rcg_names[i], root_on ? "X" : "", src,
+ m ?: 1, n ?: 1, div, d_odd ? ".5" : "", cmd);
+ }
+
+ printf("\n");
+}
+
+static void __maybe_unused msm_dump_clks(struct udevice *dev)
+{
+ struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
+ struct msm_clk_priv *priv = dev_get_priv(dev);
+ const struct gate_clk *sclk;
+ int val, i;
+
+ if (!data->clks) {
+ printf("No clocks\n");
+ return;
+ }
+
+ printf("Gate Clocks:\n");
+ for (i = 0; i < data->num_clks; i++) {
+ sclk = &data->clks[i];
+ if (!sclk->name)
+ continue;
+ printf("%-32s: ", sclk->name);
+ val = readl(priv->base + sclk->reg) & sclk->en_val;
+ printf("%s\n", val ? "ON" : "");
+ }
+
+ dump_gplls(dev, priv->base);
+ dump_rcgs(dev);
+}
+
static struct clk_ops msm_clk_ops = {
.set_rate = msm_clk_set_rate,
.enable = msm_clk_enable,
+#if IS_ENABLED(CONFIG_CMD_CLK)
+ .dump = msm_dump_clks,
+#endif
};
U_BOOT_DRIVER(qcom_clk) = {
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 7aa6ca59aad..78d9b1d81ec 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -77,6 +77,12 @@ struct msm_clk_data {
const struct gate_clk *clks;
unsigned long num_clks;
+ const phys_addr_t *dbg_pll_addrs;
+ unsigned long num_plls;
+ const phys_addr_t *dbg_rcg_addrs;
+ unsigned long num_rcgs;
+ const char * const *dbg_rcg_names;
+
int (*enable)(struct clk *clk);
unsigned long (*set_rate)(struct clk *clk, unsigned long rate);
};
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index f41f8c9e8de..adffb0cb240 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -203,6 +203,94 @@ static const struct qcom_power_map sdm845_gdscs[] = {
[HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = { 0x7d044 },
};
+static const phys_addr_t sdm845_gpll_addrs[] = {
+ 0x00100000, // GCC_GPLL0_MODE
+ 0x00101000, // GCC_GPLL1_MODE
+ 0x00102000, // GCC_GPLL2_MODE
+ 0x00103000, // GCC_GPLL3_MODE
+ 0x00176000, // GCC_GPLL4_MODE
+ 0x00174000, // GCC_GPLL5_MODE
+ 0x00113000, // GCC_GPLL6_MODE
+};
+
+static const phys_addr_t sdm845_rcg_addrs[] = {
+ 0x0010f018, // GCC_USB30_PRIM_MASTER
+ 0x0010f030, // GCC_USB30_PRIM_MOCK_UTMI
+ 0x0010f05c, // GCC_USB3_PRIM_PHY_AUX
+ 0x00110018, // GCC_USB30_SEC_MASTER
+ 0x00110030, // GCC_USB30_SEC_MOCK_UTMI
+ 0x0011005c, // GCC_USB3_SEC_PHY_AUX
+ 0x0011400c, // GCC_SDCC2_APPS
+ 0x0011600c, // GCC_SDCC4_APPS
+ 0x00117018, // GCC_QUPV3_WRAP0_CORE_2X
+ 0x00117034, // GCC_QUPV3_WRAP0_S0
+ 0x00117164, // GCC_QUPV3_WRAP0_S1
+ 0x00117294, // GCC_QUPV3_WRAP0_S2
+ 0x001173c4, // GCC_QUPV3_WRAP0_S3
+ 0x001174f4, // GCC_QUPV3_WRAP0_S4
+ 0x00117624, // GCC_QUPV3_WRAP0_S5
+ 0x00117754, // GCC_QUPV3_WRAP0_S6
+ 0x00117884, // GCC_QUPV3_WRAP0_S7
+ 0x00118018, // GCC_QUPV3_WRAP1_S0
+ 0x00118148, // GCC_QUPV3_WRAP1_S1
+ 0x00118278, // GCC_QUPV3_WRAP1_S2
+ 0x001183a8, // GCC_QUPV3_WRAP1_S3
+ 0x001184d8, // GCC_QUPV3_WRAP1_S4
+ 0x00118608, // GCC_QUPV3_WRAP1_S5
+ 0x00118738, // GCC_QUPV3_WRAP1_S6
+ 0x00118868, // GCC_QUPV3_WRAP1_S7
+ 0x0016b028, // GCC_PCIE_0_AUX
+ 0x0018d028, // GCC_PCIE_1_AUX
+ 0x0016f014, // GCC_PCIE_PHY_REFGEN
+ 0x0017501c, // GCC_UFS_CARD_AXI
+ 0x0017505c, // GCC_UFS_CARD_ICE_CORE
+ 0x00175074, // GCC_UFS_CARD_UNIPRO_CORE
+ 0x00175090, // GCC_UFS_CARD_PHY_AUX
+ 0x0017701c, // GCC_UFS_PHY_AXI
+ 0x0017705c, // GCC_UFS_PHY_ICE_CORE
+ 0x00177074, // GCC_UFS_PHY_UNIPRO_CORE
+ 0x00177090, // GCC_UFS_PHY_PHY_AUX
+};
+
+static const char *const sdm845_rcg_names[] = {
+ "GCC_USB30_PRIM_MASTER",
+ "GCC_USB30_PRIM_MOCK_UTMI",
+ "GCC_USB3_PRIM_PHY_AUX",
+ "GCC_USB30_SEC_MASTER",
+ "GCC_USB30_SEC_MOCK_UTMI",
+ "GCC_USB3_SEC_PHY_AUX",
+ "GCC_SDCC2_APPS",
+ "GCC_SDCC4_APPS",
+ "GCC_QUPV3_WRAP0_CORE_2X",
+ "GCC_QUPV3_WRAP0_S0",
+ "GCC_QUPV3_WRAP0_S1",
+ "GCC_QUPV3_WRAP0_S2",
+ "GCC_QUPV3_WRAP0_S3",
+ "GCC_QUPV3_WRAP0_S4",
+ "GCC_QUPV3_WRAP0_S5",
+ "GCC_QUPV3_WRAP0_S6",
+ "GCC_QUPV3_WRAP0_S7",
+ "GCC_QUPV3_WRAP1_S0",
+ "GCC_QUPV3_WRAP1_S1",
+ "GCC_QUPV3_WRAP1_S2",
+ "GCC_QUPV3_WRAP1_S3",
+ "GCC_QUPV3_WRAP1_S4",
+ "GCC_QUPV3_WRAP1_S5",
+ "GCC_QUPV3_WRAP1_S6",
+ "GCC_QUPV3_WRAP1_S7",
+ "GCC_PCIE_0_AUX",
+ "GCC_PCIE_1_AUX",
+ "GCC_PCIE_PHY_REFGEN",
+ "GCC_UFS_CARD_AXI",
+ "GCC_UFS_CARD_ICE_CORE",
+ "GCC_UFS_CARD_UNIPRO_CORE",
+ "GCC_UFS_CARD_PHY_AUX",
+ "GCC_UFS_PHY_AXI",
+ "GCC_UFS_PHY_ICE_CORE",
+ "GCC_UFS_PHY_UNIPRO_CORE",
+ "GCC_UFS_PHY_PHY_AUX",
+};
+
static struct msm_clk_data sdm845_clk_data = {
.resets = sdm845_gcc_resets,
.num_resets = ARRAY_SIZE(sdm845_gcc_resets),
@@ -213,6 +301,11 @@ static struct msm_clk_data sdm845_clk_data = {
.enable = sdm845_clk_enable,
.set_rate = sdm845_clk_set_rate,
+ .dbg_pll_addrs = sdm845_gpll_addrs,
+ .num_plls = ARRAY_SIZE(sdm845_gpll_addrs),
+ .dbg_rcg_addrs = sdm845_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sdm845_rcg_addrs),
+ .dbg_rcg_names = sdm845_rcg_names,
};
static const struct udevice_id gcc_sdm845_of_match[] = {
diff --git a/drivers/clk/qcom/clock-sm6115.c b/drivers/clk/qcom/clock-sm6115.c
index 8314a0deb34..9057dfe0bb1 100644
--- a/drivers/clk/qcom/clock-sm6115.c
+++ b/drivers/clk/qcom/clock-sm6115.c
@@ -170,6 +170,63 @@ static const struct qcom_power_map sm6115_gdscs[] = {
[GCC_USB30_PRIM_GDSC] = { 0x1a004 },
};
+static const phys_addr_t sm6115_gpll_addrs[] = {
+ 0x01400000, // GCC_GPLL0_MODE
+ 0x01401000, // GCC_GPLL1_MODE
+ 0x01402000, // GCC_GPLL2_MODE
+ 0x01403000, // GCC_GPLL3_MODE
+ 0x01404000, // GCC_GPLL4_MODE
+ 0x01405000, // GCC_GPLL5_MODE
+ 0x01406000, // GCC_GPLL6_MODE
+ 0x01407000, // GCC_GPLL7_MODE
+ 0x01408000, // GCC_GPLL8_MODE
+ 0x01409000, // GCC_GPLL9_MODE
+ 0x0140a000, // GCC_GPLL10_MODE
+ 0x0140b000, // GCC_GPLL11_MODE
+};
+
+static const phys_addr_t sm6115_rcg_addrs[] = {
+ 0x0141a01c, // GCC_USB30_PRIM_MASTER_CMD_RCGR
+ 0x0141a034, // GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR
+ 0x0141a060, // GCC_USB3_PRIM_PHY_AUX_CMD_RCGR
+ 0x01438028, // GCC_SDCC1_APPS_CMD_RCGR
+ 0x0141e00c, // GCC_SDCC2_APPS_CMD_RCGR
+ 0x0141f018, // GCC_QUPV3_WRAP0_CORE_2X_CMD_RCGR
+ 0x0141f148, // GCC_QUPV3_WRAP0_S0_CMD_RCGR
+ 0x0141f278, // GCC_QUPV3_WRAP0_S1_CMD_RCGR
+ 0x0141f3a8, // GCC_QUPV3_WRAP0_S2_CMD_RCGR
+ 0x0141f4d8, // GCC_QUPV3_WRAP0_S3_CMD_RCGR
+ 0x0141f608, // GCC_QUPV3_WRAP0_S4_CMD_RCGR
+ 0x0141f738, // GCC_QUPV3_WRAP0_S5_CMD_RCGR
+ 0x01428014, // GCC_SLEEP_CMD_RCGR
+ 0x0142802c, // GCC_XO_CMD_RCGR
+ 0x01445020, // GCC_UFS_PHY_AXI_CMD_RCGR
+ 0x01445048, // GCC_UFS_PHY_ICE_CORE_CMD_RCGR
+ 0x01445060, // GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR
+ 0x0144507c, // GCC_UFS_PHY_PHY_AUX_CMD_RCGR
+};
+
+static const char *const sm6115_rcg_names[] = {
+ "GCC_USB30_PRIM_MASTER_CMD_RCGR",
+ "GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR",
+ "GCC_USB3_PRIM_PHY_AUX_CMD_RCGR",
+ "GCC_SDCC1_APPS_CMD_RCGR",
+ "GCC_SDCC2_APPS_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_CORE_2X_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S5_CMD_RCGR",
+ "GCC_SLEEP_CMD_RCGR",
+ "GCC_XO_CMD_RCGR",
+ "GCC_UFS_PHY_AXI_CMD_RCGR",
+ "GCC_UFS_PHY_ICE_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_PHY_AUX_CMD_RCGR",
+};
+
static struct msm_clk_data sm6115_gcc_data = {
.resets = sm6115_gcc_resets,
.num_resets = ARRAY_SIZE(sm6115_gcc_resets),
@@ -180,6 +237,12 @@ static struct msm_clk_data sm6115_gcc_data = {
.enable = sm6115_enable,
.set_rate = sm6115_set_rate,
+
+ .dbg_pll_addrs = sm6115_gpll_addrs,
+ .num_plls = ARRAY_SIZE(sm6115_gpll_addrs),
+ .dbg_rcg_addrs = sm6115_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sm6115_rcg_addrs),
+ .dbg_rcg_names = sm6115_rcg_names,
};
static const struct udevice_id gcc_sm6115_of_match[] = {
diff --git a/drivers/clk/qcom/clock-sm8150.c b/drivers/clk/qcom/clock-sm8150.c
new file mode 100644
index 00000000000..88f2e678f43
--- /dev/null
+++ b/drivers/clk/qcom/clock-sm8150.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SM8150
+ *
+ * Volodymyr Babchuk <volodymyr_babchuk@epam.com>
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * (C) Copyright 2024 Julius Lehmann <lehmanju@devpi.de>
+ *
+ * Based on U-Boot driver for SM8250. Constants are taken from the Linux driver.
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <dt-bindings/clock/qcom,gcc-sm8150.h>
+
+#include "clock-qcom.h"
+
+#define EMAC_RGMII_CLK_CMD_RCGR 0x601c
+#define QUPV3_WRAP0_S0_CLK_CMD_RCGR 0x18148
+#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf034
+#define USB30_PRIM_PHY_AUX_CLK_CMD_RCGR 0xf060
+#define USB30_SEC_MASTER_CLK_CMD_RCGR 0x1001c
+#define USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR 0x10034
+#define USB30_SEC_PHY_AUX_CLK_CMD_RCGR 0x10060
+#define SDCC2_APPS_CLK_CMD_RCGR 0x1400c
+
+static struct pll_vote_clk gpll7_vote_clk = {
+ .status = 0x1a000,
+ .status_bit = BIT(31),
+ .ena_vote = 0x52000,
+ .vote_bit = BIT(7),
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+ F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+ F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+ F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+ F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+ F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+ F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+ F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+ F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+ F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+ F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+ F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+ F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+ F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = {
+ F(2500000, CFG_CLK_SRC_CXO, 1, 25, 192),
+ F(5000000, CFG_CLK_SRC_CXO, 1, 25, 96),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+ F(125000000, CFG_CLK_SRC_GPLL7, 4, 0, 0),
+ F(250000000, CFG_CLK_SRC_GPLL7, 2, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+ F(33333333, CFG_CLK_SRC_GPLL0_EVEN, 9, 0, 0),
+ F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
+ F(133333333, CFG_CLK_SRC_GPLL0, 4.5, 0, 0),
+ F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
+ F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(20000000, CFG_CLK_SRC_GPLL0_EVEN, 15, 0, 0),
+ F(60000000, CFG_CLK_SRC_GPLL0_EVEN, 5, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+ F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
+ F(9600000, CFG_CLK_SRC_CXO, 2, 0, 0),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(25000000, CFG_CLK_SRC_GPLL0, 12, 1, 2),
+ F(50000000, CFG_CLK_SRC_GPLL0, 12, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(202000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ { }
+};
+
+static ulong sm8150_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
+
+ switch (clk->id) {
+ case GCC_QUPV3_WRAP1_S4_CLK: /* UART2 aka debug-uart */
+ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, QUPV3_WRAP0_S0_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 16);
+ return freq->freq;
+ case GCC_EMAC_RGMII_CLK:
+ freq = qcom_find_freq(ftbl_gcc_emac_rgmii_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, EMAC_RGMII_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_USB30_PRIM_MOCK_UTMI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_mock_utmi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 0);
+ return freq->freq;
+ case GCC_USB3_PRIM_PHY_AUX_CLK_SRC:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_mock_utmi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_PHY_AUX_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 0);
+ return freq->freq;
+ case GCC_USB30_SEC_MASTER_CLK:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_SEC_MASTER_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_USB30_SEC_MOCK_UTMI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_mock_utmi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_SEC_MOCK_UTMI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 0);
+ return freq->freq;
+ case GCC_USB3_SEC_PHY_AUX_CLK_SRC:
+ freq = qcom_find_freq(ftbl_gcc_usb30_prim_mock_utmi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, USB30_SEC_PHY_AUX_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 0);
+ return freq->freq;
+ case GCC_SDCC2_APPS_CLK:
+ freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ default:
+ return 0;
+ }
+}
+
+static const struct gate_clk sm8150_clks[] = {
+ GATE_CLK(GCC_AGGRE_UFS_CARD_AXI_CLK, 0x750c0, 0x00000001),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770c0, 0x00000001),
+ GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0xf07c, 0x00000001),
+ GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x1007c, 0x00000001),
+ GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0xf078, 0x00000001),
+ GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x10078, 0x00000001),
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, 0x00001000),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, 0x00002000),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, 0x00004000),
+ GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, 0x00008000),
+ GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, 0x00400000),
+ GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, 0x00800000),
+ GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, 0x02000000),
+ GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, 0x04000000),
+ GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, 0x08000000),
+ GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x5200c, 0x00000040),
+ GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x5200c, 0x00000080),
+ GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x5200c, 0x00100000),
+ GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x5200c, 0x00200000),
+ GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, 0x00000001),
+ GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, 0x00000001),
+ GATE_CLK(GCC_SDCC4_AHB_CLK, 0x16008, 0x00000001),
+ GATE_CLK(GCC_SDCC4_APPS_CLK, 0x16004, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_AHB_CLK, 0x75014, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_AXI_CLK, 0x75010, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_CLKREF_CLK, 0x8c004, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK, 0x7505c, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK, 0x75090, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK, 0x7501c, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK, 0x750ac, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75018, 0x00000001),
+ GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75058, 0x00000001),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77014, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x7705c, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x77090, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7701c, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770ac, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77018, 0x00000001),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77058, 0x00000001),
+ GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x0f00c, 0x00000001),
+ GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x0f014, 0x00000001),
+ GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x0f010, 0x00000001),
+ GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x1000c, 0x00000001),
+ GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x10014, 0x00000001),
+ GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x10010, 0x00000001),
+ GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x8c008, 0x00000001),
+ GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x0f04c, 0x00000001),
+ GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x0f050, 0x00000001),
+ GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x0f054, 0x00000001),
+ GATE_CLK(GCC_USB3_SEC_CLKREF_CLK, 0x8c028, 0x00000001),
+ GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x1004c, 0x00000001),
+ GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK, 0x10054, 0x00000001),
+ GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x10050, 0x00000001),
+ GATE_CLK(GCC_EMAC_AXI_CLK, 0x06010, 0x00000001),
+ GATE_CLK(GCC_EMAC_SLV_AHB_CLK, 0x06014, 0x00000001),
+ GATE_CLK(GCC_EMAC_PTP_CLK, 0x06034, 0x00000001),
+ GATE_CLK(GCC_EMAC_RGMII_CLK, 0x06018, 0x00000001),
+};
+
+static int sm8150_clk_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (priv->data->num_clks <= clk->id) {
+ debug("%s: unknown clk id %lu\n", __func__, clk->id);
+ return 0;
+ }
+
+ debug("%s: clk %s\n", __func__, sm8150_clks[clk->id].name);
+
+ switch (clk->id) {
+ case GCC_EMAC_RGMII_CLK:
+ clk_enable_gpll0(priv->base, &gpll7_vote_clk);
+ case GCC_AGGRE_USB3_PRIM_AXI_CLK:
+ qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
+ fallthrough;
+ case GCC_USB30_PRIM_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
+ break;
+ case GCC_AGGRE_USB3_SEC_AXI_CLK:
+ qcom_gate_clk_en(priv, GCC_USB30_SEC_MASTER_CLK);
+ fallthrough;
+ case GCC_USB30_SEC_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
+ break;
+ };
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static const struct qcom_reset_map sm8150_gcc_resets[] = {
+ [GCC_EMAC_BCR] = { 0x6000 },
+ [GCC_GPU_BCR] = { 0x71000 },
+ [GCC_MMSS_BCR] = { 0xb000 },
+ [GCC_NPU_BCR] = { 0x4d000 },
+ [GCC_PCIE_0_BCR] = { 0x6b000 },
+ [GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
+ [GCC_PCIE_1_BCR] = { 0x8d000 },
+ [GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
+ [GCC_PCIE_PHY_BCR] = { 0x6f000 },
+ [GCC_PDM_BCR] = { 0x33000 },
+ [GCC_PRNG_BCR] = { 0x34000 },
+ [GCC_QSPI_BCR] = { 0x24008 },
+ [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
+ [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
+ [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
+ [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
+ [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
+ [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
+ [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
+ [GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
+ [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
+ [GCC_SDCC2_BCR] = { 0x14000 },
+ [GCC_SDCC4_BCR] = { 0x16000 },
+ [GCC_TSIF_BCR] = { 0x36000 },
+ [GCC_UFS_CARD_BCR] = { 0x75000 },
+ [GCC_UFS_PHY_BCR] = { 0x77000 },
+ [GCC_USB30_PRIM_BCR] = { 0xf000 },
+ [GCC_USB30_SEC_BCR] = { 0x10000 },
+ [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
+};
+
+static const struct qcom_power_map sm8150_gcc_power_domains[] = {
+ [EMAC_GDSC] = { 0x6004 },
+ [PCIE_0_GDSC] = { 0x6b004 },
+ [PCIE_1_GDSC] = { 0x8d004 },
+ [UFS_CARD_GDSC] = { 0x75004 },
+ [UFS_PHY_GDSC] = { 0x77004 },
+ [USB30_PRIM_GDSC] = { 0xf004 },
+ [USB30_SEC_GDSC] = { 0x10004 },
+};
+
+static struct msm_clk_data sm8150_clk_data = {
+ .resets = sm8150_gcc_resets,
+ .num_resets = ARRAY_SIZE(sm8150_gcc_resets),
+ .clks = sm8150_clks,
+ .num_clks = ARRAY_SIZE(sm8150_clks),
+ .power_domains = sm8150_gcc_power_domains,
+ .num_power_domains = ARRAY_SIZE(sm8150_gcc_power_domains),
+
+ .enable = sm8150_clk_enable,
+ .set_rate = sm8150_clk_set_rate,
+};
+
+static const struct udevice_id gcc_sm8150_of_match[] = {
+ {
+ .compatible = "qcom,gcc-sm8150",
+ .data = (ulong)&sm8150_clk_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(gcc_sm8150) = {
+ .name = "gcc_sm8150",
+ .id = UCLASS_NOP,
+ .of_match = gcc_sm8150_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/qcom/clock-sm8250.c b/drivers/clk/qcom/clock-sm8250.c
index af10fc11621..e322a923a5c 100644
--- a/drivers/clk/qcom/clock-sm8250.c
+++ b/drivers/clk/qcom/clock-sm8250.c
@@ -253,6 +253,115 @@ static const struct qcom_power_map sm8250_gdscs[] = {
[USB30_SEC_GDSC] = { 0x10004 },
};
+static const phys_addr_t sm8250_gpll_addrs[] = {
+ 0x00100000, // GCC_GPLL0_MODE
+ 0x00101000, // GCC_GPLL1_MODE
+ 0x00102000, // GCC_GPLL2_MODE
+ 0x00103000, // GCC_GPLL3_MODE
+ 0x00176000, // GCC_GPLL4_MODE
+ 0x00174000, // GCC_GPLL5_MODE
+ 0x00113000, // GCC_GPLL6_MODE
+ 0x0011a000, // GCC_GPLL7_MODE
+ 0x0011b000, // GCC_GPLL8_MODE
+ 0x0011c000, // GCC_GPLL9_MODE
+ 0x0011d000, // GCC_GPLL10_MODE
+ 0x0014a000, // GCC_GPLL11_MODE
+};
+
+static const phys_addr_t sm8250_rcg_addrs[] = {
+ 0x0010f020, // GCC_USB30_PRIM_MASTER_CMD_RCGR
+ 0x0010f038, // GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR
+ 0x0010f064, // GCC_USB3_PRIM_PHY_AUX_CMD_RCGR
+ 0x00110020, // GCC_USB30_SEC_MASTER_CMD_RCGR
+ 0x00110038, // GCC_USB30_SEC_MOCK_UTMI_CMD_RCGR
+ 0x00110064, // GCC_USB3_SEC_PHY_AUX_CMD_RCGR
+ 0x0011400c, // GCC_SDCC2_APPS_CMD_RCGR
+ 0x0011600c, // GCC_SDCC4_APPS_CMD_RCGR
+ 0x0012300c, // GCC_QUPV3_WRAP0_CORE_2X_CMD_RCGR
+ 0x00117010, // GCC_QUPV3_WRAP0_S0_CMD_RCGR
+ 0x00117140, // GCC_QUPV3_WRAP0_S1_CMD_RCGR
+ 0x00117270, // GCC_QUPV3_WRAP0_S2_CMD_RCGR
+ 0x001173a0, // GCC_QUPV3_WRAP0_S3_CMD_RCGR
+ 0x001174d0, // GCC_QUPV3_WRAP0_S4_CMD_RCGR
+ 0x00117600, // GCC_QUPV3_WRAP0_S5_CMD_RCGR
+ 0x00117730, // GCC_QUPV3_WRAP0_S6_CMD_RCGR
+ 0x00117860, // GCC_QUPV3_WRAP0_S7_CMD_RCGR
+ 0x00123144, // GCC_QUPV3_WRAP1_CORE_2X_CMD_RCGR
+ 0x00118010, // GCC_QUPV3_WRAP1_S0_CMD_RCGR
+ 0x00118140, // GCC_QUPV3_WRAP1_S1_CMD_RCGR
+ 0x00118270, // GCC_QUPV3_WRAP1_S2_CMD_RCGR
+ 0x001183a0, // GCC_QUPV3_WRAP1_S3_CMD_RCGR
+ 0x001184d0, // GCC_QUPV3_WRAP1_S4_CMD_RCGR
+ 0x00118600, // GCC_QUPV3_WRAP1_S5_CMD_RCGR
+ 0x0016b038, // GCC_PCIE_0_AUX_CMD_RCGR
+ 0x0018d038, // GCC_PCIE_1_AUX_CMD_RCGR
+ 0x0016f014, // GCC_PCIE_PHY_REFGEN_CMD_RCGR
+ 0x00175024, // GCC_UFS_CARD_AXI_CMD_RCGR
+ 0x0017506c, // GCC_UFS_CARD_ICE_CORE_CMD_RCGR
+ 0x00175084, // GCC_UFS_CARD_UNIPRO_CORE_CMD_RCGR
+ 0x001750a0, // GCC_UFS_CARD_PHY_AUX_CMD_RCGR
+ 0x00177024, // GCC_UFS_PHY_AXI_CMD_RCGR
+ 0x0017706c, // GCC_UFS_PHY_ICE_CORE_CMD_RCGR
+ 0x00177084, // GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR
+ 0x001770a0, // GCC_UFS_PHY_PHY_AUX_CMD_RCGR
+ 0x0012327c, // GCC_QUPV3_WRAP2_CORE_2X_CMD_RCGR
+ 0x0011e010, // GCC_QUPV3_WRAP2_S0_CMD_RCGR
+ 0x0011e140, // GCC_QUPV3_WRAP2_S1_CMD_RCGR
+ 0x0011e270, // GCC_QUPV3_WRAP2_S2_CMD_RCGR
+ 0x0011e3a0, // GCC_QUPV3_WRAP2_S3_CMD_RCGR
+ 0x0011e4d0, // GCC_QUPV3_WRAP2_S4_CMD_RCGR
+ 0x0011e600, // GCC_QUPV3_WRAP2_S5_CMD_RCGR
+ 0x0010d00c, // GCC_RBCPR_MMCX_CMD_RCGR
+ 0x00106038, // GCC_PCIE_2_AUX_CMD_RCGR
+};
+
+static const char *const sm8250_rcg_names[] = {
+ "GCC_USB30_PRIM_MASTER_CMD_RCGR",
+ "GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR",
+ "GCC_USB3_PRIM_PHY_AUX_CMD_RCGR",
+ "GCC_USB30_SEC_MASTER_CMD_RCGR",
+ "GCC_USB30_SEC_MOCK_UTMI_CMD_RCGR",
+ "GCC_USB3_SEC_PHY_AUX_CMD_RCGR",
+ "GCC_SDCC2_APPS_CMD_RCGR",
+ "GCC_SDCC4_APPS_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_CORE_2X_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S5_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S6_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S7_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_CORE_2X_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP1_S5_CMD_RCGR",
+ "GCC_PCIE_0_AUX_CMD_RCGR",
+ "GCC_PCIE_1_AUX_CMD_RCGR",
+ "GCC_PCIE_PHY_REFGEN_CMD_RCGR",
+ "GCC_UFS_CARD_AXI_CMD_RCGR",
+ "GCC_UFS_CARD_ICE_CORE_CMD_RCGR",
+ "GCC_UFS_CARD_UNIPRO_CORE_CMD_RCGR",
+ "GCC_UFS_CARD_PHY_AUX_CMD_RCGR",
+ "GCC_UFS_PHY_AXI_CMD_RCGR",
+ "GCC_UFS_PHY_ICE_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_PHY_AUX_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_CORE_2X_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP2_S5_CMD_RCGR",
+ "GCC_RBCPR_MMCX_CMD_RCGR",
+ "GCC_PCIE_2_AUX_CMD_RCGR",
+};
+
static struct msm_clk_data qcs404_gcc_data = {
.resets = sm8250_gcc_resets,
.num_resets = ARRAY_SIZE(sm8250_gcc_resets),
@@ -263,6 +372,12 @@ static struct msm_clk_data qcs404_gcc_data = {
.enable = sm8250_enable,
.set_rate = sm8250_set_rate,
+
+ .dbg_pll_addrs = sm8250_gpll_addrs,
+ .num_plls = ARRAY_SIZE(sm8250_gpll_addrs),
+ .dbg_rcg_addrs = sm8250_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sm8250_rcg_addrs),
+ .dbg_rcg_names = sm8250_rcg_names,
};
static const struct udevice_id gcc_sm8250_of_match[] = {
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 2fb266f1285..cea073b3297 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -34,13 +34,31 @@ struct msm_gpio_bank {
#define GPIO_IN_OUT_REG(dev, x) \
(GPIO_CONFIG_REG(dev, x) + 0x4)
+static void msm_gpio_direction_input_special(struct msm_gpio_bank *priv,
+ unsigned int gpio)
+{
+ unsigned int offset = gpio - priv->pin_data->special_pins_start;
+ const struct msm_special_pin_data *data;
+
+ if (!priv->pin_data->special_pins_data)
+ return;
+
+ data = &priv->pin_data->special_pins_data[offset];
+
+ if (!data->ctl_reg || data->oe_bit >= 31)
+ return;
+
+ /* switch direction */
+ clrsetbits_le32(priv->base + data->ctl_reg,
+ BIT(data->oe_bit), 0);
+}
+
static void msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
- /* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(priv->pin_data, gpio))
- return;
+ msm_gpio_direction_input_special(priv, gpio);
/* Disable OE bit */
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
@@ -49,13 +67,33 @@ static void msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
return;
}
+static int msm_gpio_set_value_special(struct msm_gpio_bank *priv,
+ unsigned int gpio, int value)
+{
+ unsigned int offset = gpio - priv->pin_data->special_pins_start;
+ const struct msm_special_pin_data *data;
+
+ if (!priv->pin_data->special_pins_data)
+ return 0;
+
+ data = &priv->pin_data->special_pins_data[offset];
+
+ if (!data->io_reg || data->out_bit >= 31)
+ return 0;
+
+ value = !!value;
+ /* set value */
+ writel(value << data->out_bit, priv->base + data->io_reg);
+
+ return 0;
+}
+
static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
- /* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(priv->pin_data, gpio))
- return 0;
+ return msm_gpio_set_value_special(priv, gpio, value);
value = !!value;
/* set value */
@@ -64,14 +102,42 @@ static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
return 0;
}
+static int msm_gpio_direction_output_special(struct msm_gpio_bank *priv,
+ unsigned int gpio,
+ int value)
+{
+ unsigned int offset = gpio - priv->pin_data->special_pins_start;
+ const struct msm_special_pin_data *data;
+
+ if (!priv->pin_data->special_pins_data)
+ return 0;
+
+ data = &priv->pin_data->special_pins_data[offset];
+
+ if (!data->io_reg || data->out_bit >= 31)
+ return 0;
+
+ value = !!value;
+ /* set value */
+ writel(value << data->out_bit, priv->base + data->io_reg);
+
+ if (!data->ctl_reg || data->oe_bit >= 31)
+ return 0;
+
+ /* switch direction */
+ clrsetbits_le32(priv->base + data->ctl_reg,
+ BIT(data->oe_bit), BIT(data->oe_bit));
+
+ return 0;
+}
+
static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
int value)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
- /* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(priv->pin_data, gpio))
- return 0;
+ return msm_gpio_direction_output_special(priv, gpio, value);
value = !!value;
/* set value */
@@ -100,13 +166,28 @@ static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flag
return 0;
}
+static int msm_gpio_get_value_special(struct msm_gpio_bank *priv, unsigned int gpio)
+{
+ unsigned int offset = gpio - priv->pin_data->special_pins_start;
+ const struct msm_special_pin_data *data;
+
+ if (!priv->pin_data->special_pins_data)
+ return 0;
+
+ data = &priv->pin_data->special_pins_data[offset];
+
+ if (!data->io_reg || data->in_bit >= 31)
+ return 0;
+
+ return !!(readl(priv->base + data->io_reg) >> data->in_bit);
+}
+
static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
- /* Always NOP for special pins, assume they're in the correct state */
if (qcom_is_special_pin(priv->pin_data, gpio))
- return 0;
+ return msm_gpio_get_value_special(priv, gpio);
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
}
diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c
index 80fee841ee3..f2ef4e5ce14 100644
--- a/drivers/gpio/qcom_pmic_gpio.c
+++ b/drivers/gpio/qcom_pmic_gpio.c
@@ -69,17 +69,6 @@
#define REG_EN_CTL 0x46
#define REG_EN_CTL_ENABLE (1 << 7)
-/**
- * pmic_gpio_match_data - platform specific configuration
- *
- * @PMIC_MATCH_READONLY: treat all GPIOs as readonly, don't attempt to configure them.
- * This is a workaround for an unknown bug on some platforms where trying to write the
- * GPIO configuration registers causes the board to hang.
- */
-enum pmic_gpio_quirks {
- QCOM_PMIC_QUIRK_READONLY = (1 << 0),
-};
-
struct qcom_pmic_gpio_data {
uint32_t pid; /* Peripheral ID on SPMI bus */
bool lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */
@@ -128,13 +117,8 @@ static int qcom_gpio_set_direction(struct udevice *dev, unsigned int offset,
{
struct qcom_pmic_gpio_data *plat = dev_get_plat(dev);
uint32_t gpio_base = plat->pid + REG_OFFSET(offset);
- ulong quirks = dev_get_driver_data(dev);
int ret = 0;
- /* Some PMICs don't like their GPIOs being configured */
- if (quirks & QCOM_PMIC_QUIRK_READONLY)
- return 0;
-
/* Disable the GPIO */
ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
REG_EN_CTL_ENABLE, 0);
@@ -278,7 +262,6 @@ static int qcom_gpio_bind(struct udevice *dev)
{
struct qcom_pmic_gpio_data *plat = dev_get_plat(dev);
- ulong quirks = dev_get_driver_data(dev);
struct udevice *child;
struct driver *drv;
int ret;
@@ -292,7 +275,7 @@ static int qcom_gpio_bind(struct udevice *dev)
/* Bind the GPIO driver as a child of the PMIC. */
ret = device_bind_with_driver_data(dev, drv,
dev->name,
- quirks, dev_ofnode(dev), &child);
+ 0, dev_ofnode(dev), &child);
if (ret)
return log_msg_ret("bind", ret);
@@ -361,11 +344,11 @@ static int qcom_gpio_probe(struct udevice *dev)
static const struct udevice_id qcom_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
- { .compatible = "qcom,pm8998-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
+ { .compatible = "qcom,pm8998-gpio" },
{ .compatible = "qcom,pms405-gpio" },
- { .compatible = "qcom,pm6125-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
- { .compatible = "qcom,pm8150-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
- { .compatible = "qcom,pm8550-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
+ { .compatible = "qcom,pm6125-gpio" },
+ { .compatible = "qcom,pm8150-gpio" },
+ { .compatible = "qcom,pm8550-gpio" },
{ }
};
diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
index 3aae1813352..5c77203d606 100644
--- a/drivers/phy/qcom/Kconfig
+++ b/drivers/phy/qcom/Kconfig
@@ -12,6 +12,12 @@ config PHY_QCOM_IPQ4019_USB
help
Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
+config PHY_QCOM_QMP_UFS
+ tristate "Qualcomm QMP UFS PHY driver"
+ depends on PHY && ARCH_SNAPDRAGON
+ help
+ Enable this to support the UFS QMP PHY on various Qualcomm chipsets.
+
config PHY_QCOM_QUSB2
tristate "Qualcomm USB QUSB2 PHY driver"
depends on PHY && ARCH_SNAPDRAGON
diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
index a5153061dfb..dc3ed492696 100644
--- a/drivers/phy/qcom/Makefile
+++ b/drivers/phy/qcom/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
+obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2) += phy-qcom-snps-femto-v2.o
obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v2.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v2.h
new file mode 100644
index 00000000000..a0803a8783d
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v2.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V2_H_
+#define QCOM_PHY_QMP_PCS_UFS_V2_H_
+
+#define QPHY_V2_PCS_UFS_PHY_START 0x000
+#define QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL 0x004
+
+#define QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x034
+#define QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL 0x038
+#define QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x03c
+#define QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL 0x040
+
+#define QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP 0x0cc
+#define QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL 0x13c
+#define QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME 0x140
+#define QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2 0x148
+#define QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND 0x154
+
+#define QPHY_V2_PCS_UFS_READY_STATUS 0x168
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v3.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v3.h
new file mode 100644
index 00000000000..adea13c3a9e
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v3.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V3_H_
+#define QCOM_PHY_QMP_PCS_UFS_V3_H_
+
+#define QPHY_V3_PCS_UFS_PHY_START 0x000
+#define QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x02c
+#define QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x034
+#define QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL 0x134
+#define QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME 0x138
+#define QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1 0x13c
+#define QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2 0x140
+#define QPHY_V3_PCS_UFS_READY_STATUS 0x160
+#define QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1 0x1bc
+#define QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1 0x1c4
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v4.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v4.h
new file mode 100644
index 00000000000..a1c7d3d1715
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v4.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V4_H_
+#define QCOM_PHY_QMP_PCS_UFS_V4_H_
+
+/* Only for QMP V4 PHY - UFS PCS registers */
+#define QPHY_V4_PCS_UFS_PHY_START 0x000
+#define QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V4_PCS_UFS_SW_RESET 0x008
+#define QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c
+#define QPHY_V4_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010
+#define QPHY_V4_PCS_UFS_PLL_CNTL 0x02c
+#define QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030
+#define QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038
+#define QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060
+#define QPHY_V4_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074
+#define QPHY_V4_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0b4
+#define QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL 0x124
+#define QPHY_V4_PCS_UFS_LINECFG_DISABLE 0x148
+#define QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME 0x150
+#define QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2 0x158
+#define QPHY_V4_PCS_UFS_TX_PWM_GEAR_BAND 0x160
+#define QPHY_V4_PCS_UFS_TX_HS_GEAR_BAND 0x168
+#define QPHY_V4_PCS_UFS_READY_STATUS 0x180
+#define QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1 0x1d8
+#define QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1 0x1e0
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v5.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v5.h
new file mode 100644
index 00000000000..07959964fcf
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v5.h
@@ -0,0 +1,32 @@
+/* Only for QMP V5 PHY - UFS PCS registers */
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V5_H_
+#define QCOM_PHY_QMP_PCS_UFS_V5_H_
+
+/* Only for QMP V5 PHY - UFS PCS registers */
+#define QPHY_V5_PCS_UFS_PHY_START 0x000
+#define QPHY_V5_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V5_PCS_UFS_SW_RESET 0x008
+#define QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c
+#define QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010
+#define QPHY_V5_PCS_UFS_PLL_CNTL 0x02c
+#define QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030
+#define QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038
+#define QPHY_V5_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060
+#define QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074
+#define QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0b4
+#define QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL 0x124
+#define QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME 0x150
+#define QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1 0x154
+#define QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2 0x158
+#define QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND 0x160
+#define QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND 0x168
+#define QPHY_V5_PCS_UFS_READY_STATUS 0x180
+#define QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1 0x1d8
+#define QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1 0x1e0
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v6.h
new file mode 100644
index 00000000000..f19f9892ed7
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-ufs-v6.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V6_H_
+#define QCOM_PHY_QMP_PCS_UFS_V6_H_
+
+/* Only for QMP V6 PHY - UFS PCS registers */
+#define QPHY_V6_PCS_UFS_PHY_START 0x000
+#define QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V6_PCS_UFS_SW_RESET 0x008
+#define QPHY_V6_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB 0x00c
+#define QPHY_V6_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB 0x010
+#define QPHY_V6_PCS_UFS_PCS_CTRL1 0x020
+#define QPHY_V6_PCS_UFS_PLL_CNTL 0x02c
+#define QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x030
+#define QPHY_V6_PCS_UFS_TX_SMALL_AMP_DRV_LVL 0x038
+#define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL 0x060
+#define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY 0x074
+#define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY 0x0bc
+#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY 0x12c
+#define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL 0x158
+#define QPHY_V6_PCS_UFS_LINECFG_DISABLE 0x17c
+#define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME 0x184
+#define QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2 0x18c
+#define QPHY_V6_PCS_UFS_TX_PWM_GEAR_BAND 0x178
+#define QPHY_V6_PCS_UFS_TX_HS_GEAR_BAND 0x174
+#define QPHY_V6_PCS_UFS_READY_STATUS 0x1a8
+#define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1 0x1f4
+#define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1 0x1fc
+#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME 0x220
+#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4 0x240
+#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5 0x244
+#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6 0x248
+#define QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7 0x24c
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-v2.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-v2.h
new file mode 100644
index 00000000000..bf36399d005
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-v2.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V2_H_
+#define QCOM_PHY_QMP_PCS_V2_H_
+
+/* Only for QMP V2 PHY - PCS registers */
+#define QPHY_V2_PCS_SW_RESET 0x000
+#define QPHY_V2_PCS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V2_PCS_START_CONTROL 0x008
+#define QPHY_V2_PCS_TXDEEMPH_M6DB_V0 0x024
+#define QPHY_V2_PCS_TXDEEMPH_M3P5DB_V0 0x028
+#define QPHY_V2_PCS_ENDPOINT_REFCLK_DRIVE 0x054
+#define QPHY_V2_PCS_RX_IDLE_DTCT_CNTRL 0x058
+#define QPHY_V2_PCS_POWER_STATE_CONFIG1 0x060
+#define QPHY_V2_PCS_POWER_STATE_CONFIG2 0x064
+#define QPHY_V2_PCS_POWER_STATE_CONFIG4 0x06c
+#define QPHY_V2_PCS_LOCK_DETECT_CONFIG1 0x080
+#define QPHY_V2_PCS_LOCK_DETECT_CONFIG2 0x084
+#define QPHY_V2_PCS_LOCK_DETECT_CONFIG3 0x088
+#define QPHY_V2_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x0a0
+#define QPHY_V2_PCS_LP_WAKEUP_DLY_TIME_AUXCLK 0x0a4
+#define QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME 0x0a8
+#define QPHY_V2_PCS_FLL_CNTRL1 0x0c0
+#define QPHY_V2_PCS_FLL_CNTRL2 0x0c4
+#define QPHY_V2_PCS_FLL_CNT_VAL_L 0x0c8
+#define QPHY_V2_PCS_FLL_CNT_VAL_H_TOL 0x0cc
+#define QPHY_V2_PCS_FLL_MAN_CODE 0x0d0
+#define QPHY_V2_PCS_AUTONOMOUS_MODE_CTRL 0x0d4
+#define QPHY_V2_PCS_LFPS_RXTERM_IRQ_CLEAR 0x0d8
+#define QPHY_V2_PCS_LFPS_RXTERM_IRQ_STATUS 0x178
+#define QPHY_V2_PCS_USB_PCS_STATUS 0x17c /* USB */
+#define QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1a8
+#define QPHY_V2_PCS_OSC_DTCT_ACTIONS 0x1ac
+#define QPHY_V2_PCS_RX_SIGDET_LVL 0x1d8
+#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1dc
+#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1e0
+
+#define QPHY_V2_PCS_PCI_PCS_STATUS 0x174 /* PCI */
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-v3.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-v3.h
new file mode 100644
index 00000000000..10dbbb00620
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-v3.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V3_H_
+#define QCOM_PHY_QMP_PCS_V3_H_
+
+/* Only for QMP V3 PHY - PCS registers */
+#define QPHY_V3_PCS_SW_RESET 0x000
+#define QPHY_V3_PCS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V3_PCS_START_CONTROL 0x008
+#define QPHY_V3_PCS_TXMGN_V0 0x00c
+#define QPHY_V3_PCS_TXMGN_V1 0x010
+#define QPHY_V3_PCS_TXMGN_V2 0x014
+#define QPHY_V3_PCS_TXMGN_V3 0x018
+#define QPHY_V3_PCS_TXMGN_V4 0x01c
+#define QPHY_V3_PCS_TXMGN_LS 0x020
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V0 0x024
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0 0x028
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V1 0x02c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1 0x030
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V2 0x034
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2 0x038
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V3 0x03c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3 0x040
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_V4 0x044
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4 0x048
+#define QPHY_V3_PCS_TXDEEMPH_M6DB_LS 0x04c
+#define QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS 0x050
+#define QPHY_V3_PCS_ENDPOINT_REFCLK_DRIVE 0x054
+#define QPHY_V3_PCS_RX_IDLE_DTCT_CNTRL 0x058
+#define QPHY_V3_PCS_RATE_SLEW_CNTRL 0x05c
+#define QPHY_V3_PCS_POWER_STATE_CONFIG1 0x060
+#define QPHY_V3_PCS_POWER_STATE_CONFIG2 0x064
+#define QPHY_V3_PCS_POWER_STATE_CONFIG3 0x068
+#define QPHY_V3_PCS_POWER_STATE_CONFIG4 0x06c
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L 0x070
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H 0x074
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L 0x078
+#define QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H 0x07c
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG1 0x080
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG2 0x084
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG3 0x088
+#define QPHY_V3_PCS_TSYNC_RSYNC_TIME 0x08c
+#define QPHY_V3_PCS_SIGDET_LOW_2_IDLE_TIME 0x090
+#define QPHY_V3_PCS_BEACON_2_IDLE_TIME_L 0x094
+#define QPHY_V3_PCS_BEACON_2_IDLE_TIME_H 0x098
+#define QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_SYSCLK 0x09c
+#define QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x0a0
+#define QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK 0x0a4
+#define QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME 0x0a8
+#define QPHY_V3_PCS_LFPS_DET_HIGH_COUNT_VAL 0x0ac
+#define QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK 0x0b0
+#define QPHY_V3_PCS_LFPS_TX_END_CNT_P2U3_START 0x0b4
+#define QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME 0x0b8
+#define QPHY_V3_PCS_RXEQTRAINING_RUN_TIME 0x0bc
+#define QPHY_V3_PCS_TXONESZEROS_RUN_LENGTH 0x0c0
+#define QPHY_V3_PCS_FLL_CNTRL1 0x0c4
+#define QPHY_V3_PCS_FLL_CNTRL2 0x0c8
+#define QPHY_V3_PCS_FLL_CNT_VAL_L 0x0cc
+#define QPHY_V3_PCS_FLL_CNT_VAL_H_TOL 0x0d0
+#define QPHY_V3_PCS_FLL_MAN_CODE 0x0d4
+#define QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL 0x0d8
+#define QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR 0x0dc
+#define QPHY_V3_PCS_ARCVR_DTCT_EN_PERIOD 0x0e0
+#define QPHY_V3_PCS_ARCVR_DTCT_CM_DLY 0x0e4
+#define QPHY_V3_PCS_ALFPS_DEGLITCH_VAL 0x0e8
+#define QPHY_V3_PCS_INSIG_SW_CTRL1 0x0ec
+#define QPHY_V3_PCS_INSIG_SW_CTRL2 0x0f0
+#define QPHY_V3_PCS_INSIG_SW_CTRL3 0x0f4
+#define QPHY_V3_PCS_INSIG_MX_CTRL1 0x0f8
+#define QPHY_V3_PCS_INSIG_MX_CTRL2 0x0fc
+#define QPHY_V3_PCS_INSIG_MX_CTRL3 0x100
+#define QPHY_V3_PCS_OUTSIG_SW_CTRL1 0x104
+#define QPHY_V3_PCS_OUTSIG_MX_CTRL1 0x108
+#define QPHY_V3_PCS_CLK_DEBUG_BYPASS_CTRL 0x10c
+#define QPHY_V3_PCS_TEST_CONTROL 0x110
+#define QPHY_V3_PCS_TEST_CONTROL2 0x114
+#define QPHY_V3_PCS_TEST_CONTROL3 0x118
+#define QPHY_V3_PCS_TEST_CONTROL4 0x11c
+#define QPHY_V3_PCS_TEST_CONTROL5 0x120
+#define QPHY_V3_PCS_TEST_CONTROL6 0x124
+#define QPHY_V3_PCS_TEST_CONTROL7 0x128
+#define QPHY_V3_PCS_COM_RESET_CONTROL 0x12c
+#define QPHY_V3_PCS_BIST_CTRL 0x130
+#define QPHY_V3_PCS_PRBS_POLY0 0x134
+#define QPHY_V3_PCS_PRBS_POLY1 0x138
+#define QPHY_V3_PCS_PRBS_SEED0 0x13c
+#define QPHY_V3_PCS_PRBS_SEED1 0x140
+#define QPHY_V3_PCS_FIXED_PAT_CTRL 0x144
+#define QPHY_V3_PCS_FIXED_PAT0 0x148
+#define QPHY_V3_PCS_FIXED_PAT1 0x14c
+#define QPHY_V3_PCS_FIXED_PAT2 0x150
+#define QPHY_V3_PCS_FIXED_PAT3 0x154
+#define QPHY_V3_PCS_COM_CLK_SWITCH_CTRL 0x158
+#define QPHY_V3_PCS_ELECIDLE_DLY_SEL 0x15c
+#define QPHY_V3_PCS_SPARE1 0x160
+#define QPHY_V3_PCS_BIST_CHK_ERR_CNT_L_STATUS 0x164
+#define QPHY_V3_PCS_BIST_CHK_ERR_CNT_H_STATUS 0x168
+#define QPHY_V3_PCS_BIST_CHK_STATUS 0x16c
+#define QPHY_V3_PCS_LFPS_RXTERM_IRQ_SOURCE_STATUS 0x170
+#define QPHY_V3_PCS_PCS_STATUS 0x174
+#define QPHY_V3_PCS_PCS_STATUS2 0x178
+#define QPHY_V3_PCS_PCS_STATUS3 0x17c
+#define QPHY_V3_PCS_COM_RESET_STATUS 0x180
+#define QPHY_V3_PCS_OSC_DTCT_STATUS 0x184
+#define QPHY_V3_PCS_REVISION_ID0 0x188
+#define QPHY_V3_PCS_REVISION_ID1 0x18c
+#define QPHY_V3_PCS_REVISION_ID2 0x190
+#define QPHY_V3_PCS_REVISION_ID3 0x194
+#define QPHY_V3_PCS_DEBUG_BUS_0_STATUS 0x198
+#define QPHY_V3_PCS_DEBUG_BUS_1_STATUS 0x19c
+#define QPHY_V3_PCS_DEBUG_BUS_2_STATUS 0x1a0
+#define QPHY_V3_PCS_DEBUG_BUS_3_STATUS 0x1a4
+#define QPHY_V3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1a8
+#define QPHY_V3_PCS_OSC_DTCT_ACTIONS 0x1ac
+#define QPHY_V3_PCS_SIGDET_CNTRL 0x1b0
+#define QPHY_V3_PCS_IDAC_CAL_CNTRL 0x1b4
+#define QPHY_V3_PCS_CMN_ACK_OUT_SEL 0x1b8
+#define QPHY_V3_PCS_PLL_LOCK_CHK_DLY_TIME_SYSCLK 0x1bc
+#define QPHY_V3_PCS_AUTONOMOUS_MODE_STATUS 0x1c0
+#define QPHY_V3_PCS_ENDPOINT_REFCLK_CNTRL 0x1c4
+#define QPHY_V3_PCS_EPCLK_PRE_PLL_LOCK_DLY_SYSCLK 0x1c8
+#define QPHY_V3_PCS_EPCLK_PRE_PLL_LOCK_DLY_AUXCLK 0x1cc
+#define QPHY_V3_PCS_EPCLK_DLY_COUNT_VAL_L 0x1d0
+#define QPHY_V3_PCS_EPCLK_DLY_COUNT_VAL_H 0x1d4
+#define QPHY_V3_PCS_RX_SIGDET_LVL 0x1d8
+#define QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1dc
+#define QPHY_V3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1e0
+#define QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL2 0x1e4
+#define QPHY_V3_PCS_RXTERMINATION_DLY_SEL 0x1e8
+#define QPHY_V3_PCS_LFPS_PER_TIMER_VAL 0x1ec
+#define QPHY_V3_PCS_SIGDET_STARTUP_TIMER_VAL 0x1f0
+#define QPHY_V3_PCS_LOCK_DETECT_CONFIG4 0x1f4
+#define QPHY_V3_PCS_RX_SIGDET_DTCT_CNTRL 0x1f8
+#define QPHY_V3_PCS_PCS_STATUS4 0x1fc
+#define QPHY_V3_PCS_PCS_STATUS4_CLEAR 0x200
+#define QPHY_V3_PCS_DEC_ERROR_COUNT_STATUS 0x204
+#define QPHY_V3_PCS_COMMA_POS_STATUS 0x208
+#define QPHY_V3_PCS_REFGEN_REQ_CONFIG1 0x20c
+#define QPHY_V3_PCS_REFGEN_REQ_CONFIG2 0x210
+#define QPHY_V3_PCS_REFGEN_REQ_CONFIG3 0x214
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-pcs-v4.h b/drivers/phy/qcom/phy-qcom-qmp-pcs-v4.h
new file mode 100644
index 00000000000..a2c1eba2b69
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-pcs-v4.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_V4_H_
+#define QCOM_PHY_QMP_PCS_V4_H_
+
+/* Only for QMP V4 PHY - USB/PCIe PCS registers */
+#define QPHY_V4_PCS_SW_RESET 0x000
+#define QPHY_V4_PCS_REVISION_ID0 0x004
+#define QPHY_V4_PCS_REVISION_ID1 0x008
+#define QPHY_V4_PCS_REVISION_ID2 0x00c
+#define QPHY_V4_PCS_REVISION_ID3 0x010
+#define QPHY_V4_PCS_PCS_STATUS1 0x014
+#define QPHY_V4_PCS_PCS_STATUS2 0x018
+#define QPHY_V4_PCS_PCS_STATUS3 0x01c
+#define QPHY_V4_PCS_PCS_STATUS4 0x020
+#define QPHY_V4_PCS_PCS_STATUS5 0x024
+#define QPHY_V4_PCS_PCS_STATUS6 0x028
+#define QPHY_V4_PCS_PCS_STATUS7 0x02c
+#define QPHY_V4_PCS_DEBUG_BUS_0_STATUS 0x030
+#define QPHY_V4_PCS_DEBUG_BUS_1_STATUS 0x034
+#define QPHY_V4_PCS_DEBUG_BUS_2_STATUS 0x038
+#define QPHY_V4_PCS_DEBUG_BUS_3_STATUS 0x03c
+#define QPHY_V4_PCS_POWER_DOWN_CONTROL 0x040
+#define QPHY_V4_PCS_START_CONTROL 0x044
+#define QPHY_V4_PCS_INSIG_SW_CTRL1 0x048
+#define QPHY_V4_PCS_INSIG_SW_CTRL2 0x04c
+#define QPHY_V4_PCS_INSIG_SW_CTRL3 0x050
+#define QPHY_V4_PCS_INSIG_SW_CTRL4 0x054
+#define QPHY_V4_PCS_INSIG_SW_CTRL5 0x058
+#define QPHY_V4_PCS_INSIG_SW_CTRL6 0x05c
+#define QPHY_V4_PCS_INSIG_SW_CTRL7 0x060
+#define QPHY_V4_PCS_INSIG_SW_CTRL8 0x064
+#define QPHY_V4_PCS_INSIG_MX_CTRL1 0x068
+#define QPHY_V4_PCS_INSIG_MX_CTRL2 0x06c
+#define QPHY_V4_PCS_INSIG_MX_CTRL3 0x070
+#define QPHY_V4_PCS_INSIG_MX_CTRL4 0x074
+#define QPHY_V4_PCS_INSIG_MX_CTRL5 0x078
+#define QPHY_V4_PCS_INSIG_MX_CTRL7 0x07c
+#define QPHY_V4_PCS_INSIG_MX_CTRL8 0x080
+#define QPHY_V4_PCS_OUTSIG_SW_CTRL1 0x084
+#define QPHY_V4_PCS_OUTSIG_MX_CTRL1 0x088
+#define QPHY_V4_PCS_CLAMP_ENABLE 0x08c
+#define QPHY_V4_PCS_POWER_STATE_CONFIG1 0x090
+#define QPHY_V4_PCS_POWER_STATE_CONFIG2 0x094
+#define QPHY_V4_PCS_FLL_CNTRL1 0x098
+#define QPHY_V4_PCS_FLL_CNTRL2 0x09c
+#define QPHY_V4_PCS_FLL_CNT_VAL_L 0x0a0
+#define QPHY_V4_PCS_FLL_CNT_VAL_H_TOL 0x0a4
+#define QPHY_V4_PCS_FLL_MAN_CODE 0x0a8
+#define QPHY_V4_PCS_TEST_CONTROL1 0x0ac
+#define QPHY_V4_PCS_TEST_CONTROL2 0x0b0
+#define QPHY_V4_PCS_TEST_CONTROL3 0x0b4
+#define QPHY_V4_PCS_TEST_CONTROL4 0x0b8
+#define QPHY_V4_PCS_TEST_CONTROL5 0x0bc
+#define QPHY_V4_PCS_TEST_CONTROL6 0x0c0
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG1 0x0c4
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG2 0x0c8
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG3 0x0cc
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG4 0x0d0
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG5 0x0d4
+#define QPHY_V4_PCS_LOCK_DETECT_CONFIG6 0x0d8
+#define QPHY_V4_PCS_REFGEN_REQ_CONFIG1 0x0dc
+#define QPHY_V4_PCS_REFGEN_REQ_CONFIG2 0x0e0
+#define QPHY_V4_PCS_REFGEN_REQ_CONFIG3 0x0e4
+#define QPHY_V4_PCS_BIST_CTRL 0x0e8
+#define QPHY_V4_PCS_PRBS_POLY0 0x0ec
+#define QPHY_V4_PCS_PRBS_POLY1 0x0f0
+#define QPHY_V4_PCS_FIXED_PAT0 0x0f4
+#define QPHY_V4_PCS_FIXED_PAT1 0x0f8
+#define QPHY_V4_PCS_FIXED_PAT2 0x0fc
+#define QPHY_V4_PCS_FIXED_PAT3 0x100
+#define QPHY_V4_PCS_FIXED_PAT4 0x104
+#define QPHY_V4_PCS_FIXED_PAT5 0x108
+#define QPHY_V4_PCS_FIXED_PAT6 0x10c
+#define QPHY_V4_PCS_FIXED_PAT7 0x110
+#define QPHY_V4_PCS_FIXED_PAT8 0x114
+#define QPHY_V4_PCS_FIXED_PAT9 0x118
+#define QPHY_V4_PCS_FIXED_PAT10 0x11c
+#define QPHY_V4_PCS_FIXED_PAT11 0x120
+#define QPHY_V4_PCS_FIXED_PAT12 0x124
+#define QPHY_V4_PCS_FIXED_PAT13 0x128
+#define QPHY_V4_PCS_FIXED_PAT14 0x12c
+#define QPHY_V4_PCS_FIXED_PAT15 0x130
+#define QPHY_V4_PCS_TXMGN_CONFIG 0x134
+#define QPHY_V4_PCS_G12S1_TXMGN_V0 0x138
+#define QPHY_V4_PCS_G12S1_TXMGN_V1 0x13c
+#define QPHY_V4_PCS_G12S1_TXMGN_V2 0x140
+#define QPHY_V4_PCS_G12S1_TXMGN_V3 0x144
+#define QPHY_V4_PCS_G12S1_TXMGN_V4 0x148
+#define QPHY_V4_PCS_G12S1_TXMGN_V0_RS 0x14c
+#define QPHY_V4_PCS_G12S1_TXMGN_V1_RS 0x150
+#define QPHY_V4_PCS_G12S1_TXMGN_V2_RS 0x154
+#define QPHY_V4_PCS_G12S1_TXMGN_V3_RS 0x158
+#define QPHY_V4_PCS_G12S1_TXMGN_V4_RS 0x15c
+#define QPHY_V4_PCS_G3S2_TXMGN_MAIN 0x160
+#define QPHY_V4_PCS_G3S2_TXMGN_MAIN_RS 0x164
+#define QPHY_V4_PCS_G12S1_TXDEEMPH_M6DB 0x168
+#define QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB 0x16c
+#define QPHY_V4_PCS_G3S2_PRE_GAIN 0x170
+#define QPHY_V4_PCS_G3S2_POST_GAIN 0x174
+#define QPHY_V4_PCS_G3S2_PRE_POST_OFFSET 0x178
+#define QPHY_V4_PCS_G3S2_PRE_GAIN_RS 0x17c
+#define QPHY_V4_PCS_G3S2_POST_GAIN_RS 0x180
+#define QPHY_V4_PCS_G3S2_PRE_POST_OFFSET_RS 0x184
+#define QPHY_V4_PCS_RX_SIGDET_LVL 0x188
+#define QPHY_V4_PCS_RX_SIGDET_DTCT_CNTRL 0x18c
+#define QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
+#define QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H 0x194
+#define QPHY_V4_PCS_RATE_SLEW_CNTRL1 0x198
+#define QPHY_V4_PCS_RATE_SLEW_CNTRL2 0x19c
+#define QPHY_V4_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x1a0
+#define QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x1a4
+#define QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x1a8
+#define QPHY_V4_PCS_TSYNC_RSYNC_TIME 0x1ac
+#define QPHY_V4_PCS_CDR_RESET_TIME 0x1b0
+#define QPHY_V4_PCS_TSYNC_DLY_TIME 0x1b4
+#define QPHY_V4_PCS_ELECIDLE_DLY_SEL 0x1b8
+#define QPHY_V4_PCS_CMN_ACK_OUT_SEL 0x1bc
+#define QPHY_V4_PCS_ALIGN_DETECT_CONFIG1 0x1c0
+#define QPHY_V4_PCS_ALIGN_DETECT_CONFIG2 0x1c4
+#define QPHY_V4_PCS_ALIGN_DETECT_CONFIG3 0x1c8
+#define QPHY_V4_PCS_ALIGN_DETECT_CONFIG4 0x1cc
+#define QPHY_V4_PCS_PCS_TX_RX_CONFIG 0x1d0
+#define QPHY_V4_PCS_RX_IDLE_DTCT_CNTRL 0x1d4
+#define QPHY_V4_PCS_RX_DCC_CAL_CONFIG 0x1d8
+#define QPHY_V4_PCS_EQ_CONFIG1 0x1dc
+#define QPHY_V4_PCS_EQ_CONFIG2 0x1e0
+#define QPHY_V4_PCS_EQ_CONFIG3 0x1e4
+#define QPHY_V4_PCS_EQ_CONFIG4 0x1e8
+#define QPHY_V4_PCS_EQ_CONFIG5 0x1ec
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v3.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v3.h
new file mode 100644
index 00000000000..c0bd54e0e7b
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v3.h
@@ -0,0 +1,111 @@
+
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_V3_H_
+#define QCOM_PHY_QMP_QSERDES_COM_V3_H_
+
+/* Only for QMP V3 PHY - QSERDES COM registers */
+#define QSERDES_V3_COM_ATB_SEL1 0x000
+#define QSERDES_V3_COM_ATB_SEL2 0x004
+#define QSERDES_V3_COM_FREQ_UPDATE 0x008
+#define QSERDES_V3_COM_BG_TIMER 0x00c
+#define QSERDES_V3_COM_SSC_EN_CENTER 0x010
+#define QSERDES_V3_COM_SSC_ADJ_PER1 0x014
+#define QSERDES_V3_COM_SSC_ADJ_PER2 0x018
+#define QSERDES_V3_COM_SSC_PER1 0x01c
+#define QSERDES_V3_COM_SSC_PER2 0x020
+#define QSERDES_V3_COM_SSC_STEP_SIZE1 0x024
+#define QSERDES_V3_COM_SSC_STEP_SIZE2 0x028
+#define QSERDES_V3_COM_POST_DIV 0x02c
+#define QSERDES_V3_COM_POST_DIV_MUX 0x030
+#define QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN 0x034
+#define QSERDES_V3_COM_CLK_ENABLE1 0x038
+#define QSERDES_V3_COM_SYS_CLK_CTRL 0x03c
+#define QSERDES_V3_COM_SYSCLK_BUF_ENABLE 0x040
+#define QSERDES_V3_COM_PLL_EN 0x044
+#define QSERDES_V3_COM_PLL_IVCO 0x048
+#define QSERDES_V3_COM_CMN_IETRIM 0x04c
+#define QSERDES_V3_COM_CMN_IPTRIM 0x050
+#define QSERDES_V3_COM_EP_CLOCK_DETECT_CTR 0x054
+#define QSERDES_V3_COM_SYSCLK_DET_COMP_STATUS 0x058
+#define QSERDES_V3_COM_CLK_EP_DIV 0x05c
+#define QSERDES_V3_COM_CP_CTRL_MODE0 0x060
+#define QSERDES_V3_COM_CP_CTRL_MODE1 0x064
+#define QSERDES_V3_COM_PLL_RCTRL_MODE0 0x068
+#define QSERDES_V3_COM_PLL_RCTRL_MODE1 0x06c
+#define QSERDES_V3_COM_PLL_CCTRL_MODE0 0x070
+#define QSERDES_V3_COM_PLL_CCTRL_MODE1 0x074
+#define QSERDES_V3_COM_PLL_CNTRL 0x078
+#define QSERDES_V3_COM_BIAS_EN_CTRL_BY_PSM 0x07c
+#define QSERDES_V3_COM_SYSCLK_EN_SEL 0x080
+#define QSERDES_V3_COM_CML_SYSCLK_SEL 0x084
+#define QSERDES_V3_COM_RESETSM_CNTRL 0x088
+#define QSERDES_V3_COM_RESETSM_CNTRL2 0x08c
+#define QSERDES_V3_COM_LOCK_CMP_EN 0x090
+#define QSERDES_V3_COM_LOCK_CMP_CFG 0x094
+#define QSERDES_V3_COM_LOCK_CMP1_MODE0 0x098
+#define QSERDES_V3_COM_LOCK_CMP2_MODE0 0x09c
+#define QSERDES_V3_COM_LOCK_CMP3_MODE0 0x0a0
+#define QSERDES_V3_COM_LOCK_CMP1_MODE1 0x0a4
+#define QSERDES_V3_COM_LOCK_CMP2_MODE1 0x0a8
+#define QSERDES_V3_COM_LOCK_CMP3_MODE1 0x0ac
+#define QSERDES_V3_COM_DEC_START_MODE0 0x0b0
+#define QSERDES_V3_COM_DEC_START_MODE1 0x0b4
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE0 0x0b8
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE0 0x0bc
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE0 0x0c0
+#define QSERDES_V3_COM_DIV_FRAC_START1_MODE1 0x0c4
+#define QSERDES_V3_COM_DIV_FRAC_START2_MODE1 0x0c8
+#define QSERDES_V3_COM_DIV_FRAC_START3_MODE1 0x0cc
+#define QSERDES_V3_COM_INTEGLOOP_INITVAL 0x0d0
+#define QSERDES_V3_COM_INTEGLOOP_EN 0x0d4
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0 0x0d8
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0 0x0dc
+#define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1 0x0e0
+#define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1 0x0e4
+#define QSERDES_V3_COM_VCOCAL_DEADMAN_CTRL 0x0e8
+#define QSERDES_V3_COM_VCO_TUNE_CTRL 0x0ec
+#define QSERDES_V3_COM_VCO_TUNE_MAP 0x0f0
+#define QSERDES_V3_COM_VCO_TUNE1_MODE0 0x0f4
+#define QSERDES_V3_COM_VCO_TUNE2_MODE0 0x0f8
+#define QSERDES_V3_COM_VCO_TUNE1_MODE1 0x0fc
+#define QSERDES_V3_COM_VCO_TUNE2_MODE1 0x100
+#define QSERDES_V3_COM_VCO_TUNE_INITVAL1 0x104
+#define QSERDES_V3_COM_VCO_TUNE_INITVAL2 0x108
+#define QSERDES_V3_COM_VCO_TUNE_MINVAL1 0x10c
+#define QSERDES_V3_COM_VCO_TUNE_MINVAL2 0x110
+#define QSERDES_V3_COM_VCO_TUNE_MAXVAL1 0x114
+#define QSERDES_V3_COM_VCO_TUNE_MAXVAL2 0x118
+#define QSERDES_V3_COM_VCO_TUNE_TIMER1 0x11c
+#define QSERDES_V3_COM_VCO_TUNE_TIMER2 0x120
+#define QSERDES_V3_COM_CMN_STATUS 0x124
+#define QSERDES_V3_COM_RESET_SM_STATUS 0x128
+#define QSERDES_V3_COM_RESTRIM_CODE_STATUS 0x12c
+#define QSERDES_V3_COM_PLLCAL_CODE1_STATUS 0x130
+#define QSERDES_V3_COM_PLLCAL_CODE2_STATUS 0x134
+#define QSERDES_V3_COM_CLK_SELECT 0x138
+#define QSERDES_V3_COM_HSCLK_SEL 0x13c
+#define QSERDES_V3_COM_INTEGLOOP_BINCODE_STATUS 0x140
+#define QSERDES_V3_COM_PLL_ANALOG 0x144
+#define QSERDES_V3_COM_CORECLK_DIV_MODE0 0x148
+#define QSERDES_V3_COM_CORECLK_DIV_MODE1 0x14c
+#define QSERDES_V3_COM_SW_RESET 0x150
+#define QSERDES_V3_COM_CORE_CLK_EN 0x154
+#define QSERDES_V3_COM_C_READY_STATUS 0x158
+#define QSERDES_V3_COM_CMN_CONFIG 0x15c
+#define QSERDES_V3_COM_CMN_RATE_OVERRIDE 0x160
+#define QSERDES_V3_COM_SVS_MODE_CLK_SEL 0x164
+#define QSERDES_V3_COM_DEBUG_BUS0 0x168
+#define QSERDES_V3_COM_DEBUG_BUS1 0x16c
+#define QSERDES_V3_COM_DEBUG_BUS2 0x170
+#define QSERDES_V3_COM_DEBUG_BUS3 0x174
+#define QSERDES_V3_COM_DEBUG_BUS_SEL 0x178
+#define QSERDES_V3_COM_CMN_MISC1 0x17c
+#define QSERDES_V3_COM_CMN_MISC2 0x180
+#define QSERDES_V3_COM_CMN_MODE 0x184
+#define QSERDES_V3_COM_CMN_VREG_SEL 0x188
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v4.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v4.h
new file mode 100644
index 00000000000..b0e3298d990
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v4.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_V4_H_
+#define QCOM_PHY_QMP_QSERDES_COM_V4_H_
+
+/* Only for QMP V4 PHY - QSERDES COM registers */
+#define QSERDES_V4_COM_ATB_SEL1 0x000
+#define QSERDES_V4_COM_ATB_SEL2 0x004
+#define QSERDES_V4_COM_FREQ_UPDATE 0x008
+#define QSERDES_V4_COM_BG_TIMER 0x00c
+#define QSERDES_V4_COM_SSC_EN_CENTER 0x010
+#define QSERDES_V4_COM_SSC_ADJ_PER1 0x014
+#define QSERDES_V4_COM_SSC_ADJ_PER2 0x018
+#define QSERDES_V4_COM_SSC_PER1 0x01c
+#define QSERDES_V4_COM_SSC_PER2 0x020
+#define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0 0x024
+#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0 0x028
+#define QSERDES_V4_COM_SSC_STEP_SIZE3_MODE0 0x02c
+#define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1 0x030
+#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1 0x034
+#define QSERDES_V4_COM_SSC_STEP_SIZE3_MODE1 0x038
+#define QSERDES_V4_COM_POST_DIV 0x03c
+#define QSERDES_V4_COM_POST_DIV_MUX 0x040
+#define QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN 0x044
+#define QSERDES_V4_COM_CLK_ENABLE1 0x048
+#define QSERDES_V4_COM_SYS_CLK_CTRL 0x04c
+#define QSERDES_V4_COM_SYSCLK_BUF_ENABLE 0x050
+#define QSERDES_V4_COM_PLL_EN 0x054
+#define QSERDES_V4_COM_PLL_IVCO 0x058
+#define QSERDES_V4_COM_CMN_IETRIM 0x05c
+#define QSERDES_V4_COM_CMN_IPTRIM 0x060
+#define QSERDES_V4_COM_EP_CLOCK_DETECT_CTRL 0x064
+#define QSERDES_V4_COM_SYSCLK_DET_COMP_STATUS 0x068
+#define QSERDES_V4_COM_CLK_EP_DIV_MODE0 0x06c
+#define QSERDES_V4_COM_CLK_EP_DIV_MODE1 0x070
+#define QSERDES_V4_COM_CP_CTRL_MODE0 0x074
+#define QSERDES_V4_COM_CP_CTRL_MODE1 0x078
+#define QSERDES_V4_COM_PLL_RCTRL_MODE0 0x07c
+#define QSERDES_V4_COM_PLL_RCTRL_MODE1 0x080
+#define QSERDES_V4_COM_PLL_CCTRL_MODE0 0x084
+#define QSERDES_V4_COM_PLL_CCTRL_MODE1 0x088
+#define QSERDES_V4_COM_PLL_CNTRL 0x08c
+#define QSERDES_V4_COM_BIAS_EN_CTRL_BY_PSM 0x090
+#define QSERDES_V4_COM_SYSCLK_EN_SEL 0x094
+#define QSERDES_V4_COM_CML_SYSCLK_SEL 0x098
+#define QSERDES_V4_COM_RESETSM_CNTRL 0x09c
+#define QSERDES_V4_COM_RESETSM_CNTRL2 0x0a0
+#define QSERDES_V4_COM_LOCK_CMP_EN 0x0a4
+#define QSERDES_V4_COM_LOCK_CMP_CFG 0x0a8
+#define QSERDES_V4_COM_LOCK_CMP1_MODE0 0x0ac
+#define QSERDES_V4_COM_LOCK_CMP2_MODE0 0x0b0
+#define QSERDES_V4_COM_LOCK_CMP1_MODE1 0x0b4
+#define QSERDES_V4_COM_LOCK_CMP2_MODE1 0x0b8
+#define QSERDES_V4_COM_DEC_START_MODE0 0x0bc
+#define QSERDES_V4_COM_DEC_START_MSB_MODE0 0x0c0
+#define QSERDES_V4_COM_DEC_START_MODE1 0x0c4
+#define QSERDES_V4_COM_DEC_START_MSB_MODE1 0x0c8
+#define QSERDES_V4_COM_DIV_FRAC_START1_MODE0 0x0cc
+#define QSERDES_V4_COM_DIV_FRAC_START2_MODE0 0x0d0
+#define QSERDES_V4_COM_DIV_FRAC_START3_MODE0 0x0d4
+#define QSERDES_V4_COM_DIV_FRAC_START1_MODE1 0x0d8
+#define QSERDES_V4_COM_DIV_FRAC_START2_MODE1 0x0dc
+#define QSERDES_V4_COM_DIV_FRAC_START3_MODE1 0x0e0
+#define QSERDES_V4_COM_INTEGLOOP_INITVAL 0x0e4
+#define QSERDES_V4_COM_INTEGLOOP_EN 0x0e8
+#define QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0 0x0ec
+#define QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0 0x0f0
+#define QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1 0x0f4
+#define QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1 0x0f8
+#define QSERDES_V4_COM_INTEGLOOP_P_PATH_GAIN0 0x0fc
+#define QSERDES_V4_COM_INTEGLOOP_P_PATH_GAIN1 0x100
+#define QSERDES_V4_COM_VCOCAL_DEADMAN_CTRL 0x104
+#define QSERDES_V4_COM_VCO_TUNE_CTRL 0x108
+#define QSERDES_V4_COM_VCO_TUNE_MAP 0x10c
+#define QSERDES_V4_COM_VCO_TUNE1_MODE0 0x110
+#define QSERDES_V4_COM_VCO_TUNE2_MODE0 0x114
+#define QSERDES_V4_COM_VCO_TUNE1_MODE1 0x118
+#define QSERDES_V4_COM_VCO_TUNE2_MODE1 0x11c
+#define QSERDES_V4_COM_VCO_TUNE_INITVAL1 0x120
+#define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124
+#define QSERDES_V4_COM_VCO_TUNE_MINVAL1 0x128
+#define QSERDES_V4_COM_VCO_TUNE_MINVAL2 0x12c
+#define QSERDES_V4_COM_VCO_TUNE_MAXVAL1 0x130
+#define QSERDES_V4_COM_VCO_TUNE_MAXVAL2 0x134
+#define QSERDES_V4_COM_VCO_TUNE_TIMER1 0x138
+#define QSERDES_V4_COM_VCO_TUNE_TIMER2 0x13c
+#define QSERDES_V4_COM_CMN_STATUS 0x140
+#define QSERDES_V4_COM_RESET_SM_STATUS 0x144
+#define QSERDES_V4_COM_RESTRIM_CODE_STATUS 0x148
+#define QSERDES_V4_COM_PLLCAL_CODE1_STATUS 0x14c
+#define QSERDES_V4_COM_PLLCAL_CODE2_STATUS 0x150
+#define QSERDES_V4_COM_CLK_SELECT 0x154
+#define QSERDES_V4_COM_HSCLK_SEL 0x158
+#define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c
+#define QSERDES_V4_COM_INTEGLOOP_BINCODE_STATUS 0x160
+#define QSERDES_V4_COM_PLL_ANALOG 0x164
+#define QSERDES_V4_COM_CORECLK_DIV_MODE0 0x168
+#define QSERDES_V4_COM_CORECLK_DIV_MODE1 0x16c
+#define QSERDES_V4_COM_SW_RESET 0x170
+#define QSERDES_V4_COM_CORE_CLK_EN 0x174
+#define QSERDES_V4_COM_C_READY_STATUS 0x178
+#define QSERDES_V4_COM_CMN_CONFIG 0x17c
+#define QSERDES_V4_COM_CMN_RATE_OVERRIDE 0x180
+#define QSERDES_V4_COM_SVS_MODE_CLK_SEL 0x184
+#define QSERDES_V4_COM_DEBUG_BUS0 0x188
+#define QSERDES_V4_COM_DEBUG_BUS1 0x18c
+#define QSERDES_V4_COM_DEBUG_BUS2 0x190
+#define QSERDES_V4_COM_DEBUG_BUS3 0x194
+#define QSERDES_V4_COM_DEBUG_BUS_SEL 0x198
+#define QSERDES_V4_COM_CMN_MISC1 0x19c
+#define QSERDES_V4_COM_CMN_MISC2 0x1a0
+#define QSERDES_V4_COM_CMN_MODE 0x1a4
+#define QSERDES_V4_COM_VCO_DC_LEVEL_CTRL 0x1a8
+#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac
+#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0
+#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x1b4
+#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x1b8
+#define QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL 0x1bc
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v6.h
new file mode 100644
index 00000000000..328c6c0b0b0
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com-v6.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_V6_H_
+#define QCOM_PHY_QMP_QSERDES_COM_V6_H_
+
+/* Only for QMP V6 PHY - QSERDES COM registers */
+
+#define QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1 0x00
+#define QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1 0x04
+#define QSERDES_V6_COM_CP_CTRL_MODE1 0x10
+#define QSERDES_V6_COM_PLL_RCTRL_MODE1 0x14
+#define QSERDES_V6_COM_PLL_CCTRL_MODE1 0x18
+#define QSERDES_V6_COM_CORECLK_DIV_MODE1 0x1c
+#define QSERDES_V6_COM_LOCK_CMP1_MODE1 0x20
+#define QSERDES_V6_COM_LOCK_CMP2_MODE1 0x24
+#define QSERDES_V6_COM_DEC_START_MODE1 0x28
+#define QSERDES_V6_COM_DEC_START_MSB_MODE1 0x2c
+#define QSERDES_V6_COM_DIV_FRAC_START1_MODE1 0x30
+#define QSERDES_V6_COM_DIV_FRAC_START2_MODE1 0x34
+#define QSERDES_V6_COM_DIV_FRAC_START3_MODE1 0x38
+#define QSERDES_V6_COM_HSCLK_SEL_1 0x3c
+#define QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE1 0x40
+#define QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE1 0x44
+#define QSERDES_V6_COM_VCO_TUNE1_MODE1 0x48
+#define QSERDES_V6_COM_VCO_TUNE2_MODE1 0x4c
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x50
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x54
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x58
+#define QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x5c
+#define QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0 0x60
+#define QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0 0x64
+#define QSERDES_V6_COM_CP_CTRL_MODE0 0x70
+#define QSERDES_V6_COM_PLL_RCTRL_MODE0 0x74
+#define QSERDES_V6_COM_PLL_CCTRL_MODE0 0x78
+#define QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0 0x7c
+#define QSERDES_V6_COM_LOCK_CMP1_MODE0 0x80
+#define QSERDES_V6_COM_LOCK_CMP2_MODE0 0x84
+#define QSERDES_V6_COM_DEC_START_MODE0 0x88
+#define QSERDES_V6_COM_DEC_START_MSB_MODE0 0x8c
+#define QSERDES_V6_COM_DIV_FRAC_START1_MODE0 0x90
+#define QSERDES_V6_COM_DIV_FRAC_START2_MODE0 0x94
+#define QSERDES_V6_COM_DIV_FRAC_START3_MODE0 0x98
+#define QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1 0x9c
+#define QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0 0xa0
+#define QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0 0xa4
+#define QSERDES_V6_COM_VCO_TUNE1_MODE0 0xa8
+#define QSERDES_V6_COM_VCO_TUNE2_MODE0 0xac
+#define QSERDES_V6_COM_BG_TIMER 0xbc
+#define QSERDES_V6_COM_SSC_EN_CENTER 0xc0
+#define QSERDES_V6_COM_SSC_ADJ_PER1 0xc4
+#define QSERDES_V6_COM_SSC_PER1 0xcc
+#define QSERDES_V6_COM_SSC_PER2 0xd0
+#define QSERDES_V6_COM_PLL_POST_DIV_MUX 0xd8
+#define QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN 0xdc
+#define QSERDES_V6_COM_CLK_ENABLE1 0xe0
+#define QSERDES_V6_COM_SYS_CLK_CTRL 0xe4
+#define QSERDES_V6_COM_SYSCLK_BUF_ENABLE 0xe8
+#define QSERDES_V6_COM_PLL_IVCO 0xf4
+#define QSERDES_V6_COM_PLL_IVCO_MODE1 0xf8
+#define QSERDES_V6_COM_CMN_IETRIM 0xfc
+#define QSERDES_V6_COM_CMN_IPTRIM 0x100
+#define QSERDES_V6_COM_SYSCLK_EN_SEL 0x110
+#define QSERDES_V6_COM_RESETSM_CNTRL 0x118
+#define QSERDES_V6_COM_LOCK_CMP_EN 0x120
+#define QSERDES_V6_COM_LOCK_CMP_CFG 0x124
+#define QSERDES_V6_COM_VCO_TUNE_CTRL 0x13c
+#define QSERDES_V6_COM_VCO_TUNE_MAP 0x140
+#define QSERDES_V6_COM_VCO_TUNE_INITVAL2 0x148
+#define QSERDES_V6_COM_VCO_TUNE_MAXVAL2 0x158
+#define QSERDES_V6_COM_CLK_SELECT 0x164
+#define QSERDES_V6_COM_CORE_CLK_EN 0x170
+#define QSERDES_V6_COM_CMN_CONFIG_1 0x174
+#define QSERDES_V6_COM_SVS_MODE_CLK_SEL 0x17c
+#define QSERDES_V6_COM_CMN_MISC_1 0x184
+#define QSERDES_V6_COM_CMN_MODE 0x188
+#define QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL 0x198
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8
+#define QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac
+#define QSERDES_V6_COM_ADDITIONAL_MISC 0x1b4
+#define QSERDES_V6_COM_ADDITIONAL_MISC_2 0x1b8
+#define QSERDES_V6_COM_ADDITIONAL_MISC_3 0x1bc
+#define QSERDES_V6_COM_CMN_STATUS 0x1d0
+#define QSERDES_V6_COM_C_READY_STATUS 0x1f8
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-com.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com.h
new file mode 100644
index 00000000000..7fa5363feeb
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-com.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_COM_H_
+#define QCOM_PHY_QMP_QSERDES_COM_H_
+
+/* Only for QMP V2 PHY - QSERDES COM registers */
+#define QSERDES_COM_ATB_SEL1 0x000
+#define QSERDES_COM_ATB_SEL2 0x004
+#define QSERDES_COM_FREQ_UPDATE 0x008
+#define QSERDES_COM_BG_TIMER 0x00c
+#define QSERDES_COM_SSC_EN_CENTER 0x010
+#define QSERDES_COM_SSC_ADJ_PER1 0x014
+#define QSERDES_COM_SSC_ADJ_PER2 0x018
+#define QSERDES_COM_SSC_PER1 0x01c
+#define QSERDES_COM_SSC_PER2 0x020
+#define QSERDES_COM_SSC_STEP_SIZE1 0x024
+#define QSERDES_COM_SSC_STEP_SIZE2 0x028
+#define QSERDES_COM_POST_DIV 0x02c
+#define QSERDES_COM_POST_DIV_MUX 0x030
+#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
+#define QSERDES_COM_CLK_ENABLE1 0x038
+#define QSERDES_COM_SYS_CLK_CTRL 0x03c
+#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
+#define QSERDES_COM_PLL_EN 0x044
+#define QSERDES_COM_PLL_IVCO 0x048
+#define QSERDES_COM_LOCK_CMP1_MODE0 0x04c
+#define QSERDES_COM_LOCK_CMP2_MODE0 0x050
+#define QSERDES_COM_LOCK_CMP3_MODE0 0x054
+#define QSERDES_COM_LOCK_CMP1_MODE1 0x058
+#define QSERDES_COM_LOCK_CMP2_MODE1 0x05c
+#define QSERDES_COM_LOCK_CMP3_MODE1 0x060
+#define QSERDES_COM_LOCK_CMP1_MODE2 0x064
+#define QSERDES_COM_CMN_RSVD0 0x064
+#define QSERDES_COM_LOCK_CMP2_MODE2 0x068
+#define QSERDES_COM_EP_CLOCK_DETECT_CTRL 0x068
+#define QSERDES_COM_LOCK_CMP3_MODE2 0x06c
+#define QSERDES_COM_SYSCLK_DET_COMP_STATUS 0x06c
+#define QSERDES_COM_BG_TRIM 0x070
+#define QSERDES_COM_CLK_EP_DIV 0x074
+#define QSERDES_COM_CP_CTRL_MODE0 0x078
+#define QSERDES_COM_CP_CTRL_MODE1 0x07c
+#define QSERDES_COM_CP_CTRL_MODE2 0x080
+#define QSERDES_COM_CMN_RSVD1 0x080
+#define QSERDES_COM_PLL_RCTRL_MODE0 0x084
+#define QSERDES_COM_PLL_RCTRL_MODE1 0x088
+#define QSERDES_COM_PLL_RCTRL_MODE2 0x08c
+#define QSERDES_COM_CMN_RSVD2 0x08c
+#define QSERDES_COM_PLL_CCTRL_MODE0 0x090
+#define QSERDES_COM_PLL_CCTRL_MODE1 0x094
+#define QSERDES_COM_PLL_CCTRL_MODE2 0x098
+#define QSERDES_COM_CMN_RSVD3 0x098
+#define QSERDES_COM_PLL_CNTRL 0x09c
+#define QSERDES_COM_PHASE_SEL_CTRL 0x0a0
+#define QSERDES_COM_PHASE_SEL_DC 0x0a4
+#define QSERDES_COM_CORE_CLK_IN_SYNC_SEL 0x0a8
+#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
+#define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
+#define QSERDES_COM_CML_SYSCLK_SEL 0x0b0
+#define QSERDES_COM_RESETSM_CNTRL 0x0b4
+#define QSERDES_COM_RESETSM_CNTRL2 0x0b8
+#define QSERDES_COM_RESTRIM_CTRL 0x0bc
+#define QSERDES_COM_RESTRIM_CTRL2 0x0c0
+#define QSERDES_COM_RESCODE_DIV_NUM 0x0c4
+#define QSERDES_COM_LOCK_CMP_EN 0x0c8
+#define QSERDES_COM_LOCK_CMP_CFG 0x0cc
+#define QSERDES_COM_DEC_START_MODE0 0x0d0
+#define QSERDES_COM_DEC_START_MODE1 0x0d4
+#define QSERDES_COM_DEC_START_MODE2 0x0d8
+#define QSERDES_COM_VCOCAL_DEADMAN_CTRL 0x0d8
+#define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0dc
+#define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0e0
+#define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0e4
+#define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0e8
+#define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0ec
+#define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0f0
+#define QSERDES_COM_DIV_FRAC_START1_MODE2 0x0f4
+#define QSERDES_COM_VCO_TUNE_MINVAL1 0x0f4
+#define QSERDES_COM_DIV_FRAC_START2_MODE2 0x0f8
+#define QSERDES_COM_VCO_TUNE_MINVAL2 0x0f8
+#define QSERDES_COM_DIV_FRAC_START3_MODE2 0x0fc
+#define QSERDES_COM_CMN_RSVD4 0x0fc
+#define QSERDES_COM_INTEGLOOP_INITVAL 0x100
+#define QSERDES_COM_INTEGLOOP_EN 0x104
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10c
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE2 0x118
+#define QSERDES_COM_VCO_TUNE_MAXVAL1 0x118
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE2 0x11c
+#define QSERDES_COM_VCO_TUNE_MAXVAL2 0x11c
+#define QSERDES_COM_RES_TRIM_CONTROL2 0x120
+#define QSERDES_COM_VCO_TUNE_CTRL 0x124
+#define QSERDES_COM_VCO_TUNE_MAP 0x128
+#define QSERDES_COM_VCO_TUNE1_MODE0 0x12c
+#define QSERDES_COM_VCO_TUNE2_MODE0 0x130
+#define QSERDES_COM_VCO_TUNE1_MODE1 0x134
+#define QSERDES_COM_VCO_TUNE2_MODE1 0x138
+#define QSERDES_COM_VCO_TUNE1_MODE2 0x13c
+#define QSERDES_COM_VCO_TUNE_INITVAL1 0x13c
+#define QSERDES_COM_VCO_TUNE2_MODE2 0x140
+#define QSERDES_COM_VCO_TUNE_INITVAL2 0x140
+#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
+#define QSERDES_COM_VCO_TUNE_TIMER2 0x148
+#define QSERDES_COM_SAR 0x14c
+#define QSERDES_COM_SAR_CLK 0x150
+#define QSERDES_COM_SAR_CODE_OUT_STATUS 0x154
+#define QSERDES_COM_SAR_CODE_READY_STATUS 0x158
+#define QSERDES_COM_CMN_STATUS 0x15c
+#define QSERDES_COM_RESET_SM_STATUS 0x160
+#define QSERDES_COM_RESTRIM_CODE_STATUS 0x164
+#define QSERDES_COM_PLLCAL_CODE1_STATUS 0x168
+#define QSERDES_COM_PLLCAL_CODE2_STATUS 0x16c
+#define QSERDES_COM_BG_CTRL 0x170
+#define QSERDES_COM_CLK_SELECT 0x174
+#define QSERDES_COM_HSCLK_SEL 0x178
+#define QSERDES_COM_INTEGLOOP_BINCODE_STATUS 0x17c
+#define QSERDES_COM_PLL_ANALOG 0x180
+#define QSERDES_COM_CORECLK_DIV 0x184
+#define QSERDES_COM_SW_RESET 0x188
+#define QSERDES_COM_CORE_CLK_EN 0x18c
+#define QSERDES_COM_C_READY_STATUS 0x190
+#define QSERDES_COM_CMN_CONFIG 0x194
+#define QSERDES_COM_CMN_RATE_OVERRIDE 0x198
+#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
+#define QSERDES_COM_DEBUG_BUS0 0x1a0
+#define QSERDES_COM_DEBUG_BUS1 0x1a4
+#define QSERDES_COM_DEBUG_BUS2 0x1a8
+#define QSERDES_COM_DEBUG_BUS3 0x1ac
+#define QSERDES_COM_DEBUG_BUS_SEL 0x1b0
+#define QSERDES_COM_CMN_MISC1 0x1b4
+#define QSERDES_COM_CMN_MISC2 0x1b8
+#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
+#define QSERDES_COM_CORECLK_DIV_MODE2 0x1c0
+#define QSERDES_COM_CMN_RSVD5 0x1c4
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-pll.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-pll.h
new file mode 100644
index 00000000000..231e59364e3
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-pll.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_PLL_H_
+#define QCOM_PHY_QMP_QSERDES_PLL_H_
+
+/* QMP V2 PHY for PCIE gen3 ports - QSERDES PLL registers */
+#define QSERDES_PLL_BG_TIMER 0x00c
+#define QSERDES_PLL_SSC_EN_CENTER 0x010
+#define QSERDES_PLL_SSC_ADJ_PER1 0x014
+#define QSERDES_PLL_SSC_ADJ_PER2 0x018
+#define QSERDES_PLL_SSC_PER1 0x01c
+#define QSERDES_PLL_SSC_PER2 0x020
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE0 0x028
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE1 0x02c
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE1 0x030
+#define QSERDES_PLL_BIAS_EN_CLKBUFLR_EN 0x03c
+#define QSERDES_PLL_CLK_ENABLE1 0x040
+#define QSERDES_PLL_SYS_CLK_CTRL 0x044
+#define QSERDES_PLL_SYSCLK_BUF_ENABLE 0x048
+#define QSERDES_PLL_PLL_IVCO 0x050
+#define QSERDES_PLL_LOCK_CMP1_MODE0 0x054
+#define QSERDES_PLL_LOCK_CMP2_MODE0 0x058
+#define QSERDES_PLL_LOCK_CMP1_MODE1 0x060
+#define QSERDES_PLL_LOCK_CMP2_MODE1 0x064
+#define QSERDES_PLL_BG_TRIM 0x074
+#define QSERDES_PLL_CLK_EP_DIV_MODE0 0x078
+#define QSERDES_PLL_CLK_EP_DIV_MODE1 0x07c
+#define QSERDES_PLL_CP_CTRL_MODE0 0x080
+#define QSERDES_PLL_CP_CTRL_MODE1 0x084
+#define QSERDES_PLL_PLL_RCTRL_MODE0 0x088
+#define QSERDES_PLL_PLL_RCTRL_MODE1 0x08c
+#define QSERDES_PLL_PLL_CCTRL_MODE0 0x090
+#define QSERDES_PLL_PLL_CCTRL_MODE1 0x094
+#define QSERDES_PLL_BIAS_EN_CTRL_BY_PSM 0x0a4
+#define QSERDES_PLL_SYSCLK_EN_SEL 0x0a8
+#define QSERDES_PLL_RESETSM_CNTRL 0x0b0
+#define QSERDES_PLL_LOCK_CMP_EN 0x0c4
+#define QSERDES_PLL_DEC_START_MODE0 0x0cc
+#define QSERDES_PLL_DEC_START_MODE1 0x0d0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE0 0x0d8
+#define QSERDES_PLL_DIV_FRAC_START2_MODE0 0x0dc
+#define QSERDES_PLL_DIV_FRAC_START3_MODE0 0x0e0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE1 0x0e4
+#define QSERDES_PLL_DIV_FRAC_START2_MODE1 0x0e8
+#define QSERDES_PLL_DIV_FRAC_START3_MODE1 0x0ec
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE0 0x100
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE0 0x104
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE1 0x108
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE1 0x10c
+#define QSERDES_PLL_VCO_TUNE_MAP 0x120
+#define QSERDES_PLL_VCO_TUNE1_MODE0 0x124
+#define QSERDES_PLL_VCO_TUNE2_MODE0 0x128
+#define QSERDES_PLL_VCO_TUNE1_MODE1 0x12c
+#define QSERDES_PLL_VCO_TUNE2_MODE1 0x130
+#define QSERDES_PLL_VCO_TUNE_TIMER1 0x13c
+#define QSERDES_PLL_VCO_TUNE_TIMER2 0x140
+#define QSERDES_PLL_CLK_SELECT 0x16c
+#define QSERDES_PLL_HSCLK_SEL 0x170
+#define QSERDES_PLL_CORECLK_DIV 0x17c
+#define QSERDES_PLL_CORE_CLK_EN 0x184
+#define QSERDES_PLL_CMN_CONFIG 0x18c
+#define QSERDES_PLL_SVS_MODE_CLK_SEL 0x194
+#define QSERDES_PLL_CORECLK_DIV_MODE1 0x1b4
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
new file mode 100644
index 00000000000..d17a5235796
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_UFS_V6_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_UFS_V6_H_
+
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_TX 0x28
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX 0x2c
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX 0x30
+#define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX 0x34
+#define QSERDES_UFS_V6_TX_LANE_MODE_1 0x7c
+#define QSERDES_UFS_V6_TX_FR_DCC_CTRL 0x108
+
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2 0x08
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4 0x10
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4 0x24
+#define QSERDES_UFS_V6_RX_UCDR_SO_SATURATION 0x28
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4 0x54
+#define QSERDES_UFS_V6_RX_UCDR_PI_CTRL1 0x58
+#define QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0 0xc4
+#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2 0xd4
+#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4 0xdc
+#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4 0xf0
+#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS 0xf4
+#define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL 0x178
+#define QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4 0x1ac
+#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x1bc
+#define QSERDES_UFS_V6_RX_INTERFACE_MODE 0x1e0
+#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3 0x1c4
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0 0x208
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1 0x20c
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2 0x210
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3 0x214
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4 0x218
+#define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6 0x220
+#define QSERDES_UFS_V6_RX_MODE_RATE2_B3 0x238
+#define QSERDES_UFS_V6_RX_MODE_RATE2_B6 0x244
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B3 0x25c
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B4 0x260
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B5 0x264
+#define QSERDES_UFS_V6_RX_MODE_RATE3_B8 0x270
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B0 0x274
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B1 0x278
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B2 0x27c
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B3 0x280
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B4 0x284
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B6 0x28c
+#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL 0x2f8
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v3.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v3.h
new file mode 100644
index 00000000000..161e6df30ea
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v3.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V3_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_V3_H_
+
+/* Only for QMP V3 PHY - TX registers */
+#define QSERDES_V3_TX_BIST_MODE_LANENO 0x000
+#define QSERDES_V3_TX_CLKBUF_ENABLE 0x008
+#define QSERDES_V3_TX_TX_EMP_POST1_LVL 0x00c
+#define QSERDES_V3_TX_TX_DRV_LVL 0x01c
+#define QSERDES_V3_TX_RESET_TSYNC_EN 0x024
+#define QSERDES_V3_TX_PRE_STALL_LDO_BOOST_EN 0x028
+#define QSERDES_V3_TX_TX_BAND 0x02c
+#define QSERDES_V3_TX_SLEW_CNTL 0x030
+#define QSERDES_V3_TX_INTERFACE_SELECT 0x034
+#define QSERDES_V3_TX_RES_CODE_LANE_TX 0x03c
+#define QSERDES_V3_TX_RES_CODE_LANE_RX 0x040
+#define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX 0x044
+#define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX 0x048
+#define QSERDES_V3_TX_DEBUG_BUS_SEL 0x058
+#define QSERDES_V3_TX_TRANSCEIVER_BIAS_EN 0x05c
+#define QSERDES_V3_TX_HIGHZ_DRVR_EN 0x060
+#define QSERDES_V3_TX_TX_POL_INV 0x064
+#define QSERDES_V3_TX_PARRATE_REC_DETECT_IDLE_EN 0x068
+#define QSERDES_V3_TX_LANE_MODE_1 0x08c
+#define QSERDES_V3_TX_LANE_MODE_2 0x090
+#define QSERDES_V3_TX_LANE_MODE_3 0x094
+#define QSERDES_V3_TX_RCV_DETECT_LVL_2 0x0a4
+#define QSERDES_V3_TX_TRAN_DRVR_EMP_EN 0x0c0
+#define QSERDES_V3_TX_TX_INTERFACE_MODE 0x0c4
+#define QSERDES_V3_TX_VMODE_CTRL1 0x0f0
+
+/* Only for QMP V3 PHY - RX registers */
+#define QSERDES_V3_RX_UCDR_FO_GAIN 0x008
+#define QSERDES_V3_RX_UCDR_SO_GAIN_HALF 0x00c
+#define QSERDES_V3_RX_UCDR_SO_GAIN 0x014
+#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF 0x024
+#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028
+#define QSERDES_V3_RX_UCDR_SVS_SO_GAIN 0x02c
+#define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN 0x030
+#define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034
+#define QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c
+#define QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040
+#define QSERDES_V3_RX_UCDR_PI_CONTROLS 0x044
+#define QSERDES_V3_RX_RX_TERM_BW 0x07c
+#define QSERDES_V3_RX_VGA_CAL_CNTRL1 0x0bc
+#define QSERDES_V3_RX_VGA_CAL_CNTRL2 0x0c0
+#define QSERDES_V3_RX_RX_EQ_GAIN2_LSB 0x0c8
+#define QSERDES_V3_RX_RX_EQ_GAIN2_MSB 0x0cc
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d0
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8
+#define QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc
+#define QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8
+#define QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc
+#define QSERDES_V3_RX_SIGDET_ENABLES 0x100
+#define QSERDES_V3_RX_SIGDET_CNTRL 0x104
+#define QSERDES_V3_RX_SIGDET_LVL 0x108
+#define QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL 0x10c
+#define QSERDES_V3_RX_RX_BAND 0x110
+#define QSERDES_V3_RX_RX_INTERFACE_MODE 0x11c
+#define QSERDES_V3_RX_RX_MODE_00 0x164
+#define QSERDES_V3_RX_RX_MODE_01 0x168
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v4.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v4.h
new file mode 100644
index 00000000000..6ee3bec9ac4
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx-v4.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V4_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_V4_H_
+
+/* Only for QMP V4 PHY - TX registers */
+#define QSERDES_V4_TX_BIST_MODE_LANENO 0x000
+#define QSERDES_V4_TX_BIST_INVERT 0x004
+#define QSERDES_V4_TX_CLKBUF_ENABLE 0x008
+#define QSERDES_V4_TX_TX_EMP_POST1_LVL 0x00c
+#define QSERDES_V4_TX_TX_IDLE_LVL_LARGE_AMP 0x010
+#define QSERDES_V4_TX_TX_DRV_LVL 0x014
+#define QSERDES_V4_TX_TX_DRV_LVL_OFFSET 0x018
+#define QSERDES_V4_TX_RESET_TSYNC_EN 0x01c
+#define QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN 0x020
+#define QSERDES_V4_TX_TX_BAND 0x024
+#define QSERDES_V4_TX_SLEW_CNTL 0x028
+#define QSERDES_V4_TX_INTERFACE_SELECT 0x02c
+#define QSERDES_V4_TX_LPB_EN 0x030
+#define QSERDES_V4_TX_RES_CODE_LANE_TX 0x034
+#define QSERDES_V4_TX_RES_CODE_LANE_RX 0x038
+#define QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX 0x03c
+#define QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX 0x040
+#define QSERDES_V4_TX_PERL_LENGTH1 0x044
+#define QSERDES_V4_TX_PERL_LENGTH2 0x048
+#define QSERDES_V4_TX_SERDES_BYP_EN_OUT 0x04c
+#define QSERDES_V4_TX_DEBUG_BUS_SEL 0x050
+#define QSERDES_V4_TX_TRANSCEIVER_BIAS_EN 0x054
+#define QSERDES_V4_TX_HIGHZ_DRVR_EN 0x058
+#define QSERDES_V4_TX_TX_POL_INV 0x05c
+#define QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN 0x060
+#define QSERDES_V4_TX_BIST_PATTERN1 0x064
+#define QSERDES_V4_TX_BIST_PATTERN2 0x068
+#define QSERDES_V4_TX_BIST_PATTERN3 0x06c
+#define QSERDES_V4_TX_BIST_PATTERN4 0x070
+#define QSERDES_V4_TX_BIST_PATTERN5 0x074
+#define QSERDES_V4_TX_BIST_PATTERN6 0x078
+#define QSERDES_V4_TX_BIST_PATTERN7 0x07c
+#define QSERDES_V4_TX_BIST_PATTERN8 0x080
+#define QSERDES_V4_TX_LANE_MODE_1 0x084
+#define QSERDES_V4_TX_LANE_MODE_2 0x088
+#define QSERDES_V4_TX_LANE_MODE_3 0x08c
+#define QSERDES_V4_TX_ATB_SEL1 0x090
+#define QSERDES_V4_TX_ATB_SEL2 0x094
+#define QSERDES_V4_TX_RCV_DETECT_LVL 0x098
+#define QSERDES_V4_TX_RCV_DETECT_LVL_2 0x09c
+#define QSERDES_V4_TX_PRBS_SEED1 0x0a0
+#define QSERDES_V4_TX_PRBS_SEED2 0x0a4
+#define QSERDES_V4_TX_PRBS_SEED3 0x0a8
+#define QSERDES_V4_TX_PRBS_SEED4 0x0ac
+#define QSERDES_V4_TX_RESET_GEN 0x0b0
+#define QSERDES_V4_TX_RESET_GEN_MUXES 0x0b4
+#define QSERDES_V4_TX_TRAN_DRVR_EMP_EN 0x0b8
+#define QSERDES_V4_TX_TX_INTERFACE_MODE 0x0bc
+#define QSERDES_V4_TX_PWM_CTRL 0x0c0
+#define QSERDES_V4_TX_PWM_ENCODED_OR_DATA 0x0c4
+#define QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND2 0x0c8
+#define QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND2 0x0cc
+#define QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND2 0x0d0
+#define QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND2 0x0d4
+#define QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0x0d8
+#define QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0x0dc
+#define QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0x0e0
+#define QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0x0e4
+#define QSERDES_V4_TX_VMODE_CTRL1 0x0e8
+#define QSERDES_V4_TX_ALOG_OBSV_BUS_CTRL_1 0x0ec
+#define QSERDES_V4_TX_BIST_STATUS 0x0f0
+#define QSERDES_V4_TX_BIST_ERROR_COUNT1 0x0f4
+#define QSERDES_V4_TX_BIST_ERROR_COUNT2 0x0f8
+#define QSERDES_V4_TX_ALOG_OBSV_BUS_STATUS_1 0x0fc
+#define QSERDES_V4_TX_LANE_DIG_CONFIG 0x100
+#define QSERDES_V4_TX_PI_QEC_CTRL 0x104
+#define QSERDES_V4_TX_PRE_EMPH 0x108
+#define QSERDES_V4_TX_SW_RESET 0x10c
+#define QSERDES_V4_TX_DCC_OFFSET 0x110
+#define QSERDES_V4_TX_DIG_BKUP_CTRL 0x114
+#define QSERDES_V4_TX_DEBUG_BUS0 0x118
+#define QSERDES_V4_TX_DEBUG_BUS1 0x11c
+#define QSERDES_V4_TX_DEBUG_BUS2 0x120
+#define QSERDES_V4_TX_DEBUG_BUS3 0x124
+#define QSERDES_V4_TX_READ_EQCODE 0x128
+#define QSERDES_V4_TX_READ_OFFSETCODE 0x12c
+#define QSERDES_V4_TX_IA_ERROR_COUNTER_LOW 0x130
+#define QSERDES_V4_TX_IA_ERROR_COUNTER_HIGH 0x134
+#define QSERDES_V4_TX_VGA_READ_CODE 0x138
+#define QSERDES_V4_TX_VTH_READ_CODE 0x13c
+#define QSERDES_V4_TX_DFE_TAP1_READ_CODE 0x140
+#define QSERDES_V4_TX_DFE_TAP2_READ_CODE 0x144
+#define QSERDES_V4_TX_IDAC_STATUS_I 0x148
+#define QSERDES_V4_TX_IDAC_STATUS_IBAR 0x14c
+#define QSERDES_V4_TX_IDAC_STATUS_Q 0x150
+#define QSERDES_V4_TX_IDAC_STATUS_QBAR 0x154
+#define QSERDES_V4_TX_IDAC_STATUS_A 0x158
+#define QSERDES_V4_TX_IDAC_STATUS_ABAR 0x15c
+#define QSERDES_V4_TX_IDAC_STATUS_SM_ON 0x160
+#define QSERDES_V4_TX_IDAC_STATUS_CAL_DONE 0x164
+#define QSERDES_V4_TX_IDAC_STATUS_SIGNERROR 0x168
+#define QSERDES_V4_TX_DCC_CAL_STATUS 0x16c
+
+/* Only for QMP V4 PHY - RX registers */
+#define QSERDES_V4_RX_UCDR_FO_GAIN_HALF 0x000
+#define QSERDES_V4_RX_UCDR_FO_GAIN_QUARTER 0x004
+#define QSERDES_V4_RX_UCDR_FO_GAIN 0x008
+#define QSERDES_V4_RX_UCDR_SO_GAIN_HALF 0x00c
+#define QSERDES_V4_RX_UCDR_SO_GAIN_QUARTER 0x010
+#define QSERDES_V4_RX_UCDR_SO_GAIN 0x014
+#define QSERDES_V4_RX_UCDR_SVS_FO_GAIN_HALF 0x018
+#define QSERDES_V4_RX_UCDR_SVS_FO_GAIN_QUARTER 0x01c
+#define QSERDES_V4_RX_UCDR_SVS_FO_GAIN 0x020
+#define QSERDES_V4_RX_UCDR_SVS_SO_GAIN_HALF 0x024
+#define QSERDES_V4_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028
+#define QSERDES_V4_RX_UCDR_SVS_SO_GAIN 0x02c
+#define QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN 0x030
+#define QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034
+#define QSERDES_V4_RX_UCDR_FO_TO_SO_DELAY 0x038
+#define QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c
+#define QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040
+#define QSERDES_V4_RX_UCDR_PI_CONTROLS 0x044
+#define QSERDES_V4_RX_UCDR_PI_CTRL2 0x048
+#define QSERDES_V4_RX_UCDR_SB2_THRESH1 0x04c
+#define QSERDES_V4_RX_UCDR_SB2_THRESH2 0x050
+#define QSERDES_V4_RX_UCDR_SB2_GAIN1 0x054
+#define QSERDES_V4_RX_UCDR_SB2_GAIN2 0x058
+#define QSERDES_V4_RX_AUX_CONTROL 0x05c
+#define QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE 0x060
+#define QSERDES_V4_RX_RCLK_AUXDATA_SEL 0x064
+#define QSERDES_V4_RX_AC_JTAG_ENABLE 0x068
+#define QSERDES_V4_RX_AC_JTAG_INITP 0x06c
+#define QSERDES_V4_RX_AC_JTAG_INITN 0x070
+#define QSERDES_V4_RX_AC_JTAG_LVL 0x074
+#define QSERDES_V4_RX_AC_JTAG_MODE 0x078
+#define QSERDES_V4_RX_AC_JTAG_RESET 0x07c
+#define QSERDES_V4_RX_RX_TERM_BW 0x080
+#define QSERDES_V4_RX_RX_RCVR_IQ_EN 0x084
+#define QSERDES_V4_RX_RX_IDAC_I_DC_OFFSETS 0x088
+#define QSERDES_V4_RX_RX_IDAC_IBAR_DC_OFFSETS 0x08c
+#define QSERDES_V4_RX_RX_IDAC_Q_DC_OFFSETS 0x090
+#define QSERDES_V4_RX_RX_IDAC_QBAR_DC_OFFSETS 0x094
+#define QSERDES_V4_RX_RX_IDAC_A_DC_OFFSETS 0x098
+#define QSERDES_V4_RX_RX_IDAC_ABAR_DC_OFFSETS 0x09c
+#define QSERDES_V4_RX_RX_IDAC_EN 0x0a0
+#define QSERDES_V4_RX_RX_IDAC_ENABLES 0x0a4
+#define QSERDES_V4_RX_RX_IDAC_SIGN 0x0a8
+#define QSERDES_V4_RX_RX_HIGHZ_HIGHRATE 0x0ac
+#define QSERDES_V4_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x0b0
+#define QSERDES_V4_RX_DFE_1 0x0b4
+#define QSERDES_V4_RX_DFE_2 0x0b8
+#define QSERDES_V4_RX_DFE_3 0x0bc
+#define QSERDES_V4_RX_DFE_4 0x0c0
+#define QSERDES_V4_RX_TX_ADAPT_PRE_THRESH1 0x0c4
+#define QSERDES_V4_RX_TX_ADAPT_PRE_THRESH2 0x0c8
+#define QSERDES_V4_RX_TX_ADAPT_POST_THRESH 0x0cc
+#define QSERDES_V4_RX_TX_ADAPT_MAIN_THRESH 0x0d0
+#define QSERDES_V4_RX_VGA_CAL_CNTRL1 0x0d4
+#define QSERDES_V4_RX_VGA_CAL_CNTRL2 0x0d8
+#define QSERDES_V4_RX_GM_CAL 0x0dc
+#define QSERDES_V4_RX_RX_VGA_GAIN2_LSB 0x0e0
+#define QSERDES_V4_RX_RX_VGA_GAIN2_MSB 0x0e4
+#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1 0x0e8
+#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2 0x0ec
+#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3 0x0f0
+#define QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4 0x0f4
+#define QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW 0x0f8
+#define QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH 0x0fc
+#define QSERDES_V4_RX_RX_IDAC_MEASURE_TIME 0x100
+#define QSERDES_V4_RX_RX_IDAC_ACCUMULATOR 0x104
+#define QSERDES_V4_RX_RX_EQ_OFFSET_LSB 0x108
+#define QSERDES_V4_RX_RX_EQ_OFFSET_MSB 0x10c
+#define QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x114
+#define QSERDES_V4_RX_SIGDET_ENABLES 0x118
+#define QSERDES_V4_RX_SIGDET_CNTRL 0x11c
+#define QSERDES_V4_RX_SIGDET_LVL 0x120
+#define QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_V4_RX_RX_BAND 0x128
+#define QSERDES_V4_RX_CDR_FREEZE_UP_DN 0x12c
+#define QSERDES_V4_RX_CDR_RESET_OVERRIDE 0x130
+#define QSERDES_V4_RX_RX_INTERFACE_MODE 0x134
+#define QSERDES_V4_RX_JITTER_GEN_MODE 0x138
+#define QSERDES_V4_RX_SJ_AMP1 0x13c
+#define QSERDES_V4_RX_SJ_AMP2 0x140
+#define QSERDES_V4_RX_SJ_PER1 0x144
+#define QSERDES_V4_RX_SJ_PER2 0x148
+#define QSERDES_V4_RX_PPM_OFFSET1 0x14c
+#define QSERDES_V4_RX_PPM_OFFSET2 0x150
+#define QSERDES_V4_RX_SIGN_PPM_PERIOD1 0x154
+#define QSERDES_V4_RX_SIGN_PPM_PERIOD2 0x158
+#define QSERDES_V4_RX_RX_PWM_ENABLE_AND_DATA 0x15c
+#define QSERDES_V4_RX_RX_PWM_GEAR1_TIMEOUT_COUNT 0x160
+#define QSERDES_V4_RX_RX_PWM_GEAR2_TIMEOUT_COUNT 0x164
+#define QSERDES_V4_RX_RX_PWM_GEAR3_TIMEOUT_COUNT 0x168
+#define QSERDES_V4_RX_RX_PWM_GEAR4_TIMEOUT_COUNT 0x16c
+#define QSERDES_V4_RX_RX_MODE_00_LOW 0x170
+#define QSERDES_V4_RX_RX_MODE_00_HIGH 0x174
+#define QSERDES_V4_RX_RX_MODE_00_HIGH2 0x178
+#define QSERDES_V4_RX_RX_MODE_00_HIGH3 0x17c
+#define QSERDES_V4_RX_RX_MODE_00_HIGH4 0x180
+#define QSERDES_V4_RX_RX_MODE_01_LOW 0x184
+#define QSERDES_V4_RX_RX_MODE_01_HIGH 0x188
+#define QSERDES_V4_RX_RX_MODE_01_HIGH2 0x18c
+#define QSERDES_V4_RX_RX_MODE_01_HIGH3 0x190
+#define QSERDES_V4_RX_RX_MODE_01_HIGH4 0x194
+#define QSERDES_V4_RX_RX_MODE_10_LOW 0x198
+#define QSERDES_V4_RX_RX_MODE_10_HIGH 0x19c
+#define QSERDES_V4_RX_RX_MODE_10_HIGH2 0x1a0
+#define QSERDES_V4_RX_RX_MODE_10_HIGH3 0x1a4
+#define QSERDES_V4_RX_RX_MODE_10_HIGH4 0x1a8
+#define QSERDES_V4_RX_PHPRE_CTRL 0x1ac
+#define QSERDES_V4_RX_PHPRE_INITVAL 0x1b0
+#define QSERDES_V4_RX_DFE_EN_TIMER 0x1b4
+#define QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET 0x1b8
+#define QSERDES_V4_RX_DCC_CTRL1 0x1bc
+#define QSERDES_V4_RX_DCC_CTRL2 0x1c0
+#define QSERDES_V4_RX_VTH_CODE 0x1c4
+#define QSERDES_V4_RX_VTH_MIN_THRESH 0x1c8
+#define QSERDES_V4_RX_VTH_MAX_THRESH 0x1cc
+#define QSERDES_V4_RX_ALOG_OBSV_BUS_CTRL_1 0x1d0
+#define QSERDES_V4_RX_PI_CTRL1 0x1d4
+#define QSERDES_V4_RX_PI_CTRL2 0x1d8
+#define QSERDES_V4_RX_PI_QUAD 0x1dc
+#define QSERDES_V4_RX_IDATA1 0x1e0
+#define QSERDES_V4_RX_IDATA2 0x1e4
+#define QSERDES_V4_RX_AUX_DATA1 0x1e8
+#define QSERDES_V4_RX_AUX_DATA2 0x1ec
+#define QSERDES_V4_RX_AC_JTAG_OUTP 0x1f0
+#define QSERDES_V4_RX_AC_JTAG_OUTN 0x1f4
+#define QSERDES_V4_RX_RX_SIGDET 0x1f8
+#define QSERDES_V4_RX_ALOG_OBSV_BUS_STATUS_1 0x1fc
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx.h b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx.h
new file mode 100644
index 00000000000..d20694513eb
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-qserdes-txrx.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_H_
+
+/* Only for QMP V2 PHY - TX registers */
+#define QSERDES_TX_BIST_MODE_LANENO 0x000
+#define QSERDES_TX_BIST_INVERT 0x004
+#define QSERDES_TX_CLKBUF_ENABLE 0x008
+#define QSERDES_TX_CMN_CONTROL_ONE 0x00c
+#define QSERDES_TX_CMN_CONTROL_TWO 0x010
+#define QSERDES_TX_CMN_CONTROL_THREE 0x014
+#define QSERDES_TX_TX_EMP_POST1_LVL 0x018
+#define QSERDES_TX_TX_POST2_EMPH 0x01c
+#define QSERDES_TX_TX_BOOST_LVL_UP_DN 0x020
+#define QSERDES_TX_HP_PD_ENABLES 0x024
+#define QSERDES_TX_TX_IDLE_LVL_LARGE_AMP 0x028
+#define QSERDES_TX_TX_DRV_LVL 0x02c
+#define QSERDES_TX_TX_DRV_LVL_OFFSET 0x030
+#define QSERDES_TX_RESET_TSYNC_EN 0x034
+#define QSERDES_TX_PRE_STALL_LDO_BOOST_EN 0x038
+#define QSERDES_TX_TX_BAND 0x03c
+#define QSERDES_TX_SLEW_CNTL 0x040
+#define QSERDES_TX_INTERFACE_SELECT 0x044
+#define QSERDES_TX_LPB_EN 0x048
+#define QSERDES_TX_RES_CODE_LANE_TX 0x04c
+#define QSERDES_TX_RES_CODE_LANE_RX 0x050
+#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
+#define QSERDES_TX_PERL_LENGTH1 0x058
+#define QSERDES_TX_PERL_LENGTH2 0x05c
+#define QSERDES_TX_SERDES_BYP_EN_OUT 0x060
+#define QSERDES_TX_DEBUG_BUS_SEL 0x064
+#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
+#define QSERDES_TX_TX_POL_INV 0x06c
+#define QSERDES_TX_PARRATE_REC_DETECT_IDLE_EN 0x070
+#define QSERDES_TX_BIST_PATTERN1 0x074
+#define QSERDES_TX_BIST_PATTERN2 0x078
+#define QSERDES_TX_BIST_PATTERN3 0x07c
+#define QSERDES_TX_BIST_PATTERN4 0x080
+#define QSERDES_TX_BIST_PATTERN5 0x084
+#define QSERDES_TX_BIST_PATTERN6 0x088
+#define QSERDES_TX_BIST_PATTERN7 0x08c
+#define QSERDES_TX_BIST_PATTERN8 0x090
+#define QSERDES_TX_LANE_MODE 0x094
+#define QSERDES_TX_IDAC_CAL_LANE_MODE 0x098
+#define QSERDES_TX_IDAC_CAL_LANE_MODE_CONFIGURATION 0x09c
+#define QSERDES_TX_ATB_SEL1 0x0a0
+#define QSERDES_TX_ATB_SEL2 0x0a4
+#define QSERDES_TX_RCV_DETECT_LVL 0x0a8
+#define QSERDES_TX_RCV_DETECT_LVL_2 0x0ac
+#define QSERDES_TX_PRBS_SEED1 0x0b0
+#define QSERDES_TX_PRBS_SEED2 0x0b4
+#define QSERDES_TX_PRBS_SEED3 0x0b8
+#define QSERDES_TX_PRBS_SEED4 0x0bc
+#define QSERDES_TX_RESET_GEN 0x0c0
+#define QSERDES_TX_RESET_GEN_MUXES 0x0c4
+#define QSERDES_TX_TRAN_DRVR_EMP_EN 0x0c8
+#define QSERDES_TX_TX_INTERFACE_MODE 0x0cc
+#define QSERDES_TX_PWM_CTRL 0x0d0
+#define QSERDES_TX_PWM_ENCODED_OR_DATA 0x0d4
+#define QSERDES_TX_PWM_GEAR_1_DIVIDER_BAND2 0x0d8
+#define QSERDES_TX_PWM_GEAR_2_DIVIDER_BAND2 0x0dc
+#define QSERDES_TX_PWM_GEAR_3_DIVIDER_BAND2 0x0e0
+#define QSERDES_TX_PWM_GEAR_4_DIVIDER_BAND2 0x0e4
+#define QSERDES_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0x0e8
+#define QSERDES_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0x0ec
+#define QSERDES_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0x0f0
+#define QSERDES_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0x0f4
+#define QSERDES_TX_VMODE_CTRL1 0x0f8
+#define QSERDES_TX_VMODE_CTRL2 0x0fc
+#define QSERDES_TX_TX_ALOG_INTF_OBSV_CNTL 0x100
+#define QSERDES_TX_BIST_STATUS 0x104
+#define QSERDES_TX_BIST_ERROR_COUNT1 0x108
+#define QSERDES_TX_BIST_ERROR_COUNT2 0x10c
+#define QSERDES_TX_TX_ALOG_INTF_OBSV 0x110
+
+/* Only for QMP V2 PHY - RX registers */
+#define QSERDES_RX_UCDR_FO_GAIN_HALF 0x000
+#define QSERDES_RX_UCDR_FO_GAIN_QUARTER 0x004
+#define QSERDES_RX_UCDR_FO_GAIN_EIGHTH 0x008
+#define QSERDES_RX_UCDR_FO_GAIN 0x00c
+#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x010
+#define QSERDES_RX_UCDR_SO_GAIN_QUARTER 0x014
+#define QSERDES_RX_UCDR_SO_GAIN_EIGHTH 0x018
+#define QSERDES_RX_UCDR_SO_GAIN 0x01c
+#define QSERDES_RX_UCDR_SVS_FO_GAIN_HALF 0x020
+#define QSERDES_RX_UCDR_SVS_FO_GAIN_QUARTER 0x024
+#define QSERDES_RX_UCDR_SVS_FO_GAIN_EIGHTH 0x028
+#define QSERDES_RX_UCDR_SVS_FO_GAIN 0x02c
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_HALF 0x030
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER 0x034
+#define QSERDES_RX_UCDR_SVS_SO_GAIN_EIGHTH 0x038
+#define QSERDES_RX_UCDR_SVS_SO_GAIN 0x03c
+#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x040
+#define QSERDES_RX_UCDR_FD_GAIN 0x044
+#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x048
+#define QSERDES_RX_UCDR_FO_TO_SO_DELAY 0x04c
+#define QSERDES_RX_UCDR_FASTLOCK_COUNT_LOW 0x050
+#define QSERDES_RX_UCDR_FASTLOCK_COUNT_HIGH 0x054
+#define QSERDES_RX_UCDR_MODULATE 0x058
+#define QSERDES_RX_UCDR_PI_CONTROLS 0x05c
+#define QSERDES_RX_RBIST_CONTROL 0x060
+#define QSERDES_RX_AUX_CONTROL 0x064
+#define QSERDES_RX_AUX_DATA_TCOARSE 0x068
+#define QSERDES_RX_AUX_DATA_TFINE_LSB 0x06c
+#define QSERDES_RX_AUX_DATA_TFINE_MSB 0x070
+#define QSERDES_RX_RCLK_AUXDATA_SEL 0x074
+#define QSERDES_RX_AC_JTAG_ENABLE 0x078
+#define QSERDES_RX_AC_JTAG_INITP 0x07c
+#define QSERDES_RX_AC_JTAG_INITN 0x080
+#define QSERDES_RX_AC_JTAG_LVL 0x084
+#define QSERDES_RX_AC_JTAG_MODE 0x088
+#define QSERDES_RX_AC_JTAG_RESET 0x08c
+#define QSERDES_RX_RX_TERM_BW 0x090
+#define QSERDES_RX_RX_RCVR_IQ_EN 0x094
+#define QSERDES_RX_RX_IDAC_I_DC_OFFSETS 0x098
+#define QSERDES_RX_RX_IDAC_IBAR_DC_OFFSETS 0x09c
+#define QSERDES_RX_RX_IDAC_Q_DC_OFFSETS 0x0a0
+#define QSERDES_RX_RX_IDAC_QBAR_DC_OFFSETS 0x0a4
+#define QSERDES_RX_RX_IDAC_A_DC_OFFSETS 0x0a8
+#define QSERDES_RX_RX_IDAC_ABAR_DC_OFFSETS 0x0ac
+#define QSERDES_RX_RX_IDAC_EN 0x0b0
+#define QSERDES_RX_RX_IDAC_ENABLES 0x0b4
+#define QSERDES_RX_RX_IDAC_SIGN 0x0b8
+#define QSERDES_RX_RX_HIGHZ_HIGHRATE 0x0bc
+#define QSERDES_RX_RX_TERM_AC_BYPASS_DC_COUPLE_OFFSET 0x0c0
+#define QSERDES_RX_RX_EQ_GAIN1_LSB 0x0c4
+#define QSERDES_RX_RX_EQ_GAIN1_MSB 0x0c8
+#define QSERDES_RX_RX_EQ_GAIN2_LSB 0x0cc
+#define QSERDES_RX_RX_EQ_GAIN2_MSB 0x0d0
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d4
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d8
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x0dc
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x0e0
+#define QSERDES_RX_RX_IDAC_CAL_CONFIGURATION 0x0e4
+#define QSERDES_RX_RX_IDAC_TSETTLE_LOW 0x0e8
+#define QSERDES_RX_RX_IDAC_TSETTLE_HIGH 0x0ec
+#define QSERDES_RX_RX_IDAC_ENDSAMP_LOW 0x0f0
+#define QSERDES_RX_RX_IDAC_ENDSAMP_HIGH 0x0f4
+#define QSERDES_RX_RX_IDAC_MIDPOINT_LOW 0x0f8
+#define QSERDES_RX_RX_IDAC_MIDPOINT_HIGH 0x0fc
+#define QSERDES_RX_RX_EQ_OFFSET_LSB 0x100
+#define QSERDES_RX_RX_EQ_OFFSET_MSB 0x104
+#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x108
+#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x10c
+#define QSERDES_RX_SIGDET_ENABLES 0x110
+#define QSERDES_RX_SIGDET_CNTRL 0x114
+#define QSERDES_RX_SIGDET_LVL 0x118
+#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x11c
+#define QSERDES_RX_RX_BAND 0x120
+#define QSERDES_RX_CDR_FREEZE_UP_DN 0x124
+#define QSERDES_RX_CDR_RESET_OVERRIDE 0x128
+#define QSERDES_RX_RX_INTERFACE_MODE 0x12c
+#define QSERDES_RX_JITTER_GEN_MODE 0x130
+#define QSERDES_RX_BUJ_AMP 0x134
+#define QSERDES_RX_SJ_AMP1 0x138
+#define QSERDES_RX_SJ_AMP2 0x13c
+#define QSERDES_RX_SJ_PER1 0x140
+#define QSERDES_RX_SJ_PER2 0x144
+#define QSERDES_RX_BUJ_STEP_FREQ1 0x148
+#define QSERDES_RX_BUJ_STEP_FREQ2 0x14c
+#define QSERDES_RX_PPM_OFFSET1 0x150
+#define QSERDES_RX_PPM_OFFSET2 0x154
+#define QSERDES_RX_SIGN_PPM_PERIOD1 0x158
+#define QSERDES_RX_SIGN_PPM_PERIOD2 0x15c
+#define QSERDES_RX_SSC_CTRL 0x160
+#define QSERDES_RX_SSC_COUNT1 0x164
+#define QSERDES_RX_SSC_COUNT2 0x168
+#define QSERDES_RX_RX_ALOG_INTF_OBSV_CNTL 0x16c
+#define QSERDES_RX_RX_PWM_ENABLE_AND_DATA 0x170
+#define QSERDES_RX_RX_PWM_GEAR1_TIMEOUT_COUNT 0x174
+#define QSERDES_RX_RX_PWM_GEAR2_TIMEOUT_COUNT 0x178
+#define QSERDES_RX_RX_PWM_GEAR3_TIMEOUT_COUNT 0x17c
+#define QSERDES_RX_RX_PWM_GEAR4_TIMEOUT_COUNT 0x180
+#define QSERDES_RX_PI_CTRL1 0x184
+#define QSERDES_RX_PI_CTRL2 0x188
+#define QSERDES_RX_PI_QUAD 0x18c
+#define QSERDES_RX_IDATA1 0x190
+#define QSERDES_RX_IDATA2 0x194
+#define QSERDES_RX_AUX_DATA1 0x198
+#define QSERDES_RX_AUX_DATA2 0x19c
+#define QSERDES_RX_AC_JTAG_OUTP 0x1a0
+#define QSERDES_RX_AC_JTAG_OUTN 0x1a4
+#define QSERDES_RX_RX_SIGDET 0x1a8
+#define QSERDES_RX_RX_VDCOFF 0x1ac
+#define QSERDES_RX_IDAC_CAL_ON 0x1b0
+#define QSERDES_RX_IDAC_STATUS_I 0x1b4
+#define QSERDES_RX_IDAC_STATUS_IBAR 0x1b8
+#define QSERDES_RX_IDAC_STATUS_Q 0x1bc
+#define QSERDES_RX_IDAC_STATUS_QBAR 0x1c0
+#define QSERDES_RX_IDAC_STATUS_A 0x1c4
+#define QSERDES_RX_IDAC_STATUS_ABAR 0x1c8
+#define QSERDES_RX_CALST_STATUS_I 0x1cc
+#define QSERDES_RX_CALST_STATUS_Q 0x1d0
+#define QSERDES_RX_CALST_STATUS_A 0x1d4
+#define QSERDES_RX_RX_ALOG_INTF_OBSV 0x1d8
+#define QSERDES_RX_READ_EQCODE 0x1dc
+#define QSERDES_RX_READ_OFFSETCODE 0x1e0
+#define QSERDES_RX_IA_ERROR_COUNTER_LOW 0x1e4
+#define QSERDES_RX_IA_ERROR_COUNTER_HIGH 0x1e8
+
+#endif
diff --git a/drivers/phy/qcom/phy-qcom-qmp-ufs.c b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
new file mode 100644
index 00000000000..8908a34df54
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
@@ -0,0 +1,1116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2023-2024 Linaro Limited
+ * Authors:
+ * - Bhupesh Sharma <bhupesh.sharma@linaro.org>
+ * - Neil Armstrong <neil.armstrong@linaro.org>
+ *
+ * Based on Linux driver
+ */
+
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <generic-phy.h>
+#include <malloc.h>
+#include <reset.h>
+
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+
+#include "phy-qcom-qmp.h"
+#include "phy-qcom-qmp-pcs-ufs-v2.h"
+#include "phy-qcom-qmp-pcs-ufs-v3.h"
+#include "phy-qcom-qmp-pcs-ufs-v4.h"
+#include "phy-qcom-qmp-pcs-ufs-v5.h"
+#include "phy-qcom-qmp-pcs-ufs-v6.h"
+
+#include "phy-qcom-qmp-qserdes-com-v4.h"
+#include "phy-qcom-qmp-qserdes-com-v6.h"
+#include "phy-qcom-qmp-qserdes-txrx-v4.h"
+#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
+
+/* QPHY_SW_RESET bit */
+#define SW_RESET BIT(0)
+/* QPHY_POWER_DOWN_CONTROL */
+#define SW_PWRDN BIT(0)
+/* QPHY_START_CONTROL bits */
+#define SERDES_START BIT(0)
+#define PCS_START BIT(1)
+/* QPHY_PCS_READY_STATUS bit */
+#define PCS_READY BIT(0)
+
+#define PHY_INIT_COMPLETE_TIMEOUT (200 * 10000)
+
+struct qmp_ufs_init_tbl {
+ unsigned int offset;
+ unsigned int val;
+ /*
+ * mask of lanes for which this register is written
+ * for cases when second lane needs different values
+ */
+ u8 lane_mask;
+};
+
+#define QMP_PHY_INIT_CFG(o, v) \
+ { \
+ .offset = o, \
+ .val = v, \
+ .lane_mask = 0xff, \
+ }
+
+#define QMP_PHY_INIT_CFG_LANE(o, v, l) \
+ { \
+ .offset = o, \
+ .val = v, \
+ .lane_mask = l, \
+ }
+
+/* set of registers with offsets different per-PHY */
+enum qphy_reg_layout {
+ /* PCS registers */
+ QPHY_SW_RESET,
+ QPHY_START_CTRL,
+ QPHY_PCS_READY_STATUS,
+ QPHY_PCS_POWER_DOWN_CONTROL,
+ /* Keep last to ensure regs_layout arrays are properly initialized */
+ QPHY_LAYOUT_SIZE
+};
+
+static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const unsigned int ufsphy_v4_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V4_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_UFS_READY_STATUS,
+ [QPHY_SW_RESET] = QPHY_V4_PCS_UFS_SW_RESET,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V6_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V6_PCS_UFS_READY_STATUS,
+ [QPHY_SW_RESET] = QPHY_V6_PCS_UFS_SW_RESET,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
+static const struct qmp_ufs_init_tbl sdm845_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
+};
+
+static const struct qmp_ufs_init_tbl sdm845_ufsphy_hs_b_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_ufs_init_tbl sdm845_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
+};
+
+static const struct qmp_ufs_init_tbl sdm845_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
+};
+
+static const struct qmp_ufs_init_tbl sdm845_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
+ QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_b_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+};
+
+static const struct qmp_ufs_init_tbl sm8150_ufsphy_hs_g4_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_BIST_FIXED_PAT_CTRL, 0x0a),
+};
+
+static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xe5),
+};
+
+static const struct qmp_ufs_init_tbl sm8250_ufsphy_hs_g4_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x81),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x6f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x2c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x6d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xed),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x3c),
+};
+
+static const struct qmp_ufs_init_tbl sm8550_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
+};
+
+static const struct qmp_ufs_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_ufs_init_tbl sm8550_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
+};
+
+static const struct qmp_ufs_init_tbl sm8550_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
+
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
+
+};
+
+static const struct qmp_ufs_init_tbl sm8550_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
+};
+
+static const struct qmp_ufs_init_tbl sm8650_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
+};
+
+static const struct qmp_ufs_init_tbl sm8650_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e),
+};
+
+static const struct qmp_ufs_init_tbl sm8650_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B1, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B2, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_SATURATION, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_TERM_BW_CTRL0, 0xfa),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
+};
+
+static const struct qmp_ufs_init_tbl sm8650_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PCS_CTRL1, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S4, 0x0e),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S5, 0x12),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S6, 0x15),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_POST_EMP_LVL_S7, 0x19),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4d),
+ QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
+};
+
+struct qmp_ufs_offsets {
+ u16 serdes;
+ u16 pcs;
+ u16 tx;
+ u16 rx;
+ /* for PHYs with >= 2 lanes */
+ u16 tx2;
+ u16 rx2;
+};
+
+struct qmp_ufs_cfg_tbls {
+ /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
+ const struct qmp_ufs_init_tbl *serdes;
+ int serdes_num;
+ const struct qmp_ufs_init_tbl *tx;
+ int tx_num;
+ const struct qmp_ufs_init_tbl *rx;
+ int rx_num;
+ const struct qmp_ufs_init_tbl *pcs;
+ int pcs_num;
+};
+
+/* struct qmp_ufs_cfg - per-PHY initialization config */
+struct qmp_ufs_cfg {
+ int lanes;
+
+ const struct qmp_ufs_offsets *offsets;
+
+ /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
+ const struct qmp_ufs_cfg_tbls tbls;
+ /* Additional sequence for HS Series B */
+ const struct qmp_ufs_cfg_tbls tbls_hs_b;
+ /* Additional sequence for HS G4 */
+ const struct qmp_ufs_cfg_tbls tbls_hs_g4;
+
+ /* clock ids to be requested */
+ const char * const *clk_list;
+ int num_clks;
+ /* regulators to be requested */
+ const char * const *vreg_list;
+ int num_vregs;
+ /* resets to be requested */
+ const char * const *reset_list;
+ int num_resets;
+
+ /* array of registers with different offsets */
+ const unsigned int *regs;
+
+ /* true, if PCS block has no separate SW_RESET register */
+ bool no_pcs_sw_reset;
+};
+
+struct qmp_ufs_priv {
+ struct phy *phy;
+
+ void __iomem *serdes;
+ void __iomem *pcs;
+ void __iomem *pcs_misc;
+ void __iomem *tx;
+ void __iomem *rx;
+ void __iomem *tx2;
+ void __iomem *rx2;
+
+ struct clk *clks;
+ unsigned int clk_count;
+
+ struct reset_ctl *resets;
+ unsigned int reset_count;
+
+ const struct qmp_ufs_cfg *cfg;
+
+ struct udevice *dev;
+
+ u32 mode;
+ u32 submode;
+};
+
+static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
+{
+ u32 reg;
+
+ reg = readl(base + offset);
+ reg |= val;
+ writel(reg, base + offset);
+
+ /* ensure that above write is through */
+ readl(base + offset);
+}
+
+static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+ u32 reg;
+
+ reg = readl(base + offset);
+ reg &= ~val;
+ writel(reg, base + offset);
+
+ /* ensure that above write is through */
+ readl(base + offset);
+}
+
+/* list of clocks required by phy */
+static const char * const sdm845_ufs_phy_clk_l[] = {
+ "ref", "ref_aux",
+};
+
+/* list of regulators */
+static const char * const qmp_ufs_vreg_l[] = {
+ "vdda-phy", "vdda-pll",
+};
+
+/* list of resets */
+static const char * const qmp_ufs_reset_l[] = {
+ "ufsphy",
+};
+
+static const struct qmp_ufs_offsets qmp_ufs_offsets = {
+ .serdes = 0,
+ .pcs = 0xc00,
+ .tx = 0x400,
+ .rx = 0x600,
+ .tx2 = 0x800,
+ .rx2 = 0xa00,
+};
+
+static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
+ .serdes = 0,
+ .pcs = 0x0400,
+ .tx = 0x1000,
+ .rx = 0x1200,
+ .tx2 = 0x1800,
+ .rx2 = 0x1a00,
+};
+
+static const struct qmp_ufs_cfg sdm845_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets,
+
+ .tbls = {
+ .serdes = sdm845_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes),
+ .tx = sdm845_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx),
+ .rx = sdm845_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sdm845_ufsphy_rx),
+ .pcs = sdm845_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sdm845_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sdm845_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_ufs_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
+ .regs = ufsphy_v3_regs_layout,
+
+ .no_pcs_sw_reset = true,
+};
+
+static const struct qmp_ufs_cfg sm8250_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets,
+
+ .tbls = {
+ .serdes = sm8150_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_serdes),
+ .tx = sm8150_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8150_ufsphy_tx),
+ .rx = sm8150_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8150_ufsphy_rx),
+ .pcs = sm8150_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8150_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8150_ufsphy_hs_b_serdes),
+ },
+ .tbls_hs_g4 = {
+ .tx = sm8250_ufsphy_hs_g4_tx,
+ .tx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_tx),
+ .rx = sm8250_ufsphy_hs_g4_rx,
+ .rx_num = ARRAY_SIZE(sm8250_ufsphy_hs_g4_rx),
+ .pcs = sm8150_ufsphy_hs_g4_pcs,
+ .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_ufs_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
+ .reset_list = qmp_ufs_reset_l,
+ .num_resets = ARRAY_SIZE(qmp_ufs_reset_l),
+ .regs = ufsphy_v4_regs_layout,
+
+ .no_pcs_sw_reset = false,
+};
+
+static const struct qmp_ufs_cfg sm8550_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets_v6,
+
+ .tbls = {
+ .serdes = sm8550_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8550_ufsphy_serdes),
+ .tx = sm8550_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8550_ufsphy_tx),
+ .rx = sm8550_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8550_ufsphy_rx),
+ .pcs = sm8550_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8550_ufsphy_pcs),
+ },
+ .tbls_hs_b = {
+ .serdes = sm8550_ufsphy_hs_b_serdes,
+ .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_ufs_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
+ .regs = ufsphy_v6_regs_layout,
+
+ .no_pcs_sw_reset = false,
+};
+
+static const struct qmp_ufs_cfg sm8650_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets_v6,
+
+ .tbls = {
+ .serdes = sm8650_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(sm8650_ufsphy_serdes),
+ .tx = sm8650_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(sm8650_ufsphy_tx),
+ .rx = sm8650_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(sm8650_ufsphy_rx),
+ .pcs = sm8650_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(sm8650_ufsphy_pcs),
+ },
+ .clk_list = sdm845_ufs_phy_clk_l,
+ .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
+ .vreg_list = qmp_ufs_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l),
+ .regs = ufsphy_v6_regs_layout,
+
+ .no_pcs_sw_reset = false,
+};
+
+static void qmp_ufs_configure_lane(void __iomem *base,
+ const struct qmp_ufs_init_tbl tbl[],
+ int num,
+ u8 lane_mask)
+{
+ int i;
+ const struct qmp_ufs_init_tbl *t = tbl;
+
+ if (!t)
+ return;
+
+ for (i = 0; i < num; i++, t++) {
+ if (!(t->lane_mask & lane_mask))
+ continue;
+
+ writel(t->val, base + t->offset);
+ }
+}
+
+static void qmp_ufs_configure(void __iomem *base,
+ const struct qmp_ufs_init_tbl tbl[],
+ int num)
+{
+ qmp_ufs_configure_lane(base, tbl, num, 0xff);
+}
+
+static void qmp_ufs_serdes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
+{
+ void __iomem *serdes = qmp->serdes;
+
+ qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num);
+}
+
+static void qmp_ufs_lanes_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
+{
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+ void __iomem *tx = qmp->tx;
+ void __iomem *rx = qmp->rx;
+
+ qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
+ qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
+
+ if (cfg->lanes >= 2) {
+ qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2);
+ qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2);
+ }
+}
+
+static void qmp_ufs_pcs_init(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg_tbls *tbls)
+{
+ void __iomem *pcs = qmp->pcs;
+
+ qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num);
+}
+
+static void qmp_ufs_init_registers(struct qmp_ufs_priv *qmp, const struct qmp_ufs_cfg *cfg)
+{
+ /* We support 'PHY_MODE_UFS_HS_B' mode & 'UFS_HS_G3' submode for now. */
+ qmp_ufs_serdes_init(qmp, &cfg->tbls);
+ qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
+ qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
+ qmp_ufs_lanes_init(qmp, &cfg->tbls);
+ qmp_ufs_pcs_init(qmp, &cfg->tbls);
+}
+
+static int qmp_ufs_do_reset(struct qmp_ufs_priv *qmp)
+{
+ int i, ret;
+
+ for (i = 0; i < qmp->reset_count; i++) {
+ ret = reset_assert(&qmp->resets[i]);
+ if (ret)
+ return ret;
+ }
+
+ udelay(10);
+
+ for (i = 0; i < qmp->reset_count; i++) {
+ ret = reset_deassert(&qmp->resets[i]);
+ if (ret)
+ return ret;
+ }
+
+ udelay(50);
+
+ return 0;
+}
+
+static int qmp_ufs_power_on(struct phy *phy)
+{
+ struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+ void __iomem *pcs = qmp->pcs;
+ void __iomem *status;
+ unsigned int val;
+ int ret;
+
+ /* Power down PHY */
+ qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
+
+ qmp_ufs_init_registers(qmp, cfg);
+
+ if (cfg->no_pcs_sw_reset) {
+ ret = qmp_ufs_do_reset(qmp);
+ if (ret) {
+ dev_err(phy->dev, "qmp reset failed\n");
+ return ret;
+ }
+ }
+
+ /* Pull PHY out of reset state */
+ if (!cfg->no_pcs_sw_reset)
+ qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+
+ /* start SerDes */
+ qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START);
+
+ status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
+ ret = readl_poll_timeout(status, val, (val & PCS_READY), PHY_INIT_COMPLETE_TIMEOUT);
+ if (ret) {
+ dev_err(phy->dev, "phy initialization timed-out\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qmp_ufs_power_off(struct phy *phy)
+{
+ struct qmp_ufs_priv *qmp = dev_get_priv(phy->dev);
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+
+ /* PHY reset */
+ qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+
+ /* stop SerDes and Phy-Coding-Sublayer */
+ qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
+ SERDES_START | PCS_START);
+
+ /* Put PHY into POWER DOWN state: active low */
+ qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+ SW_PWRDN);
+
+ clk_release_all(qmp->clks, qmp->clk_count);
+
+ return 0;
+}
+
+static int qmp_ufs_vreg_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
+{
+ /* TOFIX: Add regulator support, but they should be voted at boot time already */
+
+ return 0;
+}
+
+static int qmp_ufs_reset_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
+{
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+ int num = cfg->num_resets;
+ int i, ret;
+
+ qmp->reset_count = 0;
+ qmp->resets = devm_kcalloc(dev, num, sizeof(*qmp->resets), GFP_KERNEL);
+ if (!qmp->resets)
+ return -ENOMEM;
+
+ for (i = 0; i < num; i++) {
+ ret = reset_get_by_index(dev, i, &qmp->resets[i]);
+ if (ret < 0) {
+ dev_err(dev, "failed to get reset %d\n", i);
+ goto reset_get_err;
+ }
+
+ ++qmp->reset_count;
+ }
+
+ return 0;
+
+reset_get_err:
+ ret = reset_release_all(qmp->resets, qmp->reset_count);
+ if (ret)
+ dev_warn(dev, "failed to disable all resets\n");
+
+ return ret;
+}
+
+static int qmp_ufs_clk_init(struct udevice *dev, struct qmp_ufs_priv *qmp)
+{
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+ int num = cfg->num_clks;
+ int i, ret;
+
+ qmp->clk_count = 0;
+ qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
+ if (!qmp->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < num; i++) {
+ ret = clk_get_by_index(dev, i, &qmp->clks[i]);
+ if (ret < 0)
+ goto clk_get_err;
+
+ ret = clk_enable(&qmp->clks[i]);
+ if (ret && ret != -ENOSYS) {
+ dev_err(dev, "failed to enable clock %d\n", i);
+ goto clk_get_err;
+ }
+
+ ++qmp->clk_count;
+ }
+
+ return 0;
+
+clk_get_err:
+ ret = clk_release_all(qmp->clks, qmp->clk_count);
+ if (ret)
+ dev_warn(dev, "failed to disable all clocks\n");
+
+ return ret;
+}
+
+static int qmp_ufs_probe_generic_child(struct udevice *dev,
+ ofnode child)
+{
+ struct qmp_ufs_priv *qmp = dev_get_priv(dev);
+ const struct qmp_ufs_cfg *cfg = qmp->cfg;
+ struct resource res;
+ int ret;
+
+ /*
+ * Get memory resources for the PHY:
+ * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
+ * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
+ * For single lane PHYs: pcs_misc (optional) -> 3.
+ */
+ ret = ofnode_read_resource(child, 0, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property of child %s\n",
+ ofnode_get_name(child));
+ return ret;
+ }
+
+ qmp->tx = (void __iomem *)res.start;
+
+ ret = ofnode_read_resource(child, 1, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property of child %s\n",
+ ofnode_get_name(child));
+ return ret;
+ }
+
+ qmp->rx = (void __iomem *)res.start;
+
+ ret = ofnode_read_resource(child, 2, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property of child %s\n",
+ ofnode_get_name(child));
+ return ret;
+ }
+
+ qmp->pcs = (void __iomem *)res.start;
+
+ if (cfg->lanes >= 2) {
+ ret = ofnode_read_resource(child, 3, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property of child %s\n",
+ ofnode_get_name(child));
+ return ret;
+ }
+
+ qmp->tx2 = (void __iomem *)res.start;
+
+ ret = ofnode_read_resource(child, 4, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property of child %s\n",
+ ofnode_get_name(child));
+ return ret;
+ }
+
+ qmp->rx2 = (void __iomem *)res.start;
+
+ ret = ofnode_read_resource(child, 5, &res);
+ if (ret)
+ qmp->pcs_misc = NULL;
+ } else {
+ ret = ofnode_read_resource(child, 3, &res);
+ if (ret)
+ qmp->pcs_misc = NULL;
+ }
+
+ return 0;
+}
+
+static int qmp_ufs_probe_dt_children(struct udevice *dev)
+{
+ int ret;
+ ofnode child;
+
+ ofnode_for_each_subnode(child, dev_ofnode(dev)) {
+ ret = qmp_ufs_probe_generic_child(dev, child);
+ if (ret) {
+ dev_err(dev, "Cannot parse child %s:%d\n",
+ ofnode_get_name(child), ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int qmp_ufs_probe(struct udevice *dev)
+{
+ struct qmp_ufs_priv *qmp = dev_get_priv(dev);
+ int ret;
+
+ qmp->serdes = (void __iomem *)dev_read_addr(dev);
+ if (IS_ERR(qmp->serdes))
+ return PTR_ERR(qmp->serdes);
+
+ qmp->cfg = (const struct qmp_ufs_cfg *)dev_get_driver_data(dev);
+ if (!qmp->cfg)
+ return -EINVAL;
+
+ ret = qmp_ufs_clk_init(dev, qmp);
+ if (ret) {
+ dev_err(dev, "failed to get UFS clks\n");
+ return ret;
+ }
+
+ ret = qmp_ufs_vreg_init(dev, qmp);
+ if (ret) {
+ dev_err(dev, "failed to get UFS voltage regulators\n");
+ return ret;
+ }
+
+ if (qmp->cfg->no_pcs_sw_reset) {
+ ret = qmp_ufs_reset_init(dev, qmp);
+ if (ret) {
+ dev_err(dev, "failed to get UFS resets\n");
+ return ret;
+ }
+ }
+
+ qmp->dev = dev;
+
+ if (ofnode_get_child_count(dev_ofnode(dev))) {
+ ret = qmp_ufs_probe_dt_children(dev);
+ if (ret) {
+ dev_err(dev, "failed to get UFS dt regs\n");
+ return ret;
+ }
+ } else {
+ const struct qmp_ufs_offsets *offs = qmp->cfg->offsets;
+ struct resource res;
+
+ if (!qmp->cfg->offsets) {
+ dev_err(dev, "missing UFS offsets\n");
+ return -EINVAL;
+ }
+
+ ret = ofnode_read_resource(dev_ofnode(dev), 0, &res);
+ if (ret) {
+ dev_err(dev, "can't get reg property\n");
+ return ret;
+ }
+
+ qmp->serdes = (void __iomem *)res.start + offs->serdes;
+ qmp->pcs = (void __iomem *)res.start + offs->pcs;
+ qmp->tx = (void __iomem *)res.start + offs->tx;
+ qmp->rx = (void __iomem *)res.start + offs->rx;
+
+ if (qmp->cfg->lanes >= 2) {
+ qmp->tx2 = (void __iomem *)res.start + offs->tx2;
+ qmp->rx2 = (void __iomem *)res.start + offs->rx2;
+ }
+ }
+
+ return 0;
+}
+
+static struct phy_ops qmp_ufs_ops = {
+ .power_on = qmp_ufs_power_on,
+ .power_off = qmp_ufs_power_off,
+};
+
+static const struct udevice_id qmp_ufs_ids[] = {
+ { .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
+ { .compatible = "qcom,sm8250-qmp-ufs-phy", .data = (ulong)&sm8250_ufsphy_cfg },
+ { .compatible = "qcom,sm8550-qmp-ufs-phy", .data = (ulong)&sm8550_ufsphy_cfg },
+ { .compatible = "qcom,sm8650-qmp-ufs-phy", .data = (ulong)&sm8650_ufsphy_cfg },
+ { }
+};
+
+U_BOOT_DRIVER(qcom_qmp_ufs) = {
+ .name = "qcom-qmp-ufs",
+ .id = UCLASS_PHY,
+ .of_match = qmp_ufs_ids,
+ .ops = &qmp_ufs_ops,
+ .probe = qmp_ufs_probe,
+ .priv_auto = sizeof(struct qmp_ufs_priv),
+};
diff --git a/drivers/phy/qcom/phy-qcom-qmp.h b/drivers/phy/qcom/phy-qcom-qmp.h
new file mode 100644
index 00000000000..99f4d447caf
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qmp.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_H_
+#define QCOM_PHY_QMP_H_
+
+#include "phy-qcom-qmp-qserdes-com.h"
+#include "phy-qcom-qmp-qserdes-txrx.h"
+
+#include "phy-qcom-qmp-qserdes-com-v3.h"
+#include "phy-qcom-qmp-qserdes-txrx-v3.h"
+
+#include "phy-qcom-qmp-qserdes-pll.h"
+
+#include "phy-qcom-qmp-pcs-v2.h"
+
+#include "phy-qcom-qmp-pcs-v3.h"
+
+/* Only for QMP V3 & V4 PHY - DP COM registers */
+#define QPHY_V3_DP_COM_PHY_MODE_CTRL 0x00
+#define QPHY_V3_DP_COM_SW_RESET 0x04
+#define QPHY_V3_DP_COM_POWER_DOWN_CTRL 0x08
+#define QPHY_V3_DP_COM_SWI_CTRL 0x0c
+#define QPHY_V3_DP_COM_TYPEC_CTRL 0x10
+#define QPHY_V3_DP_COM_TYPEC_PWRDN_CTRL 0x14
+#define QPHY_V3_DP_COM_RESET_OVRD_CTRL 0x1c
+
+/* QSERDES V3 COM bits */
+# define QSERDES_V3_COM_BIAS_EN 0x0001
+# define QSERDES_V3_COM_BIAS_EN_MUX 0x0002
+# define QSERDES_V3_COM_CLKBUF_R_EN 0x0004
+# define QSERDES_V3_COM_CLKBUF_L_EN 0x0008
+# define QSERDES_V3_COM_EN_SYSCLK_TX_SEL 0x0010
+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_L 0x0020
+# define QSERDES_V3_COM_CLKBUF_RX_DRIVE_R 0x0040
+
+/* QSERDES V3 TX bits */
+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MASK 0x001f
+# define DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN 0x0020
+# define DP_PHY_TXn_TX_DRV_LVL_MASK 0x001f
+# define DP_PHY_TXn_TX_DRV_LVL_MUX_EN 0x0020
+
+/* QMP PHY - DP PHY registers */
+#define QSERDES_DP_PHY_REVISION_ID0 0x000
+#define QSERDES_DP_PHY_REVISION_ID1 0x004
+#define QSERDES_DP_PHY_REVISION_ID2 0x008
+#define QSERDES_DP_PHY_REVISION_ID3 0x00c
+#define QSERDES_DP_PHY_CFG 0x010
+#define QSERDES_DP_PHY_PD_CTL 0x018
+# define DP_PHY_PD_CTL_PWRDN 0x001
+# define DP_PHY_PD_CTL_PSR_PWRDN 0x002
+# define DP_PHY_PD_CTL_AUX_PWRDN 0x004
+# define DP_PHY_PD_CTL_LANE_0_1_PWRDN 0x008
+# define DP_PHY_PD_CTL_LANE_2_3_PWRDN 0x010
+# define DP_PHY_PD_CTL_PLL_PWRDN 0x020
+# define DP_PHY_PD_CTL_DP_CLAMP_EN 0x040
+#define QSERDES_DP_PHY_MODE 0x01c
+#define QSERDES_DP_PHY_AUX_CFG0 0x020
+#define QSERDES_DP_PHY_AUX_CFG1 0x024
+#define QSERDES_DP_PHY_AUX_CFG2 0x028
+#define QSERDES_DP_PHY_AUX_CFG3 0x02c
+#define QSERDES_DP_PHY_AUX_CFG4 0x030
+#define QSERDES_DP_PHY_AUX_CFG5 0x034
+#define QSERDES_DP_PHY_AUX_CFG6 0x038
+#define QSERDES_DP_PHY_AUX_CFG7 0x03c
+#define QSERDES_DP_PHY_AUX_CFG8 0x040
+#define QSERDES_DP_PHY_AUX_CFG9 0x044
+
+/* Only for QMP V3 PHY - DP PHY registers */
+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK 0x048
+# define PHY_AUX_STOP_ERR_MASK 0x01
+# define PHY_AUX_DEC_ERR_MASK 0x02
+# define PHY_AUX_SYNC_ERR_MASK 0x04
+# define PHY_AUX_ALIGN_ERR_MASK 0x08
+# define PHY_AUX_REQ_ERR_MASK 0x10
+
+#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c
+#define QSERDES_V3_DP_PHY_AUX_BIST_CFG 0x050
+
+#define QSERDES_V3_DP_PHY_VCO_DIV 0x064
+#define QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL 0x06c
+#define QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL 0x088
+
+#define QSERDES_V3_DP_PHY_SPARE0 0x0ac
+#define DP_PHY_SPARE0_MASK 0x0f
+#define DP_PHY_SPARE0_ORIENTATION_INFO_SHIFT 0x04(0x0004)
+
+#define QSERDES_V3_DP_PHY_STATUS 0x0c0
+
+/* Only for QMP V4 PHY - DP PHY registers */
+#define QSERDES_V4_DP_PHY_CFG_1 0x014
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK 0x054
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR 0x058
+#define QSERDES_V4_DP_PHY_VCO_DIV 0x070
+#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL 0x078
+#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL 0x09c
+#define QSERDES_V4_DP_PHY_SPARE0 0x0c8
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS 0x0d8
+#define QSERDES_V4_DP_PHY_STATUS 0x0dc
+
+/* Only for QMP V4 PHY - PCS_MISC registers */
+#define QPHY_V4_PCS_MISC_TYPEC_CTRL 0x00
+#define QPHY_V4_PCS_MISC_TYPEC_PWRDN_CTRL 0x04
+#define QPHY_V4_PCS_MISC_PCS_MISC_CONFIG1 0x08
+#define QPHY_V4_PCS_MISC_CLAMP_ENABLE 0x0c
+#define QPHY_V4_PCS_MISC_TYPEC_STATUS 0x10
+#define QPHY_V4_PCS_MISC_PLACEHOLDER_STATUS 0x14
+
+/* Only for QMP V6 PHY - DP PHY registers */
+#define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0
+#define QSERDES_V6_DP_PHY_STATUS 0x0e4
+
+#endif
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index b326fa85140..4f93a34281d 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -55,6 +55,13 @@ config PINCTRL_QCOM_SM6115
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_SM8150
+ bool "Qualcomm SM8150 GCC"
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_SM8250
bool "Qualcomm SM8250 GCC"
select PINCTRL_QCOM
@@ -74,6 +81,7 @@ config PINCTRL_QCOM_SM8650
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8650 SoC,
+ as well as the associated GPIO driver.
endmenu
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 4f1d96787be..43d0dd29222 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
+obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
obj-$(CONFIG_PINCTRL_QCOM_SM8250) += pinctrl-sm8250.o
obj-$(CONFIG_PINCTRL_QCOM_SM8550) += pinctrl-sm8550.o
obj-$(CONFIG_PINCTRL_QCOM_SM8650) += pinctrl-sm8650.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8150.c b/drivers/pinctrl/qcom/pinctrl-sm8150.c
new file mode 100644
index 00000000000..1fb2ffb9597
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm8150.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Qualcomm SM8150 pinctrl and GPIO driver
+ *
+ * Volodymyr Babchuk <volodymyr_babchuk@epam.com>
+ * Copyright (c) 2024 EPAM Systems.
+ *
+ * (C) Copyright 2024 Julius Lehmann <lehmanju@devpi.de>
+ *
+ * Based on similar U-Boot drivers. Constants were taken from the Linux driver
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define WEST 0x100000
+#define EAST 0x500000
+#define NORTH 0x900000
+#define SOUTH 0xd00000
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ { "qup2", 1 },
+ { "gpio", 0 },
+};
+
+static const unsigned int sm8150_pin_offsets[] = {
+ [0] = SOUTH, [1] = SOUTH, [2] = SOUTH, [3] = SOUTH,
+ [4] = SOUTH, [5] = SOUTH, [6] = SOUTH, [7] = SOUTH,
+ [8] = NORTH, [9] = NORTH, [10] = NORTH, [11] = NORTH,
+ [12] = NORTH, [13] = NORTH, [14] = NORTH, [15] = NORTH,
+ [16] = NORTH, [17] = NORTH, [18] = NORTH, [19] = NORTH,
+ [20] = NORTH, [21] = EAST, [22] = EAST, [23] = EAST,
+ [24] = EAST, [25] = EAST, [26] = EAST, [27] = EAST,
+ [28] = EAST, [29] = EAST, [30] = EAST, [31] = NORTH,
+ [32] = NORTH, [33] = NORTH, [34] = NORTH, [35] = NORTH,
+ [36] = NORTH, [37] = NORTH, [38] = SOUTH, [39] = NORTH,
+ [40] = NORTH, [41] = NORTH, [42] = NORTH, [43] = EAST,
+ [44] = EAST, [45] = EAST, [46] = EAST, [47] = EAST,
+ [48] = EAST, [49] = EAST, [50] = EAST, [51] = SOUTH,
+ [52] = SOUTH, [53] = SOUTH, [54] = SOUTH, [55] = SOUTH,
+ [56] = SOUTH, [57] = SOUTH, [58] = SOUTH, [59] = SOUTH,
+ [60] = SOUTH, [61] = SOUTH, [62] = SOUTH, [63] = SOUTH,
+ [64] = SOUTH, [65] = SOUTH, [66] = SOUTH, [67] = SOUTH,
+ [68] = SOUTH, [69] = SOUTH, [70] = SOUTH, [71] = SOUTH,
+ [72] = SOUTH, [73] = SOUTH, [74] = SOUTH, [75] = SOUTH,
+ [76] = SOUTH, [77] = SOUTH, [78] = SOUTH, [79] = SOUTH,
+ [80] = SOUTH, [81] = SOUTH, [82] = SOUTH, [83] = NORTH,
+ [84] = NORTH, [85] = NORTH, [86] = NORTH, [87] = EAST,
+ [88] = NORTH, [89] = NORTH, [90] = NORTH, [91] = NORTH,
+ [92] = NORTH, [93] = NORTH, [94] = NORTH, [95] = NORTH,
+ [96] = NORTH, [97] = NORTH, [98] = SOUTH, [99] = SOUTH,
+ [100] = SOUTH, [101] = SOUTH, [102] = NORTH, [103] = NORTH,
+ [104] = NORTH, [105] = WEST, [106] = WEST, [107] = WEST,
+ [108] = WEST, [109] = WEST, [110] = WEST, [111] = WEST,
+ [112] = WEST, [113] = WEST, [114] = SOUTH, [115] = SOUTH,
+ [116] = SOUTH, [117] = SOUTH, [118] = SOUTH, [119] = SOUTH,
+ [120] = SOUTH, [121] = SOUTH, [122] = SOUTH, [123] = SOUTH,
+ [124] = SOUTH, [125] = WEST, [126] = SOUTH, [127] = SOUTH,
+ [128] = SOUTH, [129] = SOUTH, [130] = SOUTH, [131] = SOUTH,
+ [132] = SOUTH, [133] = SOUTH, [134] = SOUTH, [135] = SOUTH,
+ [136] = SOUTH, [137] = SOUTH, [138] = SOUTH, [139] = SOUTH,
+ [140] = SOUTH, [141] = SOUTH, [142] = SOUTH, [143] = SOUTH,
+ [144] = SOUTH, [145] = SOUTH, [146] = SOUTH, [147] = SOUTH,
+ [148] = SOUTH, [149] = SOUTH, [150] = SOUTH, [151] = SOUTH,
+ [152] = SOUTH, [153] = SOUTH, [154] = SOUTH, [155] = WEST,
+ [156] = WEST, [157] = WEST, [158] = WEST, [159] = WEST,
+ [160] = WEST, [161] = WEST, [162] = WEST, [163] = WEST,
+ [164] = WEST, [165] = WEST, [166] = WEST, [167] = WEST,
+ [168] = WEST, [169] = NORTH, [170] = NORTH, [171] = NORTH,
+ [172] = NORTH, [173] = NORTH, [174] = NORTH,
+};
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ }
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x04, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ }
+
+static const struct msm_special_pin_data msm_special_pins_data[] = {
+ [0] = UFS_RESET("ufs_reset", SOUTH + 0xb6000),
+ [1] = SDC_QDSD_PINGROUP("sdc2_clk", NORTH + 0xb2000, 14, 6),
+ [2] = SDC_QDSD_PINGROUP("sdc2_cmd", NORTH + 0xb2000, 11, 3),
+ [3] = SDC_QDSD_PINGROUP("sdc2_data", NORTH + 0xb2000, 9, 0),
+};
+
+static const char *sm8150_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *sm8150_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector >= 175 && selector <= 178)
+ snprintf(pin_name, MAX_PIN_NAME_LEN,
+ msm_special_pins_data[selector - 175].name);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+
+ return pin_name;
+}
+
+static unsigned int sm8150_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].val;
+}
+
+static struct msm_pinctrl_data sm8150_data = {
+ .pin_data = {
+ .pin_offsets = sm8150_pin_offsets,
+ .pin_count = 179,
+ .special_pins_start = 175,
+ .special_pins_data = msm_special_pins_data,
+ },
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = sm8150_get_function_name,
+ .get_function_mux = sm8150_get_function_mux,
+ .get_pin_name = sm8150_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,sm8150-pinctrl", .data = (ulong)&sm8150_data },
+ { /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(pinctrl_sm8150) = {
+ .name = "pinctrl_sm8150",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+};
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8250.c b/drivers/pinctrl/qcom/pinctrl-sm8250.c
index dac24f11bc2..cab42fa64ed 100644
--- a/drivers/pinctrl/qcom/pinctrl-sm8250.c
+++ b/drivers/pinctrl/qcom/pinctrl-sm8250.c
@@ -18,8 +18,37 @@
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = { { "qup12", 1 },
- { "gpio", 0 },
- { "sdc2_clk", 0 } };
+ { "gpio", 0 }, };
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ }
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x4, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ }
+
+static const struct msm_special_pin_data sm8250_special_pins_data[] = {
+ [0] = UFS_RESET("ufs_reset", SOUTH + 0xb8000),
+ [1] = SDC_PINGROUP("sdc2_clk", NORTH + 0xb7000, 14, 6),
+ [2] = SDC_PINGROUP("sdc2_cmd", NORTH + 0xb7000, 11, 3),
+ [3] = SDC_PINGROUP("sdc2_data", NORTH + 0xb7000, 9, 0),
+};
static const unsigned int sm8250_pin_offsets[] = {
[0] = SOUTH, [1] = SOUTH, [2] = SOUTH, [3] = SOUTH, [4] = NORTH, [5] = NORTH,
@@ -52,7 +81,6 @@ static const unsigned int sm8250_pin_offsets[] = {
[162] = WEST, [163] = WEST, [164] = WEST, [165] = WEST, [166] = WEST, [167] = WEST,
[168] = WEST, [169] = WEST, [170] = WEST, [171] = WEST, [172] = WEST, [173] = WEST,
[174] = WEST, [175] = WEST, [176] = WEST, [177] = WEST, [178] = WEST, [179] = WEST,
- [180] = 0, [181] = 0, [182] = 0, [183] = 0,
};
static const char *sm8250_get_function_name(struct udevice *dev, unsigned int selector)
@@ -62,7 +90,12 @@ static const char *sm8250_get_function_name(struct udevice *dev, unsigned int se
static const char *sm8250_get_pin_name(struct udevice *dev, unsigned int selector)
{
- snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+ if (selector >= 180 && selector <= 183)
+ snprintf(pin_name, MAX_PIN_NAME_LEN,
+ sm8250_special_pins_data[selector - 180].name);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+
return pin_name;
}
@@ -76,6 +109,7 @@ static struct msm_pinctrl_data sm8250_data = {
.pin_offsets = sm8250_pin_offsets,
.pin_count = ARRAY_SIZE(sm8250_pin_offsets),
.special_pins_start = 180,
+ .special_pins_data = sm8250_special_pins_data,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = sm8250_get_function_name,