summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-01-16 15:14:37 -0600
committerTom Rini <[email protected]>2026-01-16 15:14:37 -0600
commitff498a3c5efb424accc1d825cc45cede2540ca13 (patch)
tree390a18b9462e99d6ed961425fd6a71020b22092f /drivers
parentadccdb22ebd799a7d964892d4a7e7454ed3c239c (diff)
parentcd8ee4fff82788546df06fae7bbe6d22a710737b (diff)
Merge branch 'qcom-main' of https://source.denx.de/u-boot/custodians/u-boot-snapdragon
We have been getting a lot more patches from Qualcomm engineers, largely focusing on IoT, router, and automotive platforms (those with QCS, IPQ, and SA prefixes specifically). Quite a variety of changes here: - Watchdog overflow fix - Hardcoded fastboot buffer addresses for a few board (hoppefully temporary until fastboot is updated to read $fastboot_addr_r) - Enable memory protection (MMU_MGPROT) for ARCH_SNAPDRAGON - pinctrl support for the QCS615 soc - various USB/phy fixes including phy config for msm8996/qcs615 - mmc and i2c clock configuration fixes - significant fixes for rpmh and regulator drivers - added config fragment for pixel devices - sa8775p clock fixes - support for "flattened" dwc3 DT that recently landed upstream for sc7280 (qcs6490) and a few other platforms
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/qcom/clock-qcm2290.c29
-rw-r--r--drivers/clk/qcom/clock-sa8775p.c82
-rw-r--r--drivers/clk/qcom/clock-sc7280.c12
-rw-r--r--drivers/i2c/geni_i2c.c4
-rw-r--r--drivers/mmc/msm_sdhci.c40
-rw-r--r--drivers/phy/qcom/phy-qcom-qusb2.c14
-rw-r--r--drivers/phy/qcom/phy-qcom-snps-femto-v2.c2
-rw-r--r--drivers/pinctrl/qcom/Kconfig36
-rw-r--r--drivers/pinctrl/qcom/Makefile1
-rw-r--r--drivers/pinctrl/qcom/pinctrl-qcs615.c473
-rw-r--r--drivers/power/regulator/qcom-rpmh-regulator.c220
-rw-r--r--drivers/smem/msm_smem.c56
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c89
-rw-r--r--drivers/soc/qcom/rpmh.c38
-rw-r--r--drivers/spmi/spmi-msm.c19
-rw-r--r--drivers/usb/dwc3/dwc3-generic.c32
-rw-r--r--drivers/usb/gadget/Kconfig4
-rw-r--r--drivers/watchdog/qcom-wdt.c23
18 files changed, 1105 insertions, 69 deletions
diff --git a/drivers/clk/qcom/clock-qcm2290.c b/drivers/clk/qcom/clock-qcm2290.c
index fad104fb91a..5a599085b50 100644
--- a/drivers/clk/qcom/clock-qcm2290.c
+++ b/drivers/clk/qcom/clock-qcm2290.c
@@ -17,6 +17,8 @@
#define QUPV3_WRAP0_S4_CMD_RCGR 0x1f608
#define SDCC2_APPS_CLK_CMD_RCGR 0x1e00c
+#define SDCC1_APPS_CLK_CMD_RCGR 0x38028
+
static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_AUX2, 1, 384, 15625),
@@ -55,6 +57,25 @@ static const struct pll_vote_clk gpll7_clk = {
.vote_bit = BIT(7),
};
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+ F(144000, CFG_CLK_SRC_CXO, 16, 3, 25),
+ F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
+ F(20000000, CFG_CLK_SRC_GPLL0_AUX2, 5, 1, 3),
+ F(25000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 1, 2),
+ F(50000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
+ F(192000000, CFG_CLK_SRC_GPLL6, 2, 0, 0),
+ F(384000000, CFG_CLK_SRC_GPLL6, 1, 0, 0),
+ {}
+};
+
+static const struct pll_vote_clk gpll6_clk = {
+ .status = 0x6000,
+ .status_bit = BIT(31),
+ .ena_vote = 0x79000,
+ .vote_bit = BIT(7),
+};
+
static const struct gate_clk qcm2290_clks[] = {
GATE_CLK(GCC_AHB2PHY_USB_CLK, 0x1d008, 0x00000001),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1a084, 0x00000001),
@@ -109,8 +130,12 @@ static ulong qcm2290_set_rate(struct clk *clk, ulong rate)
8);
return freq->freq;
case GCC_SDCC1_APPS_CLK:
- /* The firmware turns this on for us and always sets it to this rate */
- return 384000000;
+ clk_enable_gpll0(priv->base, &gpll6_clk);
+ freq = qcom_find_freq(ftbl_gcc_sdcc1_apps_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, SDCC1_APPS_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src,
+ 8);
+ return freq->freq;
default:
return 0;
}
diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
index 527cecf5c82..4957abf6f58 100644
--- a/drivers/clk/qcom/clock-sa8775p.c
+++ b/drivers/clk/qcom/clock-sa8775p.c
@@ -15,8 +15,34 @@
#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
#include "clock-qcom.h"
-#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
-#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0x1b040
+#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0x1b028
+#define USB3_PRIM_PHY_AUX_CMD_RCGR 0x1b06c
+
+#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
+#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
+#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
+#define GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT BIT(13)
+#define GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT BIT(14)
+#define GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT BIT(15)
+
+#define GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT BIT(22)
+#define GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT BIT(23)
+#define GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT BIT(24)
+#define GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT BIT(25)
+#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
+#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
+#define GCC_QUPV3_WRAP1_S6_CLK_ENA_BIT BIT(27)
+
+#define GCC_QUPV3_WRAP2_S0_CLK_ENA_BIT BIT(4)
+#define GCC_QUPV3_WRAP2_S1_CLK_ENA_BIT BIT(5)
+#define GCC_QUPV3_WRAP2_S2_CLK_ENA_BIT BIT(6)
+#define GCC_QUPV3_WRAP2_S3_CLK_ENA_BIT BIT(7)
+#define GCC_QUPV3_WRAP2_S4_CLK_ENA_BIT BIT(8)
+#define GCC_QUPV3_WRAP2_S5_CLK_ENA_BIT BIT(9)
+#define GCC_QUPV3_WRAP2_S6_CLK_ENA_BIT BIT(29)
+
+#define GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT BIT(25)
static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
{
@@ -34,8 +60,8 @@ static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
case GCC_USB30_PRIM_MASTER_CLK:
WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate);
clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
- 1, 0, 0, CFG_CLK_SRC_GPLL0_ODD, 8);
- clk_rcg_set_rate(priv->base, 0xf064, 0, 0);
+ 5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
+ clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
default:
return 0;
@@ -50,6 +76,36 @@ static const struct gate_clk sa8775p_clks[] = {
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1b024, 1),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x1b05c, 1),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1b060, 1),
+ GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x1b064, 1),
+
+ /* QUP Wrapper 0 clocks */
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x4b008, GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x4b008, GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x4b008, GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x4b008, GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x4b008, GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x4b008, GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT),
+
+ /* QUP Wrapper 1 clocks (includes uart10) */
+ GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x4b008, GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x4b008, GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x4b008, GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x4b008, GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT), /* uart10 */
+ GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x4b008, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x4b008, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x4b018, GCC_QUPV3_WRAP1_S6_CLK_ENA_BIT),
+
+ /* QUP Wrapper 2 clocks */
+ GATE_CLK(GCC_QUPV3_WRAP2_S0_CLK, 0x4b010, GCC_QUPV3_WRAP2_S0_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S1_CLK, 0x4b010, GCC_QUPV3_WRAP2_S1_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S2_CLK, 0x4b010, GCC_QUPV3_WRAP2_S2_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S3_CLK, 0x4b010, GCC_QUPV3_WRAP2_S3_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S4_CLK, 0x4b010, GCC_QUPV3_WRAP2_S4_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S5_CLK, 0x4b010, GCC_QUPV3_WRAP2_S5_CLK_ENA_BIT),
+ GATE_CLK(GCC_QUPV3_WRAP2_S6_CLK, 0x4b018, GCC_QUPV3_WRAP2_S6_CLK_ENA_BIT),
+
+ /* QUP Wrapper 3 clocks */
+ GATE_CLK(GCC_QUPV3_WRAP3_S0_CLK, 0x4b000, GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT),
};
static int sa8775p_enable(struct clk *clk)
@@ -103,6 +159,24 @@ static const struct qcom_reset_map sa8775p_gcc_resets[] = {
[GCC_TSCSS_BCR] = { 0x21000 },
[GCC_UFS_CARD_BCR] = { 0x81000 },
[GCC_UFS_PHY_BCR] = { 0x83000 },
+ [GCC_USB20_PRIM_BCR] = {0x1c000},
+ [GCC_USB2_PHY_PRIM_BCR] = {0x5c028},
+ [GCC_USB2_PHY_SEC_BCR] = {0x5c02c},
+ [GCC_USB30_PRIM_BCR] = {0x1b000},
+ [GCC_USB30_SEC_BCR] = {0x2f000},
+ [GCC_USB3_DP_PHY_PRIM_BCR] = {0x5c008},
+ [GCC_USB3_DP_PHY_SEC_BCR] = {0x5c014},
+ [GCC_USB3_PHY_PRIM_BCR] = {0x5c000},
+ [GCC_USB3_PHY_SEC_BCR] = {0x5c00c},
+ [GCC_USB3_PHY_TERT_BCR] = {0x5c030},
+ [GCC_USB3_UNIPHY_MP0_BCR] = {0x5c018},
+ [GCC_USB3_UNIPHY_MP1_BCR] = {0x5c01c},
+ [GCC_USB3PHY_PHY_PRIM_BCR] = {0x5c004},
+ [GCC_USB3PHY_PHY_SEC_BCR] = {0x5c010},
+ [GCC_USB3UNIPHY_PHY_MP0_BCR] = {0x5c020},
+ [GCC_USB3UNIPHY_PHY_MP1_BCR] = {0x5c024},
+ [GCC_USB_PHY_CFG_AHB2PHY_BCR] = {0x76000},
+ [GCC_VIDEO_BCR] = {0x34000}
};
static const struct qcom_power_map sa8775p_gdscs[] = {
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 55a233df394..7b6ed826023 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -63,6 +63,11 @@ static ulong sc7280_set_rate(struct clk *clk, ulong rate)
debug("%s: %s, requested rate=%ld\n", __func__, priv->data->clks[clk->id].name, rate);
switch (clk->id) {
+ case GCC_QUPV3_WRAP0_S2_CLK: /* UART2 */
+ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s2_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, 0x17270,
+ freq->pre_div, freq->m, freq->n, freq->src, 16);
+ return freq->freq;
case GCC_QUPV3_WRAP0_S5_CLK: /* UART5 */
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s2_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x17600,
@@ -132,9 +137,13 @@ static const struct gate_clk sc7280_clks[] = {
GATE_CLK(GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK, 0x52008, BIT(28)),
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, BIT(10)),
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, BIT(11)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x52008, BIT(12)),
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, BIT(13)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x52008, BIT(14)),
GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x52008, BIT(15)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK, 0x52008, BIT(16)),
GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK, 0x52008, BIT(17)),
+ GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x52008, BIT(23)),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
@@ -190,6 +199,9 @@ static int sc7280_enable(struct clk *clk)
case GCC_QUPV3_WRAP0_S3_CLK:
clk_rcg_set_rate_mnd(priv->base, 0x173a0, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
break;
+ case GCC_QUPV3_WRAP1_S1_CLK:
+ clk_rcg_set_rate_mnd(priv->base, 0x18140, 1, 0, 0, CFG_CLK_SRC_CXO, 16);
+ break;
}
return qcom_gate_clk_en(priv, clk->id);
diff --git a/drivers/i2c/geni_i2c.c b/drivers/i2c/geni_i2c.c
index d29e00fdf41..fbe5ab0ad0c 100644
--- a/drivers/i2c/geni_i2c.c
+++ b/drivers/i2c/geni_i2c.c
@@ -494,7 +494,9 @@ static int geni_i2c_probe(struct udevice *dev)
return ret;
}
- geni_i2c_enable_clocks(dev, geni);
+ ret = geni_i2c_enable_clocks(dev, geni);
+ if (ret)
+ return ret;
proto = readl(geni->base + GENI_FW_REVISION_RO);
proto &= FW_REV_PROTOCOL_MSK;
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index ac77fb06bf7..38dc36a2194 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -36,6 +36,11 @@
#define CORE_VENDOR_SPEC_POR_VAL 0xa9c
+#define CORE_DLL_PDN BIT(29)
+#define CORE_DLL_RST BIT(30)
+
+#define MHZ(X) ((X) * 1000000UL)
+
struct msm_sdhc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -51,6 +56,7 @@ struct msm_sdhc {
struct msm_sdhc_variant_info {
bool mci_removed;
+ u32 core_dll_config;
u32 core_vendor_spec;
u32 core_vendor_spec_capabilities0;
};
@@ -114,6 +120,9 @@ static int msm_sdc_clk_init(struct udevice *dev)
return -EINVAL;
}
+ /* This is the base clock sdhci core will use to configure the SDCLK */
+ prv->host.max_clk = clk_rate;
+
writel_relaxed(CORE_VENDOR_SPEC_POR_VAL,
prv->host.ioaddr + var_info->core_vendor_spec);
@@ -146,6 +155,34 @@ static int msm_sdc_mci_init(struct msm_sdhc *prv)
return 0;
}
+static int msm_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enable)
+{
+ struct udevice *dev = mmc_to_dev(host->mmc);
+ const struct msm_sdhc_variant_info *var_info = (void *)dev_get_driver_data(dev);
+ u32 config;
+
+ if (enable && clock < MHZ(100)) {
+ /*
+ * DLL is not required for clock <= 100MHz
+ * Thus, make sure DLL is disabled when not required
+ */
+ config = readl(host->ioaddr + var_info->core_dll_config);
+ config |= CORE_DLL_RST;
+ writel(config, host->ioaddr + var_info->core_dll_config);
+
+ config = readl(host->ioaddr + var_info->core_dll_config);
+ config |= CORE_DLL_PDN;
+ writel(config, host->ioaddr + var_info->core_dll_config);
+ }
+
+ return 0;
+}
+
+struct sdhci_ops msm_sdhci_ops = {
+ .config_dll = &msm_sdhci_config_dll,
+ .set_control_reg = &sdhci_set_control_reg,
+};
+
static int msm_sdc_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
@@ -220,6 +257,7 @@ static int msm_sdc_probe(struct udevice *dev)
host->mmc = &plat->mmc;
host->mmc->dev = dev;
+ host->ops = &msm_sdhci_ops;
ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
if (ret)
return ret;
@@ -285,6 +323,7 @@ static int msm_sdc_bind(struct udevice *dev)
static const struct msm_sdhc_variant_info msm_sdhc_mci_var = {
.mci_removed = false,
+ .core_dll_config = 0x100,
.core_vendor_spec = 0x10c,
.core_vendor_spec_capabilities0 = 0x11c,
};
@@ -292,6 +331,7 @@ static const struct msm_sdhc_variant_info msm_sdhc_mci_var = {
static const struct msm_sdhc_variant_info msm_sdhc_v5_var = {
.mci_removed = true,
+ .core_dll_config = 0x200,
.core_vendor_spec = 0x20c,
.core_vendor_spec_capabilities0 = 0x21c,
};
diff --git a/drivers/phy/qcom/phy-qcom-qusb2.c b/drivers/phy/qcom/phy-qcom-qusb2.c
index d98f6108e69..9e821365c15 100644
--- a/drivers/phy/qcom/phy-qcom-qusb2.c
+++ b/drivers/phy/qcom/phy-qcom-qusb2.c
@@ -224,6 +224,18 @@ static const unsigned int qusb2_v2_regs_layout[] = {
[QUSB2PHY_INTR_CTRL] = 0x230,
};
+static const struct qusb2_phy_cfg msm8996_phy_cfg = {
+ .tbl = msm8996_init_tbl,
+ .tbl_num = ARRAY_SIZE(msm8996_init_tbl),
+ .regs = sm6115_regs_layout,
+
+ .has_pll_test = true,
+ .se_clk_scheme_default = true,
+ .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
+ .mask_core_ready = PLL_LOCKED,
+ .autoresume_en = BIT(3),
+};
+
static const struct qusb2_phy_cfg sm6115_phy_cfg = {
.tbl = sm6115_init_tbl,
.tbl_num = ARRAY_SIZE(sm6115_init_tbl),
@@ -450,6 +462,8 @@ static struct phy_ops qusb2phy_ops = {
};
static const struct udevice_id qusb2phy_ids[] = {
+ { .compatible = "qcom,msm8996-qusb2-phy",
+ .data = (ulong)&msm8996_phy_cfg },
{ .compatible = "qcom,qusb2-phy" },
{ .compatible = "qcom,qcm2290-qusb2-phy",
.data = (ulong)&sm6115_phy_cfg },
diff --git a/drivers/phy/qcom/phy-qcom-snps-femto-v2.c b/drivers/phy/qcom/phy-qcom-snps-femto-v2.c
index 04f0f0e7817..e782de07ebc 100644
--- a/drivers/phy/qcom/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qcom/phy-qcom-snps-femto-v2.c
@@ -174,7 +174,7 @@ static int qcom_snps_hsphy_phy_probe(struct udevice *dev)
return ret;
}
- reset_deassert_bulk(&priv->resets);
+ reset_assert_bulk(&priv->resets);
return 0;
}
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 320aba33347..580308621b1 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -6,8 +6,17 @@ config PINCTRL_QCOM
menu "Qualcomm pinctrl drivers"
+config PINCTRL_QCOM_GENERIC
+ bool "Enable all Qualcomm pinctrl drivers by default"
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable all Qualcomm pinctrl drivers by default.
+ This is useful for generic Qualcomm defconfigs that support
+ multiple SoCs. Individual drivers can still be disabled if needed.
+
config PINCTRL_QCOM_APQ8016
bool "Qualcomm APQ8016 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the MSM8916 / APQ8016
@@ -15,6 +24,7 @@ config PINCTRL_QCOM_APQ8016
config PINCTRL_QCOM_APQ8096
bool "Qualcomm APQ8096 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the MSM8996 / APQ8096
@@ -22,6 +32,7 @@ config PINCTRL_QCOM_APQ8096
config PINCTRL_QCOM_IPQ4019
bool "Qualcomm IPQ4019 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the IPQ4019 SoC,
@@ -29,6 +40,7 @@ config PINCTRL_QCOM_IPQ4019
config PINCTRL_QCOM_IPQ5424
bool "Qualcomm IPQ5424 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the IPQ5424 SoC,
@@ -36,6 +48,7 @@ config PINCTRL_QCOM_IPQ5424
config PINCTRL_QCOM_IPQ9574
bool "Qualcomm IPQ9574 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the IPQ9574 SoC,
@@ -43,6 +56,7 @@ config PINCTRL_QCOM_IPQ9574
config PINCTRL_QCOM_QCM2290
bool "Qualcomm QCM2290 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon QCM2290 SoC,
@@ -50,13 +64,23 @@ config PINCTRL_QCOM_QCM2290
config PINCTRL_QCOM_QCS404
bool "Qualcomm QCS404 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_QCS615
+ bool "Qualcomm QCS615 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the Snapdragon QCS615 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_SA8775P
bool "Qualcomm SA8775P Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SA8775P SoC,
@@ -64,12 +88,14 @@ config PINCTRL_QCOM_SA8775P
config PINCTRL_QCOM_SC7280
bool "Qualcomm SC7280/QCM6490 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC,
config PINCTRL_QCOM_SDM670
bool "Qualcomm SDM670 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SDM670 SoC,
@@ -77,6 +103,7 @@ config PINCTRL_QCOM_SDM670
config PINCTRL_QCOM_SDM660
bool "Qualcomm SDM630/660 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon 630/636/660
@@ -84,6 +111,7 @@ config PINCTRL_QCOM_SDM660
config PINCTRL_QCOM_SDM845
bool "Qualcomm SDM845 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
@@ -91,6 +119,7 @@ config PINCTRL_QCOM_SDM845
config PINCTRL_QCOM_SM6115
bool "Qualcomm SM6115 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
@@ -98,12 +127,14 @@ config PINCTRL_QCOM_SM6115
config PINCTRL_QCOM_SM6350
bool "Qualcomm SM6350 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM6350 SoC,
config PINCTRL_QCOM_SM7150
bool "Qualcomm SM7150 GCC"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM7150 SoC,
@@ -111,6 +142,7 @@ config PINCTRL_QCOM_SM7150
config PINCTRL_QCOM_SM8150
bool "Qualcomm SM8150 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8150 SoC,
@@ -118,6 +150,7 @@ config PINCTRL_QCOM_SM8150
config PINCTRL_QCOM_SM8250
bool "Qualcomm SM8250 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8250 SoC,
@@ -125,6 +158,7 @@ config PINCTRL_QCOM_SM8250
config PINCTRL_QCOM_SM8550
bool "Qualcomm SM8550 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8550 SoC,
@@ -132,6 +166,7 @@ config PINCTRL_QCOM_SM8550
config PINCTRL_QCOM_SM8650
bool "Qualcomm SM8650 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8650 SoC,
@@ -139,6 +174,7 @@ config PINCTRL_QCOM_SM8650
config PINCTRL_QCOM_X1E80100
bool "Qualcomm X1E80100 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon X1E80100 SoC,
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 06582ac2068..b5a111605ed 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
+obj-$(CONFIG_PINCTRL_QCOM_QCS615) += pinctrl-qcs615.o
obj-$(CONFIG_PINCTRL_QCOM_SA8775P) += pinctrl-sa8775p.o
obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o
obj-$(CONFIG_PINCTRL_QCOM_SDM660) += pinctrl-sdm660.o
diff --git a/drivers/pinctrl/qcom/pinctrl-qcs615.c b/drivers/pinctrl/qcom/pinctrl-qcs615.c
new file mode 100644
index 00000000000..1a66cf73456
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-qcs615.c
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+typedef unsigned int msm_pin_function[10];
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)\
+ { \
+ msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9 \
+ }
+
+#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, ctl) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = ctl, \
+ .io_reg = ctl + 0x4, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ }
+
+#define EAST 0x000000
+#define SOUTH 0xc00000
+#define WEST 0x400000
+
+enum qcs615_functions {
+ msm_mux_gpio,
+ msm_mux_adsp_ext,
+ msm_mux_agera_pll,
+ msm_mux_aoss_cti,
+ msm_mux_atest_char,
+ msm_mux_atest_tsens,
+ msm_mux_atest_usb,
+ msm_mux_cam_mclk,
+ msm_mux_cci_async,
+ msm_mux_cci_i2c,
+ msm_mux_cci_timer,
+ msm_mux_copy_gp,
+ msm_mux_copy_phase,
+ msm_mux_cri_trng,
+ msm_mux_dbg_out_clk,
+ msm_mux_ddr_bist,
+ msm_mux_ddr_pxi,
+ msm_mux_dp_hot,
+ msm_mux_edp_hot,
+ msm_mux_edp_lcd,
+ msm_mux_emac_gcc,
+ msm_mux_emac_phy_intr,
+ msm_mux_forced_usb,
+ msm_mux_gcc_gp,
+ msm_mux_gp_pdm,
+ msm_mux_gps_tx,
+ msm_mux_hs0_mi2s,
+ msm_mux_hs1_mi2s,
+ msm_mux_jitter_bist,
+ msm_mux_ldo_en,
+ msm_mux_ldo_update,
+ msm_mux_m_voc,
+ msm_mux_mclk1,
+ msm_mux_mclk2,
+ msm_mux_mdp_vsync,
+ msm_mux_mdp_vsync0_out,
+ msm_mux_mdp_vsync1_out,
+ msm_mux_mdp_vsync2_out,
+ msm_mux_mdp_vsync3_out,
+ msm_mux_mdp_vsync4_out,
+ msm_mux_mdp_vsync5_out,
+ msm_mux_mi2s_1,
+ msm_mux_mss_lte,
+ msm_mux_nav_pps_in,
+ msm_mux_nav_pps_out,
+ msm_mux_pa_indicator_or,
+ msm_mux_pcie_clk_req,
+ msm_mux_pcie_ep_rst,
+ msm_mux_phase_flag,
+ msm_mux_pll_bist,
+ msm_mux_pll_bypassnl,
+ msm_mux_pll_reset_n,
+ msm_mux_prng_rosc,
+ msm_mux_qdss_cti,
+ msm_mux_qdss_gpio,
+ msm_mux_qlink_enable,
+ msm_mux_qlink_request,
+ msm_mux_qspi,
+ msm_mux_qup0,
+ msm_mux_qup1,
+ msm_mux_rgmii,
+ msm_mux_sd_write_protect,
+ msm_mux_sp_cmu,
+ msm_mux_ter_mi2s,
+ msm_mux_tgu_ch,
+ msm_mux_uim1,
+ msm_mux_uim2,
+ msm_mux_usb0_hs,
+ msm_mux_usb1_hs,
+ msm_mux_usb_phy_ps,
+ msm_mux_vfr_1,
+ msm_mux_vsense_trigger_mirnat,
+ msm_mux_wlan,
+ msm_mux_wsa_clk,
+ msm_mux_wsa_data,
+ msm_mux__,
+};
+
+#define MSM_PIN_FUNCTION(fname) \
+ [msm_mux_##fname] = {#fname, msm_mux_##fname}
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ MSM_PIN_FUNCTION(gpio),
+ MSM_PIN_FUNCTION(adsp_ext),
+ MSM_PIN_FUNCTION(agera_pll),
+ MSM_PIN_FUNCTION(aoss_cti),
+ MSM_PIN_FUNCTION(atest_char),
+ MSM_PIN_FUNCTION(atest_tsens),
+ MSM_PIN_FUNCTION(atest_usb),
+ MSM_PIN_FUNCTION(cam_mclk),
+ MSM_PIN_FUNCTION(cci_async),
+ MSM_PIN_FUNCTION(cci_i2c),
+ MSM_PIN_FUNCTION(cci_timer),
+ MSM_PIN_FUNCTION(copy_gp),
+ MSM_PIN_FUNCTION(copy_phase),
+ MSM_PIN_FUNCTION(cri_trng),
+ MSM_PIN_FUNCTION(dbg_out_clk),
+ MSM_PIN_FUNCTION(ddr_bist),
+ MSM_PIN_FUNCTION(ddr_pxi),
+ MSM_PIN_FUNCTION(dp_hot),
+ MSM_PIN_FUNCTION(edp_hot),
+ MSM_PIN_FUNCTION(edp_lcd),
+ MSM_PIN_FUNCTION(emac_gcc),
+ MSM_PIN_FUNCTION(emac_phy_intr),
+ MSM_PIN_FUNCTION(forced_usb),
+ MSM_PIN_FUNCTION(gcc_gp),
+ MSM_PIN_FUNCTION(gp_pdm),
+ MSM_PIN_FUNCTION(gps_tx),
+ MSM_PIN_FUNCTION(hs0_mi2s),
+ MSM_PIN_FUNCTION(hs1_mi2s),
+ MSM_PIN_FUNCTION(jitter_bist),
+ MSM_PIN_FUNCTION(ldo_en),
+ MSM_PIN_FUNCTION(ldo_update),
+ MSM_PIN_FUNCTION(m_voc),
+ MSM_PIN_FUNCTION(mclk1),
+ MSM_PIN_FUNCTION(mclk2),
+ MSM_PIN_FUNCTION(mdp_vsync),
+ MSM_PIN_FUNCTION(mdp_vsync0_out),
+ MSM_PIN_FUNCTION(mdp_vsync1_out),
+ MSM_PIN_FUNCTION(mdp_vsync2_out),
+ MSM_PIN_FUNCTION(mdp_vsync3_out),
+ MSM_PIN_FUNCTION(mdp_vsync4_out),
+ MSM_PIN_FUNCTION(mdp_vsync5_out),
+ MSM_PIN_FUNCTION(mi2s_1),
+ MSM_PIN_FUNCTION(mss_lte),
+ MSM_PIN_FUNCTION(nav_pps_in),
+ MSM_PIN_FUNCTION(nav_pps_out),
+ MSM_PIN_FUNCTION(pa_indicator_or),
+ MSM_PIN_FUNCTION(pcie_clk_req),
+ MSM_PIN_FUNCTION(pcie_ep_rst),
+ MSM_PIN_FUNCTION(phase_flag),
+ MSM_PIN_FUNCTION(pll_bist),
+ MSM_PIN_FUNCTION(pll_bypassnl),
+ MSM_PIN_FUNCTION(pll_reset_n),
+ MSM_PIN_FUNCTION(prng_rosc),
+ MSM_PIN_FUNCTION(qdss_cti),
+ MSM_PIN_FUNCTION(qdss_gpio),
+ MSM_PIN_FUNCTION(qlink_enable),
+ MSM_PIN_FUNCTION(qlink_request),
+ MSM_PIN_FUNCTION(qspi),
+ MSM_PIN_FUNCTION(qup0),
+ MSM_PIN_FUNCTION(qup1),
+ MSM_PIN_FUNCTION(rgmii),
+ MSM_PIN_FUNCTION(sd_write_protect),
+ MSM_PIN_FUNCTION(sp_cmu),
+ MSM_PIN_FUNCTION(ter_mi2s),
+ MSM_PIN_FUNCTION(tgu_ch),
+ MSM_PIN_FUNCTION(uim1),
+ MSM_PIN_FUNCTION(uim2),
+ MSM_PIN_FUNCTION(usb0_hs),
+ MSM_PIN_FUNCTION(usb1_hs),
+ MSM_PIN_FUNCTION(usb_phy_ps),
+ MSM_PIN_FUNCTION(vfr_1),
+ MSM_PIN_FUNCTION(vsense_trigger_mirnat),
+ MSM_PIN_FUNCTION(wlan),
+ MSM_PIN_FUNCTION(wsa_clk),
+ MSM_PIN_FUNCTION(wsa_data),
+};
+
+static const msm_pin_function qcs615_pin_functions[] = {
+ [0] = PINGROUP(0, qup0, _, qdss_gpio, _, _, _, _, _, _),
+ [1] = PINGROUP(1, qup0, _, qdss_gpio, _, _, _, _, _, _),
+ [2] = PINGROUP(2, qup0, _, qdss_gpio, _, _, _, _, _, _),
+ [3] = PINGROUP(3, qup0, _, qdss_gpio, _, _, _, _, _, _),
+ [4] = PINGROUP(4, qup0, _, _, _, _, _, _, _, _),
+ [5] = PINGROUP(5, qup0, _, _, _, _, _, _, _, _),
+ [6] = PINGROUP(6, qup1, qdss_gpio, ddr_pxi, _, _, _, _, _, _),
+ [7] = PINGROUP(7, qup1, ddr_bist, qdss_gpio, atest_tsens,
+ vsense_trigger_mirnat, atest_usb, ddr_pxi, _, _),
+ [8] = PINGROUP(8, qup1, gp_pdm, ddr_bist, qdss_gpio, _, _, _, _, _),
+ [9] = PINGROUP(9, qup1, ddr_bist, qdss_gpio, _, _, _, _, _, _),
+ [10] = PINGROUP(10, qup1, ddr_bist, _, phase_flag, atest_usb, ddr_pxi, _, _, _),
+ [11] = PINGROUP(11, qup1, dbg_out_clk, atest_usb, ddr_pxi, _, _, _, _, _),
+ [12] = PINGROUP(12, qup1, jitter_bist, ddr_pxi, _, _, _, _, _, _),
+ [13] = PINGROUP(13, qup1, pll_bypassnl, _, ddr_pxi, _, _, _, _, _),
+ [14] = PINGROUP(14, qup1, pll_reset_n, _, qdss_gpio, _, _, _, _, _),
+ [15] = PINGROUP(15, qup1, qdss_gpio, _, _, _, _, _, _, _),
+ [16] = PINGROUP(16, qup0, _, wlan, _, _, _, _, _, _),
+ [17] = PINGROUP(17, qup0, _, wlan, _, _, _, _, _, _),
+ [18] = PINGROUP(18, qup0, _, phase_flag, _, _, _, _, _, _),
+ [19] = PINGROUP(19, qup0, _, phase_flag, _, _, _, _, _, _),
+ [20] = PINGROUP(20, qup1, _, phase_flag, qdss_gpio, _, _, _, _, _),
+ [21] = PINGROUP(21, qup1, gcc_gp, _, qdss_gpio, _, _, _, _, _),
+ [22] = PINGROUP(22, qup1, gcc_gp, _, _, _, _, _, _, _),
+ [23] = PINGROUP(23, qup1, _, phase_flag, _, _, _, _, _, _),
+ [24] = PINGROUP(24, hs1_mi2s, sd_write_protect, _, phase_flag, _, _, _, _, _),
+ [25] = PINGROUP(25, hs1_mi2s, _, phase_flag, _, _, _, _, _, _),
+ [26] = PINGROUP(26, cci_async, hs1_mi2s, jitter_bist, _, _, _, _, _, _),
+ [27] = PINGROUP(27, hs1_mi2s, pll_bist, _, _, _, _, _, _, _),
+ [28] = PINGROUP(28, cam_mclk, agera_pll, qdss_gpio, _, _, _, _, _, _),
+ [29] = PINGROUP(29, cam_mclk, _, qdss_gpio, atest_tsens, _, _, _, _, _),
+ [30] = PINGROUP(30, cam_mclk, qdss_gpio, _, _, _, _, _, _, _),
+ [31] = PINGROUP(31, cam_mclk, _, qdss_gpio, _, _, _, _, _, _),
+ [32] = PINGROUP(32, cci_i2c, _, qdss_gpio, _, _, _, _, _, _),
+ [33] = PINGROUP(33, cci_i2c, _, qdss_gpio, _, _, _, _, _, _),
+ [34] = PINGROUP(34, cci_i2c, _, qdss_gpio, _, _, _, _, _, _),
+ [35] = PINGROUP(35, cci_i2c, _, qdss_gpio, _, _, _, _, _, _),
+ [36] = PINGROUP(36, hs0_mi2s, _, _, _, _, _, _, _, _),
+ [37] = PINGROUP(37, cci_timer, hs0_mi2s, _, _, _, _, _, _, _),
+ [38] = PINGROUP(38, cci_timer, hs0_mi2s, _, phase_flag, _, _, _, _, _),
+ [39] = PINGROUP(39, cci_timer, hs0_mi2s, _, _, _, _, _, _, _),
+ [40] = PINGROUP(40, _, phase_flag, _, _, _, _, _, _, _),
+ [41] = PINGROUP(41, cci_async, cci_timer, _, phase_flag, _, _, _, _, _),
+ [42] = PINGROUP(42, cci_async, cci_timer, _, phase_flag, _, _, _, _, _),
+ [43] = PINGROUP(43, _, phase_flag, forced_usb, _, _, _, _, _, _),
+ [44] = PINGROUP(44, qspi, _, phase_flag, qdss_gpio, _, _, _, _, _),
+ [45] = PINGROUP(45, qspi, _, phase_flag, qdss_gpio, _, _, _, _, _),
+ [46] = PINGROUP(46, qspi, _, qdss_gpio, _, _, _, _, _, _),
+ [47] = PINGROUP(47, qspi, _, qdss_gpio, wlan, _, _, _, _, _),
+ [48] = PINGROUP(48, qspi, _, wlan, _, _, _, _, _, _),
+ [49] = PINGROUP(49, qspi, _, _, _, _, _, _, _, _),
+ [50] = PINGROUP(50, qspi, _, _, _, _, _, _, _, _),
+ [51] = PINGROUP(51, qlink_request, _, _, _, _, _, _, _, _),
+ [52] = PINGROUP(52, qlink_enable, _, _, _, _, _, _, _, _),
+ [53] = PINGROUP(53, pa_indicator_or, nav_pps_in, nav_pps_out, gps_tx, _,
+ phase_flag, _, _, _),
+ [54] = PINGROUP(54, _, gps_tx, gp_pdm, _, phase_flag, atest_usb, ddr_pxi, _, _),
+ [55] = PINGROUP(55, _, _, phase_flag, atest_usb, ddr_pxi, _, _, _, _),
+ [56] = PINGROUP(56, _, nav_pps_in, nav_pps_out, gps_tx, _, _, _, _, _),
+ [57] = PINGROUP(57, _, nav_pps_in, gps_tx, nav_pps_out, gcc_gp, _, _, _, _),
+ [58] = PINGROUP(58, _, gcc_gp, _, _, _, _, _, _, _),
+ [59] = PINGROUP(59, _, nav_pps_in, nav_pps_out, gps_tx, gcc_gp, _, _, _, _),
+ [60] = PINGROUP(60, _, nav_pps_in, nav_pps_out, gps_tx, cri_trng, _, _, _, _),
+ [61] = PINGROUP(61, _, cri_trng, _, _, _, _, _, _, _),
+ [62] = PINGROUP(62, _, cri_trng, _, _, _, _, _, _, _),
+ [63] = PINGROUP(63, _, _, gp_pdm, _, _, _, _, _, _),
+ [64] = PINGROUP(64, _, sp_cmu, _, _, _, _, _, _, _),
+ [65] = PINGROUP(65, _, _, _, _, _, _, _, _, _),
+ [66] = PINGROUP(66, _, gp_pdm, _, _, _, _, _, _, _),
+ [67] = PINGROUP(67, _, _, _, phase_flag, atest_usb, _, _, _, _),
+ [68] = PINGROUP(68, _, _, _, phase_flag, atest_usb, _, _, _, _),
+ [69] = PINGROUP(69, _, _, _, _, _, _, _, _, _),
+ [70] = PINGROUP(70, _, _, _, _, _, _, _, _, _),
+ [71] = PINGROUP(71, _, _, _, _, _, _, _, _, _),
+ [72] = PINGROUP(72, _, _, _, _, _, _, _, _, _),
+ [73] = PINGROUP(73, uim2, _, _, _, _, _, _, _, _),
+ [74] = PINGROUP(74, uim2, _, _, _, _, _, _, _, _),
+ [75] = PINGROUP(75, uim2, _, phase_flag, atest_usb, _, _, _, _, _),
+ [76] = PINGROUP(76, uim2, _, phase_flag, atest_usb, aoss_cti, _, _, _, _),
+ [77] = PINGROUP(77, uim1, _, phase_flag, atest_usb, _, _, _, _, _),
+ [78] = PINGROUP(78, uim1, gcc_gp, _, phase_flag, _, _, _, _, _),
+ [79] = PINGROUP(79, uim1, gp_pdm, _, phase_flag, _, _, _, _, _),
+ [80] = PINGROUP(80, uim1, _, phase_flag, _, _, _, _, _, _),
+ [81] = PINGROUP(81, rgmii, mdp_vsync, _, qdss_gpio, _, _, _, _, _),
+ [82] = PINGROUP(82, rgmii, mdp_vsync, _, phase_flag, qdss_gpio, _, _, _, _),
+ [83] = PINGROUP(83, rgmii, mdp_vsync, _, qdss_cti, _, _, _, _, _),
+ [84] = PINGROUP(84, _, phase_flag, atest_char, _, _, _, _, _, _),
+ [85] = PINGROUP(85, _, atest_char, _, _, _, _, _, _, _),
+ [86] = PINGROUP(86, copy_gp, _, atest_char, _, _, _, _, _, _),
+ [87] = PINGROUP(87, _, atest_char, _, _, _, _, _, _, _),
+ [88] = PINGROUP(88, _, usb0_hs, _, _, _, _, _, _, _),
+ [89] = PINGROUP(89, emac_phy_intr, pcie_ep_rst, tgu_ch, usb1_hs, _, _, _, _, _),
+ [90] = PINGROUP(90, mdp_vsync, mdp_vsync0_out, mdp_vsync1_out,
+ mdp_vsync2_out, mdp_vsync3_out, mdp_vsync4_out, mdp_vsync5_out,
+ pcie_clk_req, tgu_ch),
+ [91] = PINGROUP(91, rgmii, tgu_ch, _, _, _, _, _, _, _),
+ [92] = PINGROUP(92, rgmii, vfr_1, tgu_ch, _, phase_flag, qdss_gpio, _, _, _),
+ [93] = PINGROUP(93, rgmii, qdss_gpio, _, _, _, _, _, _, _),
+ [94] = PINGROUP(94, rgmii, qdss_gpio, _, _, _, _, _, _, _),
+ [95] = PINGROUP(95, rgmii, gp_pdm, qdss_gpio, _, _, _, _, _, _),
+ [96] = PINGROUP(96, rgmii, qdss_cti, _, _, _, _, _, _, _),
+ [97] = PINGROUP(97, rgmii, mdp_vsync, ldo_en, qdss_cti, _, _, _, _, _),
+ [98] = PINGROUP(98, mdp_vsync, ldo_update, qdss_cti, _, _, _, _, _, _),
+ [99] = PINGROUP(99, prng_rosc, _, _, _, _, _, _, _, _),
+ [100] = PINGROUP(100, _, _, _, _, _, _, _, _, _),
+ [101] = PINGROUP(101, emac_gcc, _, _, _, _, _, _, _, _),
+ [102] = PINGROUP(102, rgmii, dp_hot, emac_gcc, prng_rosc, _, _, _, _, _),
+ [103] = PINGROUP(103, rgmii, dp_hot, copy_phase, qdss_cti, _, _, _, _, _),
+ [104] = PINGROUP(104, usb_phy_ps, _, qdss_cti, dp_hot, _, _, _, _, _),
+ [105] = PINGROUP(105, _, _, _, _, _, _, _, _, _),
+ [106] = PINGROUP(106, mss_lte, _, _, _, _, _, _, _, _),
+ [107] = PINGROUP(107, mss_lte, _, _, _, _, _, _, _, _),
+ [108] = PINGROUP(108, mi2s_1, _, qdss_gpio, _, _, _, _, _, _),
+ [109] = PINGROUP(109, mi2s_1, _, qdss_gpio, _, _, _, _, _, _),
+ [110] = PINGROUP(110, wsa_data, mi2s_1, _, _, _, _, _, _, _),
+ [111] = PINGROUP(111, wsa_clk, mi2s_1, _, _, _, _, _, _, _),
+ [112] = PINGROUP(112, rgmii, _, qdss_cti, _, _, _, _, _, _),
+ [113] = PINGROUP(113, rgmii, edp_hot, _, qdss_cti, _, _, _, _, _),
+ [114] = PINGROUP(114, rgmii, _, _, _, _, _, _, _, _),
+ [115] = PINGROUP(115, ter_mi2s, atest_char, _, _, _, _, _, _, _),
+ [116] = PINGROUP(116, ter_mi2s, _, phase_flag, _, _, _, _, _, _),
+ [117] = PINGROUP(117, ter_mi2s, _, phase_flag, qdss_gpio, atest_char, _, _, _, _),
+ [118] = PINGROUP(118, ter_mi2s, adsp_ext, _, phase_flag, qdss_gpio, atest_char,
+ _, _, _),
+ [119] = PINGROUP(119, edp_lcd, _, phase_flag, qdss_gpio, atest_char, _, _, _, _),
+ [120] = PINGROUP(120, m_voc, qdss_gpio, atest_char, _, _, _, _, _, _),
+ [121] = PINGROUP(121, mclk1, atest_char, _, _, _, _, _, _, _),
+ [122] = PINGROUP(122, mclk2, _, _, _, _, _, _, _, _),
+};
+
+static const struct msm_special_pin_data qcs615_special_pins_data[] = {
+ [0] = UFS_RESET("ufs_reset", 0x9f000 + WEST),
+ [1] = SDC_QDSD_PINGROUP("sdc1_rclk", 0x9a000 + WEST, 15, 0),
+ [2] = SDC_QDSD_PINGROUP("sdc1_clk", 0x9a000 + WEST, 13, 6),
+ [3] = SDC_QDSD_PINGROUP("sdc1_cmd", 0x9a000 + WEST, 11, 3),
+ [4] = SDC_QDSD_PINGROUP("sdc1_data", 0x9a000 + WEST, 9, 0),
+ [5] = SDC_QDSD_PINGROUP("sdc2_clk", 0x98000 + SOUTH, 14, 6),
+ [6] = SDC_QDSD_PINGROUP("sdc2_cmd", 0x98000 + SOUTH, 11, 3),
+ [7] = SDC_QDSD_PINGROUP("sdc2_data", 0x98000 + SOUTH, 9, 0),
+};
+
+static const unsigned int qcs615_pin_offsets[] = {
+ [0] = WEST, [1] = WEST, [2] = WEST,
+ [3] = WEST, [4] = WEST, [5] = WEST,
+ [6] = EAST, [7] = EAST, [8] = EAST,
+ [9] = EAST, [10] = EAST, [11] = EAST,
+ [12] = EAST, [13] = EAST, [14] = EAST,
+ [15] = EAST, [16] = WEST, [17] = WEST,
+ [18] = WEST, [19] = WEST, [20] = SOUTH,
+ [21] = SOUTH, [22] = SOUTH, [23] = SOUTH,
+ [24] = EAST, [25] = EAST, [26] = EAST,
+ [27] = EAST, [28] = EAST, [29] = EAST,
+ [30] = EAST, [31] = EAST, [32] = EAST,
+ [33] = EAST, [34] = EAST, [35] = EAST,
+ [36] = EAST, [37] = EAST, [38] = EAST,
+ [39] = EAST, [40] = EAST, [41] = EAST,
+ [42] = EAST, [43] = SOUTH, [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] = WEST, [82] = WEST, [83] = WEST,
+ [84] = SOUTH, [85] = SOUTH, [86] = SOUTH,
+ [87] = SOUTH, [88] = WEST, [89] = WEST,
+ [90] = WEST, [91] = WEST, [92] = WEST,
+ [93] = WEST, [94] = WEST, [95] = WEST,
+ [96] = WEST, [97] = WEST, [98] = WEST,
+ [99] = EAST, [100] = WEST, [101] = WEST,
+ [102] = WEST, [103] = WEST, [104] = WEST,
+ [105] = SOUTH, [106] = EAST, [107] = EAST,
+ [108] = SOUTH, [109] = SOUTH, [110] = SOUTH,
+ [111] = SOUTH, [112] = WEST, [113] = WEST,
+ [114] = WEST, [115] = SOUTH, [116] = SOUTH,
+ [117] = SOUTH, [118] = SOUTH, [119] = SOUTH,
+ [120] = SOUTH, [121] = SOUTH, [122] = SOUTH,
+};
+
+static const char *qcs615_get_function_name(struct udevice *dev,
+ unsigned int selector)
+
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *qcs615_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct msm_pinctrl_data *data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
+ unsigned int special_pins_start = data->pin_data.special_pins_start;
+
+ if (selector > (data->pin_data.pin_count - 1))
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "unknown");
+ else if (selector >= special_pins_start)
+
+ snprintf(pin_name, MAX_PIN_NAME_LEN,
+ qcs615_special_pins_data[selector - special_pins_start].name);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+
+ return pin_name;
+}
+
+static int qcs615_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
+{
+ unsigned int i;
+ const msm_pin_function *func = NULL;
+
+ if (pin >= ARRAY_SIZE(qcs615_pin_functions))
+ return -EINVAL;
+
+ func = qcs615_pin_functions + pin;
+ for (i = 0; i < 10; i++)
+ if ((*func)[i] == selector)
+ return i;
+
+ pr_err("Can't find requested function for pin %u pin\n", pin);
+
+ return -EINVAL;
+}
+
+static const struct msm_pinctrl_data qcs615_data = {
+ .pin_data = {
+ .pin_count = 131,
+ .special_pins_start = 123,
+ .special_pins_data = qcs615_special_pins_data,
+ .pin_offsets = qcs615_pin_offsets,
+ },
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = qcs615_get_function_name,
+ .get_function_mux = qcs615_get_function_mux,
+ .get_pin_name = qcs615_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,qcs615-tlmm", .data = (ulong)&qcs615_data},
+ { }
+};
+
+U_BOOT_DRIVER(qcs615_pinctrl) = {
+ .name = "qcs615_pinctrl",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+
+};
diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c
index 06466142560..3f0f1845469 100644
--- a/drivers/power/regulator/qcom-rpmh-regulator.c
+++ b/drivers/power/regulator/qcom-rpmh-regulator.c
@@ -37,8 +37,11 @@ enum rpmh_regulator_mode {
};
#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
+#define RPMH_REGULATOR_VOLTAGE_MASK 0x1FFF
#define RPMH_REGULATOR_REG_ENABLE 0x4
+#define RPMH_REGULATOR_ENABLE_MASK 0x1
#define RPMH_REGULATOR_REG_VRM_MODE 0x8
+#define RPMH_REGULATOR_MODE_MASK 0x7
#define PMIC4_LDO_MODE_RETENTION 4
#define PMIC4_LDO_MODE_LPM 5
@@ -205,6 +208,38 @@ static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
return ret;
}
+static int rpmh_regulator_read_data(struct rpmh_vreg *vreg, struct tcs_cmd *cmd)
+{
+ return rpmh_read(vreg->dev->parent, RPMH_ACTIVE_ONLY_STATE, cmd);
+}
+
+static int rpmh_regulator_vrm_get_voltage(struct udevice *rdev, int *uV)
+{
+ struct rpmh_vreg *vreg = dev_get_priv(rdev);
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
+ };
+ const struct linear_range *uv_range = &vreg->hw_data->voltage_range;
+ int min_uV = uv_range->min;
+ int max_uV = uv_range->min + uv_range->max_sel * uv_range->step;
+
+ int ret, _uV = 0;
+
+ ret = rpmh_regulator_read_data(vreg, &cmd);
+ if (!ret)
+ _uV = (cmd.data & RPMH_REGULATOR_VOLTAGE_MASK) * 1000;
+ else
+ dev_err(vreg->dev, "failed to read VOLTAGE ret = %d\n", ret);
+
+ if (!_uV || (_uV >= min_uV && _uV <= max_uV))
+ *uV = _uV;
+ else
+ dev_info(vreg->dev, "read voltage %d is out-of-range[%d:%d]\n",
+ _uV, min_uV, max_uV);
+
+ return ret;
+}
+
static int _rpmh_regulator_vrm_set_value(struct udevice *rdev,
int uv, bool wait_for_ack)
{
@@ -249,8 +284,13 @@ static int rpmh_regulator_vrm_set_value(struct udevice *rdev,
static int rpmh_regulator_vrm_get_value(struct udevice *rdev)
{
struct rpmh_vreg *vreg = dev_get_priv(rdev);
+ int ret, uV;
- debug("%s: get_value %d\n", rdev->name, vreg->uv);
+ if (vreg->uv < 0) {
+ ret = rpmh_regulator_vrm_get_voltage(rdev, &uV);
+ if (!ret && uV != 0)
+ vreg->uv = uV;
+ }
return vreg->uv;
}
@@ -258,9 +298,23 @@ static int rpmh_regulator_vrm_get_value(struct udevice *rdev)
static int rpmh_regulator_is_enabled(struct udevice *rdev)
{
struct rpmh_vreg *vreg = dev_get_priv(rdev);
+ int ret;
debug("%s: is_enabled %d\n", rdev->name, vreg->enabled);
+ if (vreg->enabled < 0) {
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+ };
+ ret = rpmh_regulator_read_data(vreg, &cmd);
+ /*
+ * Don't override if disabled since we will also vote the right voltage
+ * while enabling
+ */
+ if (!ret && cmd.data)
+ vreg->enabled = cmd.data & RPMH_REGULATOR_ENABLE_MASK;
+ }
+
return vreg->enabled > 0;
}
@@ -315,9 +369,11 @@ static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
}
if (bypassed)
- cmd.data = PMIC4_BOB_MODE_PASS;
+ // XXX: should have a version check for PMIC4 but we don't have any yet
+ // and we don't use bypass mode
+ cmd.data = PMIC5_BOB_MODE_PASS;
else
- cmd.data = pmic_mode->id;
+ cmd.data = pmic_mode->register_value;
return rpmh_regulator_send_request(vreg, &cmd, true);
}
@@ -340,12 +396,40 @@ static int rpmh_regulator_vrm_set_mode(struct udevice *rdev,
return ret;
}
+static int rpmh_regulator_vrm_get_pmic_mode(struct rpmh_vreg *vreg, int *pmic_mode)
+{
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+ };
+ struct dm_regulator_mode *pmic_mode_map = vreg->hw_data->pmic_mode_map;
+ int ret, register_value;
+
+ ret = rpmh_regulator_read_data(vreg, &cmd);
+ if (!ret)
+ register_value = cmd.data & RPMH_REGULATOR_MODE_MASK;
+ else
+ return -EINVAL;
+
+ for (int i = 0; i < vreg->hw_data->n_modes; i++) {
+ if (pmic_mode_map[i].register_value == register_value) {
+ *pmic_mode = pmic_mode_map[i].id;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
static int rpmh_regulator_vrm_get_mode(struct udevice *rdev)
{
struct rpmh_vreg *vreg = dev_get_priv(rdev);
+ int mode;
debug("%s: get_mode %d\n", rdev->name, vreg->mode);
+ if (!rpmh_regulator_vrm_get_pmic_mode(vreg, &mode))
+ vreg->mode = mode;
+
return vreg->mode;
}
static const struct dm_regulator_ops rpmh_regulator_vrm_drms_ops = {
@@ -402,6 +486,42 @@ static const struct rpmh_vreg_hw_data pmic5_bob = {
.n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_bob),
};
+static const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+ .n_voltages = 216,
+ .pmic_mode_map = pmic_mode_map_pmic5_smps,
+ .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps),
+};
+
+static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000),
+ .n_voltages = 236,
+ .pmic_mode_map = pmic_mode_map_pmic5_smps,
+ .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps),
+};
+
+static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
+ .n_voltages = 264,
+ .pmic_mode_map = pmic_mode_map_pmic5_smps,
+ .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps),
+};
+
+static const struct rpmh_vreg_hw_data pmic5_ftsmps520 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
+ .n_voltages = 264,
+ .pmic_mode_map = pmic_mode_map_pmic5_smps,
+ .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_smps),
+};
+
static const struct rpmh_vreg_hw_data pmic5_ftsmps525_lv = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_drms_ops,
@@ -521,7 +641,34 @@ static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = {
};
static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"),
+ RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"),
+ RPMH_VREG("smps4", "smp%s4", &pmic5_hfsmps510, "vdd-s4"),
+ RPMH_VREG("smps5", "smp%s5", &pmic5_hfsmps510, "vdd-s5"),
+ RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"),
+ RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"),
+ RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"),
+ RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"),
+ RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"),
+ RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l8-l11"),
+ RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l10"),
+ RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
+ RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
+ RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
+ RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9"),
+ RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l1-l8-l11"),
+ RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9"),
+ RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l2-l10"),
+ RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l1-l8-l11"),
+ RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"),
+ RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"),
+ RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"),
+ RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"),
{}
};
@@ -626,6 +773,65 @@ static const struct rpmh_vreg_init_data pmm8654au_vreg_data[] = {
{}
};
+static const struct rpmh_vreg_init_data pm8350c_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps515, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"),
+ RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps510, "vdd-s3"),
+ RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps510, "vdd-s4"),
+ RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps510, "vdd-s5"),
+ RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps510, "vdd-s6"),
+ RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps510, "vdd-s7"),
+ RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps510, "vdd-s8"),
+ RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps510, "vdd-s9"),
+ RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"),
+ RPMH_VREG("ldo1", "ldo%s1", &pmic5_pldo_lv, "vdd-l1-l12"),
+ RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo_lv, "vdd-l2-l8"),
+ RPMH_VREG("ldo3", "ldo%s3", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
+ RPMH_VREG("ldo4", "ldo%s4", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
+ RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
+ RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l6-l9-l11"),
+ RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
+ RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l2-l8"),
+ RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l6-l9-l11"),
+ RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l10"),
+ RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l6-l9-l11"),
+ RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l1-l12"),
+ RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l3-l4-l5-l7-l13"),
+ RPMH_VREG("bob", "bob%s1", &pmic5_bob, "vdd-bob"),
+ {}
+};
+
+static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"),
+ RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps520, "vdd-s3"),
+ RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps520, "vdd-s4"),
+ RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps520, "vdd-s5"),
+ RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps520, "vdd-s6"),
+ RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps520, "vdd-s7"),
+ RPMH_VREG("smps8", "smp%s8", &pmic5_hfsmps510, "vdd-s8"),
+ RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1-l4-l12-l15"),
+ RPMH_VREG("ldo2", "ldo%s2", &pmic5_pldo, "vdd-l2-l7"),
+ RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
+ RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l1-l4-l12-l15"),
+ RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5"),
+ RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l6-l9-l10"),
+ RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l2-l7"),
+ RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo, "vdd-l8"),
+ RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo, "vdd-l6-l9-l10"),
+ RPMH_VREG("ldo10", "ldo%s10", &pmic5_nldo, "vdd-l6-l9-l10"),
+ RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo, "vdd-l1-l4-l12-l15"),
+ RPMH_VREG("ldo13", "ldo%s13", &pmic5_nldo, "vdd-l13"),
+ RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo, "vdd-l14-l16"),
+ RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo, "vdd-l1-l4-l12-l15"),
+ RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo, "vdd-l14-l16"),
+ RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ {}
+};
+
/* probe an individual regulator */
static int rpmh_regulator_probe(struct udevice *dev)
{
@@ -737,6 +943,10 @@ static const struct udevice_id rpmh_regulator_ids[] = {
.data = (ulong)pm6150l_vreg_data,
},
{
+ .compatible = "qcom,pm7325-rpmh-regulators",
+ .data = (ulong)pm7325_vreg_data,
+ },
+ {
.compatible = "qcom,pm8150-rpmh-regulators",
.data = (ulong)pm8150_vreg_data,
},
@@ -745,6 +955,10 @@ static const struct udevice_id rpmh_regulator_ids[] = {
.data = (ulong)pm8150l_vreg_data,
},
{
+ .compatible = "qcom,pm8350c-rpmh-regulators",
+ .data = (ulong)pm8350c_vreg_data,
+ },
+ {
.compatible = "qcom,pm8550-rpmh-regulators",
.data = (ulong)pm8550_vreg_data,
},
diff --git a/drivers/smem/msm_smem.c b/drivers/smem/msm_smem.c
index ccd145f9afb..b6b92d3530d 100644
--- a/drivers/smem/msm_smem.c
+++ b/drivers/smem/msm_smem.c
@@ -88,7 +88,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define SMEM_GLOBAL_HOST 0xfffe
/* Max number of processors/hosts in a system */
-#define SMEM_HOST_COUNT 10
+#define SMEM_HOST_COUNT 25
/**
* struct smem_proc_comm - proc_comm communication struct (legacy)
@@ -821,23 +821,34 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
static int qcom_smem_map_memory(struct qcom_smem *smem, struct udevice *dev,
const char *name, int i)
{
- struct fdt_resource r;
int ret;
- int node = dev_of_offset(dev);
+ struct ofnode_phandle_args args;
+ struct resource r;
- ret = fdtdec_lookup_phandle(gd->fdt_blob, node, name);
- if (ret < 0) {
- dev_err(dev, "No %s specified\n", name);
+ if (!dev_read_prop(dev, name, NULL)) {
+ dev_err(dev, "%s prop not found\n", name);
return -EINVAL;
}
- ret = fdt_get_resource(gd->fdt_blob, ret, "reg", 0, &r);
- if (ret)
- return ret;
+ ret = dev_read_phandle_with_args(dev, name, NULL, 0, 0, &args);
+ if (ret) {
+ dev_err(dev, "%s phandle read failed\n", name);
+ return -EINVAL;
+ }
+ if (!ofnode_valid(args.node)) {
+ dev_err(dev, "Invalid node from phandle args\n");
+ return -EINVAL;
+ }
+
+ ret = ofnode_read_resource(args.node, 0, &r);
+ if (ret) {
+ dev_err(dev, "Can't get mmap base address(%d)\n", ret);
+ return ret;
+ }
smem->regions[i].aux_base = (u32)r.start;
- smem->regions[i].size = fdt_resource_size(&r);
- smem->regions[i].virt_base = devm_ioremap(dev, r.start, fdt_resource_size(&r));
+ smem->regions[i].size = resource_size(&r);
+ smem->regions[i].virt_base = devm_ioremap(dev, r.start, resource_size(&r));
if (!smem->regions[i].virt_base)
return -ENOMEM;
@@ -852,10 +863,14 @@ static int qcom_smem_probe(struct udevice *dev)
int num_regions;
u32 version;
int ret;
- int node = dev_of_offset(dev);
+ fdt_addr_t addr;
+ fdt_size_t size;
+
+ if (__smem)
+ return 0;
num_regions = 1;
- if (fdtdec_lookup_phandle(gd->fdt_blob, node, "qcomrpm-msg-ram") >= 0)
+ if (dev_read_prop(dev, "qcom,rpm-msg-ram", NULL))
num_regions++;
array_size = num_regions * sizeof(struct smem_region);
@@ -866,9 +881,18 @@ static int qcom_smem_probe(struct udevice *dev)
smem->dev = dev;
smem->num_regions = num_regions;
- ret = qcom_smem_map_memory(smem, dev, "memory-region", 0);
- if (ret)
- return ret;
+ addr = dev_read_addr_size(dev, &size);
+ if (addr == FDT_ADDR_T_NONE) {
+ ret = qcom_smem_map_memory(smem, dev, "memory-region", 0);
+ if (ret)
+ return ret;
+ } else {
+ smem->regions[0].aux_base = (u32)addr;
+ smem->regions[0].size = size;
+ smem->regions[0].virt_base = devm_ioremap(dev, addr, size);
+ if (!smem->regions[0].virt_base)
+ return -ENOMEM;
+ }
if (num_regions > 1) {
ret = qcom_smem_map_memory(smem, dev,
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index aee9e55194e..dce61f26229 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -36,15 +36,31 @@
enum {
RSC_DRV_TCS_OFFSET,
RSC_DRV_CMD_OFFSET,
+/* DRV HW Solver Configuration Information Register */
DRV_SOLVER_CONFIG,
+/* DRV TCS Configuration Information Register */
DRV_PRNT_CHLD_CONFIG,
+/* Offsets for common TCS Registers, one bit per TCS */
RSC_DRV_IRQ_ENABLE,
RSC_DRV_IRQ_STATUS,
- RSC_DRV_IRQ_CLEAR,
- RSC_DRV_CMD_WAIT_FOR_CMPL,
+ RSC_DRV_IRQ_CLEAR, /* w/o; write 1 to clear */
+/*
+ * Offsets for per TCS Registers.
+ *
+ * TCSes start at 0x10 from tcs_base and are stored one after another.
+ * Multiply tcs_id by RSC_DRV_TCS_OFFSET to find a given TCS and add one
+ * of the below to find a register.
+ */
+ RSC_DRV_CMD_WAIT_FOR_CMPL, /* 1 bit per command */
RSC_DRV_CONTROL,
- RSC_DRV_STATUS,
- RSC_DRV_CMD_ENABLE,
+ RSC_DRV_STATUS, /* zero if tcs is busy */
+ RSC_DRV_CMD_ENABLE, /* 1 bit per command */
+/*
+ * Offsets for per command in a TCS.
+ *
+ * Commands (up to 16) start at 0x30 in a TCS; multiply command index
+ * by RSC_DRV_CMD_OFFSET and add one of the below to find a register.
+ */
RSC_DRV_CMD_MSGID,
RSC_DRV_CMD_ADDR,
RSC_DRV_CMD_DATA,
@@ -266,31 +282,41 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
const struct tcs_request *msg)
{
u32 msgid;
- u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE;
+ u32 cmd_msgid = CMD_MSGID_LEN;
u32 cmd_enable = 0;
+ u32 cmd_complete = 0;
struct tcs_cmd *cmd;
int i, j;
+ if (!msg->is_read)
+ cmd_msgid |= CMD_MSGID_WRITE;
+
+ if (msg->wait_for_compl)
+ cmd_msgid |= CMD_MSGID_RESP_REQ;
+
+ cmd_complete = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id);
+
for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) {
cmd = &msg->cmds[i];
cmd_enable |= BIT(j);
+ /* U-Boot: always wait for completion */
+ cmd_complete |= (!!msg->wait_for_compl) << j;
msgid = cmd_msgid;
- /*
- * Additionally, if the cmd->wait is set, make the command
- * response reqd even if the overall request was fire-n-forget.
- */
- msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0;
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr);
- write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
- debug("tcs(m): %d [%s] cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d\n",
+ if (!msg->is_read)
+ write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
+ debug("tcs(%d): [%s] cmd_id: %d: msgid: %#x addr: %#x data: %#x complete: %#x\n",
tcs_id, msg->state == RPMH_ACTIVE_ONLY_STATE ? "active" : "?", j, msgid,
- cmd->addr, cmd->data, cmd->wait);
+ cmd->addr, cmd->data, cmd_complete);
}
cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id);
write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable);
+ /* U-Boot: Tell the DRV to wait for completion (?) so we can poll on DRV_STATUS */
+ /* This register applies to the entire TCS group not per command */
+ write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, cmd_complete);
}
/**
@@ -360,26 +386,22 @@ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
{
struct tcs_group *tcs;
- int tcs_id, i;
- u32 addr;
+ int tcs_id, i = 0;
+ u32 val;
tcs = get_tcs_for_msg(drv, msg);
if (IS_ERR(tcs))
return PTR_ERR(tcs);
- /* u-boot is single-threaded, always use the first TCS as we'll never conflict */
+ /* U-Boot is single-threaded, always use the first TCS as we'll never conflict */
tcs_id = tcs->offset;
+ if (!read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id)) {
+ pr_err("%s: TCS %d is busy!\n", __func__, tcs_id);
+ return -EBUSY;
+ }
tcs->req[tcs_id - tcs->offset] = msg;
generic_set_bit(tcs_id, drv->tcs_in_use);
- if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
- /*
- * Clear previously programmed WAKE commands in selected
- * repurposed TCS to avoid triggering them. tcs->slots will be
- * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
- */
- write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
- }
/*
* These two can be done after the lock is released because:
@@ -392,14 +414,27 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
__tcs_buffer_write(drv, tcs_id, 0, msg);
__tcs_set_trigger(drv, tcs_id, true);
- /* U-Boot: Now wait for the TCS to be cleared, indicating that we're done */
+ /* U-Boot: Now wait for the TCS to be cleared, indicating that we're done. */
for (i = 0; i < USEC_PER_SEC; i++) {
- addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, 0);
- if (addr != msg->cmds[0].addr)
+ val = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_STATUS], tcs_id, 0);
+ if (val & CMD_STATUS_COMPL)
break;
udelay(1);
}
+ /* U-Boot: read the response now we know it's available */
+ if (msg->is_read) {
+ msg->cmds[0].data = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_RESP_DATA], tcs_id, 0);
+ log_debug("data response: %#x\n", msg->cmds[0].data);
+ }
+
+ __tcs_set_trigger(drv, tcs_id, false);
+
+ /* Reclaim the TCS */
+ write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
+ writel_relaxed(BIT(tcs_id), drv->tcs_base + drv->regs[RSC_DRV_IRQ_CLEAR]);
+ generic_clear_bit(tcs_id, drv->tcs_in_use);
+
if (i == USEC_PER_SEC) {
log_err("%s: error writing %#x to %d:%#x\n", drv->name,
msg->cmds[0].addr, tcs_id, drv->regs[RSC_DRV_CMD_ADDR]);
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index 96f14a9afdf..8c222324c66 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -22,6 +22,7 @@
.state = s, \
.cmds = name.cmd, \
.num_cmds = 0, \
+ .wait_for_compl = true \
}, \
.cmd = { { 0 } }, \
.dev = device, \
@@ -67,7 +68,7 @@ static int __rpmh_write(const struct udevice *dev, enum rpmh_state state,
}
static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
- const struct tcs_cmd *cmd, u32 n)
+ const struct tcs_cmd *cmd, u32 n, bool is_read)
{
if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
return -EINVAL;
@@ -77,6 +78,7 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
req->msg.state = state;
req->msg.cmds = req->cmd;
req->msg.num_cmds = n;
+ req->msg.is_read = is_read;
debug("rpmh_msg: %d, %d cmds [first %#x/%#x]\n", state, n, cmd->addr, cmd->data);
@@ -84,6 +86,38 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
}
/**
+ * rpmh_read: Read a resource value
+ *
+ * @dev: The device making the request
+ * @cmd: The payload having address of resource to read
+ *
+ * Reads the value for the resource address given in tcs_cmd->addr
+ * and returns the tcs_cmd->data filled with same.
+ *
+ * May sleep. Do not call from atomic contexts.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd)
+{
+ DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg);
+ int ret;
+
+ ret = __fill_rpmh_msg(&rpm_msg, state, cmd, 1, true);
+ if (ret)
+ return ret;
+
+ ret = __rpmh_write(dev, state, &rpm_msg);
+ if (ret)
+ return ret;
+
+ /* Read back the response into the cmd data structure */
+ cmd->data = rpm_msg.cmd[0].data;
+
+ return (ret > 0) ? 0 : ret;
+}
+
+/**
* rpmh_write: Write a set of RPMH commands and block until response
*
* @dev: The device making the request
@@ -99,7 +133,7 @@ int rpmh_write(const struct udevice *dev, enum rpmh_state state,
DEFINE_RPMH_MSG_ONSTACK(dev, state, rpm_msg);
int ret;
- ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
+ ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n, false);
if (ret)
return ret;
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index faae54e9fef..f3cd98c3db8 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -274,10 +274,25 @@ static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i,
priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
if (owner != priv->owner)
priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY;
- } else if ((owner == priv->owner) && prev_read_only) {
- /* Read only and we found one we own, switch */
+
+ } else if (owner == priv->owner) {
+ /*
+ * Found a channel owned by our EE - ALWAYS switch to it!
+ * even if we already have a mapping, we must prefer the one
+ * owned by our EE to avoid hardware access violations.
+ */
priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
+ /* Clear READ_ONLY flag since we own this channel */
+
+ } else if (prev_read_only) {
+ /*
+ * Previous mapping was read-only and this one is also not ours.
+ * Update to this channel.
+ */
+ priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID | SPMI_CHANNEL_READ_ONLY;
+
}
+ /* else: Previous was writable and owned by us, this one isn't - keep previous */
}
static int msm_spmi_probe(struct udevice *dev)
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index bb11613a587..22b9ef0b24e 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -461,9 +461,13 @@ static void dwc3_qcom_select_utmi_clk(void __iomem *qscratch_base)
setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
PIPE_UTMI_CLK_DIS);
+ udelay(100);
+
setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
+ udelay(100);
+
clrbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
PIPE_UTMI_CLK_DIS);
}
@@ -472,7 +476,14 @@ static void dwc3_qcom_glue_configure(struct udevice *dev, int index,
enum usb_dr_mode mode)
{
struct dwc3_glue_data *glue = dev_get_plat(dev);
- void __iomem *qscratch_base = map_physmem(glue->regs, 0x400, MAP_NOCACHE);
+ fdt_addr_t regs = glue->regs;
+ void __iomem *qscratch_base;
+
+ /* Offset for qscratch base when using flat DT */
+ if (device_is_compatible(dev, "qcom,snps-dwc3"))
+ regs += SDM845_QSCRATCH_BASE_OFFSET;
+
+ qscratch_base = map_physmem(regs, 0x400, MAP_NOCACHE);
if (IS_ERR_OR_NULL(qscratch_base)) {
log_err("%s: Invalid qscratch base address\n", dev->name);
return;
@@ -485,11 +496,8 @@ static void dwc3_qcom_glue_configure(struct udevice *dev, int index,
dwc3_qcom_vbus_override_enable(qscratch_base, true);
}
-struct dwc3_glue_ops qcom_ops = {
- .glue_configure = dwc3_qcom_glue_configure,
-};
-
-static int dwc3_rk_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
+/* In cases where there is no dwc3 node and it's flattened into the glue node */
+static int dwc3_flat_dt_get_ctrl_dev(struct udevice *dev, ofnode *node)
{
*node = dev_ofnode(dev);
if (!ofnode_valid(*node))
@@ -498,8 +506,17 @@ static int dwc3_rk_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
return 0;
}
+struct dwc3_glue_ops qcom_ops = {
+ .glue_configure = dwc3_qcom_glue_configure,
+};
+
+struct dwc3_glue_ops qcom_flat_dt_ops = {
+ .glue_configure = dwc3_qcom_glue_configure,
+ .glue_get_ctrl_dev = dwc3_flat_dt_get_ctrl_dev,
+};
+
struct dwc3_glue_ops rk_ops = {
- .glue_get_ctrl_dev = dwc3_rk_glue_get_ctrl_dev,
+ .glue_get_ctrl_dev = dwc3_flat_dt_get_ctrl_dev,
};
static int dwc3_glue_bind_common(struct udevice *parent, ofnode node)
@@ -708,6 +725,7 @@ static const struct udevice_id dwc3_glue_ids[] = {
{ .compatible = "rockchip,rk3576-dwc3", .data = (ulong)&rk_ops },
{ .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops },
{ .compatible = "qcom,dwc3", .data = (ulong)&qcom_ops },
+ { .compatible = "qcom,snps-dwc3", .data = (ulong)&qcom_flat_dt_ops },
{ .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops },
{ .compatible = "fsl,imx8mq-dwc3" },
{ .compatible = "intel,tangier-dwc3" },
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7e08aeab904..ebb306852a6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -61,7 +61,7 @@ config USB_GADGET_VENDOR_NUM
default 0x0955 if ARCH_TEGRA
default 0x1f3a if ARCH_SUNXI
default 0x2207 if ARCH_ROCKCHIP
- default 0x18d1 if ARCH_QCOM
+ default 0x18d1 if ARCH_SNAPDRAGON
default 0x0
help
Vendor ID of the USB device emulated, reported to the host device.
@@ -89,7 +89,7 @@ config USB_GADGET_PRODUCT_NUM
default 0x350b if ROCKCHIP_RK3588
default 0x350c if ROCKCHIP_RK3528
default 0x350e if ROCKCHIP_RK3576
- default 0x4ee0 if ARCH_QCOM
+ default 0x4ee0 if ARCH_SNAPDRAGON
default 0x0
help
Product ID of the USB device emulated, reported to the host device.
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 4b972cff72c..e4ebb1f31d4 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -17,6 +17,9 @@
#include <asm/io.h>
+/* Maximum allowed timeout value in Qcom SoCs*/
+#define QCOM_WDT_MAX_TIMEOUT 0xfffff
+
enum wdt_reg {
WDT_RST,
WDT_EN,
@@ -55,8 +58,24 @@ static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
struct qcom_wdt *wdt = dev_get_priv(dev);
- ulong bark_timeout_s = ((timeout_ms - 1) * wdt->clk_rate) / 1000;
- ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000;
+ u64 tmp_timeout;
+ u32 bark_timeout_s, bite_timeout_s;
+
+ /* Compute timeout in watchdog ticks */
+ tmp_timeout = (timeout_ms * (u64)wdt->clk_rate) / 1000;
+ if (tmp_timeout > QCOM_WDT_MAX_TIMEOUT) {
+ dev_warn(dev,
+ "Requested timeout (%llu ms) exceeds maximum allowed value (%llu ms). "
+ "Using max timeout instead.\n",
+ timeout_ms,
+ ((u64)QCOM_WDT_MAX_TIMEOUT * 1000) / wdt->clk_rate);
+ tmp_timeout = (u32)QCOM_WDT_MAX_TIMEOUT;
+ timeout_ms = (tmp_timeout * 1000) / wdt->clk_rate;
+ }
+
+ bite_timeout_s = (u32)tmp_timeout;
+ tmp_timeout = ((timeout_ms - 1) * (u64)wdt->clk_rate) / 1000;
+ bark_timeout_s = (u32)tmp_timeout;
writel(0, wdt_addr(wdt, WDT_EN));
writel(BIT(0), wdt_addr(wdt, WDT_RST));