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
This commit is contained in:
Tom Rini 2026-01-16 15:14:37 -06:00
commit ff498a3c5e
30 changed files with 1195 additions and 104 deletions

View File

@ -1143,6 +1143,7 @@ config ARCH_SNAPDRAGON
select SYSRESET
select SYSRESET_PSCI
select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR
select MMU_PGPROT
imply OF_UPSTREAM
imply CMD_DM
imply DM_USB_GADGET

View File

@ -13,6 +13,7 @@
#include <efi.h>
#include <efi_loader.h>
#include <malloc.h>
#include <mmc.h>
#include <scsi.h>
#include <part.h>
#include <linux/err.h>
@ -80,6 +81,23 @@ static enum ab_slot get_part_slot(const char *partname)
return SLOT_NONE;
}
/* Shamelessly copied from lib/efi_loader/efi_device_path.c @ 33 */
/*
* Determine if an MMC device is an SD card.
*
* @desc block device descriptor
* Return: true if the device is an SD card
*/
static bool is_sd(struct blk_desc *desc)
{
struct mmc *mmc = find_mmc_device(desc->devnum);
if (!mmc)
return false;
return IS_SD(mmc) != 0U;
}
/*
* Determine which partition U-Boot is flashed to based on the boot source (ABL/XBL),
* the slot status, and prioritizing the uefi partition over xbl if found.
@ -109,19 +127,21 @@ static int find_target_partition(int *devnum, enum uclass_id *uclass,
if (device_get_uclass_id(dev) != UCLASS_BLK)
continue;
desc = dev_get_uclass_plat(dev);
/* If we have a UFS then don't look at any other block devices */
if (have_ufs) {
if (device_get_uclass_id(dev->parent->parent) != UCLASS_UFS)
continue;
}
/*
* If we don't have UFS, then U-Boot must be on the eMMC which is always the first
* MMC device.
* If we don't have UFS, then U-Boot must be on the eMMC
*/
} else if (dev->parent->seq_ > 0) {
else if (IS_ENABLED(CONFIG_MMC) && is_sd(desc)) {
log_debug("skipped SD-Card (devnum %d)\n", desc->devnum);
continue;
}
desc = dev_get_uclass_plat(dev);
if (!desc || desc->part_type == PART_TYPE_UNKNOWN)
continue;
for (partnum = 1;; partnum++) {

View File

@ -32,7 +32,7 @@
* DT here. This improves compatibility with upstream DT and simplifies the
* porting process for new devices.
*/
static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np)
static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np, bool flat)
{
struct device_node *dwc3;
int ret, len, hsphy_idx = 1;
@ -41,6 +41,19 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
debug("Fixing up %s\n", glue_np->name);
/* New DT flattens the glue and controller into a single node. */
if (flat) {
dwc3 = glue_np;
debug("%s uses flat DT\n", glue_np->name);
} else {
/* Find the DWC3 node itself */
dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3");
if (!dwc3) {
log_err("Failed to find dwc3 node\n");
return -ENOENT;
}
}
/* Tell the glue driver to configure the wrapper for high-speed only operation */
ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
if (ret) {
@ -48,13 +61,6 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
return ret;
}
/* Find the DWC3 node itself */
dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3");
if (!dwc3) {
log_err("Failed to find dwc3 node\n");
return -ENOENT;
}
phandles = of_get_property(dwc3, "phys", &len);
len /= sizeof(*phandles);
if (len == 1) {
@ -104,13 +110,25 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np
static void fixup_usb_nodes(struct device_node *root)
{
struct device_node *glue_np = root;
struct device_node *glue_np = root, *tmp;
int ret;
bool flat;
while (true) {
flat = false;
/* First check for the old DT format with glue node then the new flattened format */
tmp = of_find_compatible_node(glue_np, NULL, "qcom,dwc3");
if (!tmp) {
tmp = of_find_compatible_node(glue_np, NULL, "qcom,snps-dwc3");
flat = !!tmp;
}
if (!tmp)
break;
glue_np = tmp;
while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) {
if (!of_device_is_available(glue_np))
continue;
ret = fixup_qcom_dwc3(root, glue_np);
ret = fixup_qcom_dwc3(root, glue_np, flat);
if (ret)
log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
}

View File

@ -0,0 +1,5 @@
# Enables chainloading of U-Boot on Google Pixel phones using
# newer bootloaders (Android Q/R)
# Use for following devices: Pixel 3 (blueline), Pixel 3 XL (crosshatch),
# Pixel 5 (redfin)...
CONFIG_TEXT_BASE=0x80080000

View File

@ -13,3 +13,5 @@ CONFIG_TEXT_BASE=0x9fc00000
CONFIG_REMAKE_ELF=y
CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs6490-rb3gen2"
CONFIG_FASTBOOT_BUF_ADDR=0xd8800000

View File

@ -113,23 +113,7 @@ CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
CONFIG_PHY_QCOM_SNPS_EUSB2=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_QCOM_APQ8016=y
CONFIG_PINCTRL_QCOM_APQ8096=y
CONFIG_PINCTRL_QCOM_QCM2290=y
CONFIG_PINCTRL_QCOM_QCS404=y
CONFIG_PINCTRL_QCOM_SA8775P=y
CONFIG_PINCTRL_QCOM_SC7280=y
CONFIG_PINCTRL_QCOM_SDM670=y
CONFIG_PINCTRL_QCOM_SDM660=y
CONFIG_PINCTRL_QCOM_SDM845=y
CONFIG_PINCTRL_QCOM_SM6115=y
CONFIG_PINCTRL_QCOM_SM6350=y
CONFIG_PINCTRL_QCOM_SM7150=y
CONFIG_PINCTRL_QCOM_SM8150=y
CONFIG_PINCTRL_QCOM_SM8250=y
CONFIG_PINCTRL_QCOM_SM8550=y
CONFIG_PINCTRL_QCOM_SM8650=y
CONFIG_PINCTRL_QCOM_X1E80100=y
CONFIG_PINCTRL_QCOM_GENERIC=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_QCOM=y
CONFIG_DM_REGULATOR=y

View File

@ -12,7 +12,7 @@ CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_DEBUG_UART_BASE=0x880000
CONFIG_DEBUG_UART_MSM_GENI=y
CONFIG_DEBUG_UART_CLOCK=14745600
CONFIG_DEBUG_UART_CLOCK=7372800
CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs615-ride"
@ -20,3 +20,5 @@ CONFIG_REMAKE_ELF=y
# Address where U-Boot will be loaded
CONFIG_TEXT_BASE=0x9fc00000
CONFIG_FASTBOOT_BUF_ADDR=0xa1600000

View File

@ -8,6 +8,7 @@
# Address where U-Boot will be loaded
CONFIG_TEXT_BASE=0xaf000000
CONFIG_REMAKE_ELF=y
CONFIG_FASTBOOT_BUF_ADDR=0xdb300000
CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs9100-ride-r3"
CONFIG_ENV_IS_IN_SCSI=y
CONFIG_SCSI_ENV_PART_UUID="71cb9cd0-acf1-b6cb-ad91-be9572fe11a9"

View File

@ -38,6 +38,25 @@ with appended dtb, so let's mimic linux to satisfy stock bootloader.
Boards
------
Pixel 3 (blueline) and Pixel 3 XL (crosshatch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
blueline refers to the Google Pixel 3, and crosshatch to the Pixel 3 XL, both
powered by the Qualcomm SDM845 SoC.
These devices use the common qcom_defconfig with the google-pixel.config
fragment for configuration.
Use the following commands::
make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig google-pixel.config qcom-phone.config
The DTB is called:
- "sdm845-google-blueline.dtb" (Pixel 3)
- "sdm845-google-crosshatch.dtb" (Pixel 3 XL)
More information can be found on the `Google Pixel 3 page`_.
starqlte
^^^^^^^^
@ -131,5 +150,6 @@ Other devices with boot image version 2 can be built like this example::
fastboot flash boot boot.img
fastboot erase dtbo
.. _Google Pixel 3 page: https://en.wikipedia.org/wiki/Pixel_3
.. _Samsung S9 page: https://en.wikipedia.org/wiki/Samsung_Galaxy_S9
.. _DragonBoard 845c page: https://www.96boards.org/product/rb3-platform/

View File

@ -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;
}

View File

@ -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[] = {

View File

@ -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);

View File

@ -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;

View File

@ -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,
};

View File

@ -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 },

View File

@ -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;
}

View File

@ -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,

View File

@ -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

View File

@ -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,
};

View File

@ -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)
{
@ -736,6 +942,10 @@ static const struct udevice_id rpmh_regulator_ids[] = {
.compatible = "qcom,pm6150l-rpmh-regulators",
.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,
@ -744,6 +954,10 @@ static const struct udevice_id rpmh_regulator_ids[] = {
.compatible = "qcom,pm8150l-rpmh-regulators",
.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,

View File

@ -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,

View File

@ -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]);

View File

@ -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,12 +78,45 @@ 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);
return 0;
}
/**
* 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
*
@ -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;

View File

@ -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)

View File

@ -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" },

View File

@ -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.

View File

@ -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));

View File

@ -27,7 +27,6 @@
#define CFG_EXTRA_ENV_SETTINGS \
"loadaddr=0x95000000\0" \
"fdt_high=0xffffffffffffffff\0" \
"initrd_high=0xffffffffffffffff\0" \
"linux_image=uImage\0" \
"kernel_addr_r=0x95000000\0"\

View File

@ -13,12 +13,14 @@
#if IS_ENABLED(CONFIG_QCOM_RPMH)
int rpmh_write(const struct udevice *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n);
int rpmh_read(const struct udevice *dev, enum rpmh_state state, struct tcs_cmd *cmd);
#else
static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
const struct tcs_cmd *cmd, u32 n)
{ return -ENODEV; }
static inline int rpmh_read(const struct udevice *dev, struct tcs_cmd *cmd)
{ return -ENODEV; }
#endif /* CONFIG_QCOM_RPMH */

View File

@ -55,6 +55,7 @@ struct tcs_cmd {
*/
struct tcs_request {
enum rpmh_state state;
bool is_read;
u32 wait_for_compl;
u32 num_cmds;
struct tcs_cmd *cmds;