From a6c88ca805c6a5b13aa92f8b8ba6e3ca63522948 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 28 Mar 2025 11:40:07 +0100 Subject: qcom_defconfig: enable OF_UPSTREAM_BUILD_VENDOR A single U-Boot binary can be run on many different Qualcomm boards just by booting with a different DTB. Simplify the build process for this by enabling OF_UPSTREAM_BUILD_VENDOR so that all the DTBs will be available after building U-Boot once. Acked-by: Ilias Apalodimas Acked-by: Christopher Obbard Link: https://lore.kernel.org/r/20250328104011.1837872-1-caleb.connolly@linaro.org Signed-off-by: Caleb Connolly --- configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index ba4d38d100e..a12a5d17b40 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -41,6 +41,7 @@ CONFIG_CMD_RNG=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_LOG=y CONFIG_OF_LIVE=y +CONFIG_OF_UPSTREAM_BUILD_VENDOR=y CONFIG_USE_DEFAULT_ENV_FILE=y CONFIG_DEFAULT_ENV_FILE="board/qualcomm/default.env" CONFIG_BUTTON_QCOM_PMIC=y -- cgit v1.3.1 From ec2850e40ceb182b81d7ad74686d96585fbedebc Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Tue, 25 Mar 2025 11:37:13 +0300 Subject: phy: Add SDM660 support to Qualcomm QUSB2 phy Imported from Linux driver. Note that already existing but previously unused member of struct qusb2_phy::has_se_clk_scheme is now utilized for it's purpose. Signed-off-by: Alexey Minnekhanov Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250325083713.2425430-1-alexeymin@postmarketos.org Signed-off-by: Caleb Connolly --- drivers/phy/qcom/phy-qcom-qusb2.c | 42 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qcom/phy-qcom-qusb2.c b/drivers/phy/qcom/phy-qcom-qusb2.c index c91ba18c4ab..cabd05bf5a6 100644 --- a/drivers/phy/qcom/phy-qcom-qusb2.c +++ b/drivers/phy/qcom/phy-qcom-qusb2.c @@ -122,6 +122,9 @@ struct qusb2_phy_cfg { /* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */ bool has_pll_override; + + /* true if PHY default clk scheme is single-ended */ + bool se_clk_scheme_default; }; /* set of registers with offsets different per-PHY */ @@ -173,6 +176,19 @@ static const unsigned int sm6115_regs_layout[] = { [QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc, }; +static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = { + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8), + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3), + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83), + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21), + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00), +}; + static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = { QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03), QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c), @@ -219,6 +235,18 @@ static const struct qusb2_phy_cfg sm6115_phy_cfg = { .autoresume_en = BIT(3), }; +static const struct qusb2_phy_cfg sdm660_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 = false, + .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN), + .mask_core_ready = PLL_LOCKED, + .autoresume_en = BIT(3), +}; + static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = { .tbl = qusb2_v2_init_tbl, .tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl), @@ -316,8 +344,18 @@ static int qusb2phy_power_on(struct phy *phy) /* Required to get phy pll lock successfully */ udelay(150); + /* + * Not all the SoCs have got a readable TCSR_PHY_CLK_SCHEME + * register in the TCSR so, if there's none, use the default + * value hardcoded in the configuration. + */ + qphy->has_se_clk_scheme = cfg->se_clk_scheme_default; + if (cfg->has_pll_test) { - val |= CLK_REF_SEL; + if (!qphy->has_se_clk_scheme) + val &= ~CLK_REF_SEL; + else + val |= CLK_REF_SEL; writel(val, qphy->base + QUSB2PHY_PLL_TEST); @@ -413,6 +451,8 @@ static const struct udevice_id qusb2phy_ids[] = { { .compatible = "qcom,qusb2-phy" }, { .compatible = "qcom,qcm2290-qusb2-phy", .data = (ulong)&sm6115_phy_cfg }, + { .compatible = "qcom,sdm660-qusb2-phy", + .data = (ulong)&sdm660_phy_cfg }, { .compatible = "qcom,sm6115-qusb2-phy", .data = (ulong)&sm6115_phy_cfg }, { .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg }, -- cgit v1.3.1 From ec8209d04a46546c3e58752544413158aebbfae2 Mon Sep 17 00:00:00 2001 From: Sam Day Date: Wed, 19 Mar 2025 15:45:29 +0000 Subject: clk/qcom: sdm845: add missing USB3 clocks These are necessary for USB gadget to come up properly, now that qcom_gate_clk_en fails on unknown clocks. Signed-off-by: Sam Day Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250319-sdm845-usb-clocks-v1-1-ddea854f62ec@samcday.com Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-sdm845.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 6a0bf16ba2d..7fd875e55d5 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -77,7 +77,9 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate) } static const struct gate_clk sdm845_clks[] = { + GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x8201c, 0x00000001), GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x82020, 0x00000001), + GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0502c, 0x00000001), GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x05030, 0x00000001), GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, 0x00000400), GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, 0x00000800), -- cgit v1.3.1 From 7c07628e5b5ad6a2914613fb3e83797280567ce9 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 24 Mar 2025 19:17:37 +0100 Subject: clk/stub: add sdm845 rpmh clock Necessary for UFS to successfully probe all clocks. Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250324-sdm845-fixes-fastboot-v1-1-d177a10f336d@linaro.org Signed-off-by: Caleb Connolly --- drivers/clk/clk-stub.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c index 343fa5cd3fe..521ecfc5917 100644 --- a/drivers/clk/clk-stub.c +++ b/drivers/clk/clk-stub.c @@ -50,6 +50,7 @@ static struct clk_ops stub_clk_ops = { static const struct udevice_id stub_clk_ids[] = { { .compatible = "qcom,rpmcc" }, + { .compatible = "qcom,sdm845-rpmh-clk" }, { .compatible = "qcom,sc7280-rpmh-clk" }, { .compatible = "qcom,sm8150-rpmh-clk" }, { .compatible = "qcom,sm8250-rpmh-clk" }, -- cgit v1.3.1 From c8db6bdba6dc4ca5f9570994c8640ba08a27e62e Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 24 Mar 2025 19:17:38 +0100 Subject: clk/qcom: sdm845: add GCC_AGGRE_UFS_PHY_AXI_CLK Missing for UFS. Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250324-sdm845-fixes-fastboot-v1-2-d177a10f336d@linaro.org Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-sdm845.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index 7fd875e55d5..5c8702ef2fe 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -114,6 +114,7 @@ static const struct gate_clk sdm845_clks[] = { GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x75014, 0x00000001), GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x75054, 0x00000001), GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, 0x00000001), + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x82024, 0x00000001), GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77010, 0x00000001), GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x7700c, 0x00000001), GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77058, 0x00000001), -- cgit v1.3.1 From 520f26425bb01c2fd471d0b8efd89bad5671a3b0 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 24 Mar 2025 19:17:39 +0100 Subject: mach-snapdragon: enable DM_USB_GADGET by default This is required for gadget modes to work on most platforms. It must be disabled for dragonboard410c since that doesn't use dwc3. USB on other MSM8916 platforms isn't supported by qcom_defconfig anyway. Link: https://lore.kernel.org/r/20250324-sdm845-fixes-fastboot-v1-3-d177a10f336d@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/Kconfig | 1 + configs/dragonboard410c_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b7311d3b754..6e234af4ac9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1126,6 +1126,7 @@ config ARCH_SNAPDRAGON select SYSRESET_PSCI imply OF_UPSTREAM imply CMD_DM + imply DM_USB_GADGET config ARCH_SOCFPGA bool "Altera SOCFPGA family" diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 967817f4f58..5870aae83b4 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -60,6 +60,7 @@ CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_USB=y +# CONFIG_DM_USB_GADGET is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MSM=y CONFIG_USB_ULPI_VIEWPORT=y -- cgit v1.3.1 From 32ad75f7873cd05800a6ec1be9c5abcd5c9dcd35 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 24 Mar 2025 19:17:40 +0100 Subject: qcom_defconfig: enable fastboot Enable fastboot support over USB, using MMC as the backend. This will be the internal eMMC on devices that have it, or the sdcard slot on devices with UFS (if available). We don't use a fixed address for the fastboot buffer because it's allocated at runtime per-board. Entering fastboot mode should be done by executing "run fastboot" or manually running: fastboot -l $fastboot_addr_r usb 0 Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250324-sdm845-fixes-fastboot-v1-4-d177a10f336d@linaro.org Signed-off-by: Caleb Connolly --- configs/qcom_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index a12a5d17b40..3dce271ee2d 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -63,6 +63,11 @@ CONFIG_CLK_QCOM_X1E80100=y CONFIG_DFU_MMC=y CONFIG_DFU_SCSI=y CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000 +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x0 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_MMC_USER_SUPPORT=y CONFIG_MSM_GPIO=y CONFIG_QCOM_PMIC_GPIO=y CONFIG_DM_I2C=y -- cgit v1.3.1 From 1542c090ee0081abbb126c31f9a12cb3afe86ad8 Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Thu, 27 Feb 2025 09:45:49 +0000 Subject: mach-snapdragon: of_fixup: fix property length at writing The length of a property includes '\0' in a string type one, so the length passed by needs to have that in account, if not, when getting the property value it will fail because it has the wrong size. Signed-off-by: Rui Miguel Silva Tested-by: caleb.connolly@linaro.org # db845c Reviewed-by: Caleb Connolly Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250227094911.497219-2-rui.silva@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/mach-snapdragon/of_fixup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index 55368dd43b6..ea956a4791d 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -86,13 +86,13 @@ static int fixup_qcom_dwc3(struct device_node *glue_np) } /* Overwrite "phy-names" to only contain a single entry */ - ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "usb2-phy"); + ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy") + 1, "usb2-phy"); if (ret) { log_err("Failed to overwrite 'phy-names' property: %d\n", ret); return ret; } - ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed"), "high-speed"); + ret = of_write_prop(dwc3, "maximum-speed", strlen("high-speed") + 1, "high-speed"); if (ret) { log_err("Failed to set 'maximum-speed' property: %d\n", ret); return ret; -- cgit v1.3.1 From 925efba5793d5ab0aca4b0e5f1378f50d228d191 Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Thu, 27 Feb 2025 09:45:50 +0000 Subject: power: regulator: add qcom-usb-vbus Add regulator driver that allow some Qualcomm PMIC to feed VBUS output to peripherals that are connected. Signed-off-by: Rui Miguel Silva Acked-by: Caleb Connolly Reviewed-by: Neil Armstrong Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250227094911.497219-3-rui.silva@linaro.org Signed-off-by: Caleb Connolly --- drivers/power/regulator/Kconfig | 7 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/qcom_usb_vbus_regulator.c | 111 ++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 drivers/power/regulator/qcom_usb_vbus_regulator.c diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 8f102a92c23..bab68317cfa 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -224,6 +224,13 @@ config DM_REGULATOR_QCOM_RPMH implements get/set api for a limited set of regulators used by u-boot. +config DM_REGULATOR_QCOM_USB_VBUS + bool "Enable driver model for Qualcomm USB vbus regulator" + depends on DM_REGULATOR + ---help--- + Enable support for the Qualcomm USB Vbus regulator. The driver + implements get/set api for the regulator to be used by u-boot. + config SPL_DM_REGULATOR_GPIO bool "Enable Driver Model for GPIO REGULATOR in SPL" depends on DM_REGULATOR_GPIO && SPL_GPIO diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 4382d4b3ab9..054a93e129a 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_$(XPL_)DM_REGULATOR_COMMON) += regulator_common.o obj-$(CONFIG_$(XPL_)DM_REGULATOR_FIXED) += fixed.o obj-$(CONFIG_$(XPL_)DM_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o +obj-$(CONFIG_DM_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus_regulator.o obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o diff --git a/drivers/power/regulator/qcom_usb_vbus_regulator.c b/drivers/power/regulator/qcom_usb_vbus_regulator.c new file mode 100644 index 00000000000..2d58ef5e111 --- /dev/null +++ b/drivers/power/regulator/qcom_usb_vbus_regulator.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Linaro Limited + */ +#define pr_fmt(fmt) "qcom_usb_vbus: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CMD_OTG 0x50 +#define OTG_EN BIT(0) +// The 0 bit in this register's bit field is undocumented +#define OTG_CFG 0x56 +#define OTG_EN_SRC_CFG BIT(1) + +struct qcom_usb_vbus_priv { + phys_addr_t base; +}; + +static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev) +{ + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev) +{ + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); + int otg_en_reg = priv->base + CMD_OTG; + int ret; + + ret = pmic_reg_read(dev->parent, otg_en_reg); + if (ret < 0) + log_err("failed to read usb vbus: %d\n", ret); + else + ret &= OTG_EN; + + return ret; +} + +static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool enable) +{ + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); + int otg_en_reg = priv->base + CMD_OTG; + int ret; + + if (enable) { + ret = pmic_clrsetbits(dev->parent, otg_en_reg, 0, OTG_EN); + if (ret < 0) { + log_err("error enabling: %d\n", ret); + return ret; + } + } else { + ret = pmic_clrsetbits(dev->parent, otg_en_reg, OTG_EN, 0); + if (ret < 0) { + log_err("error disabling: %d\n", ret); + return ret; + } + } + + return 0; +} + +static int qcom_usb_vbus_regulator_probe(struct udevice *dev) +{ + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); + int otg_cfg_reg = priv->base + OTG_CFG; + int ret; + + /* Disable HW logic for VBUS enable */ + ret = pmic_clrsetbits(dev->parent, otg_cfg_reg, OTG_EN_SRC_CFG, 0); + if (ret < 0) { + log_err("error setting EN_SRC_CFG: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct dm_regulator_ops qcom_usb_vbus_regulator_ops = { + .get_enable = qcom_usb_vbus_regulator_get_enable, + .set_enable = qcom_usb_vbus_regulator_set_enable, +}; + +static const struct udevice_id qcom_usb_vbus_regulator_ids[] = { + { .compatible = "qcom,pm8150b-vbus-reg"}, + { }, +}; + +U_BOOT_DRIVER(qcom_usb_vbus_regulator) = { + .name = "qcom-usb-vbus-regulator", + .id = UCLASS_REGULATOR, + .of_match = qcom_usb_vbus_regulator_ids, + .of_to_plat = qcom_usb_vbus_regulator_of_to_plat, + .ops = &qcom_usb_vbus_regulator_ops, + .probe = qcom_usb_vbus_regulator_probe, + .priv_auto = sizeof(struct qcom_usb_vbus_priv), +}; -- cgit v1.3.1 From b2f89b33d3355f009fdaf304985d23df0e428bdf Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Mon, 24 Mar 2025 17:00:30 +0530 Subject: regulator: qcom-rpmh-regulator: add support for pmm8654 regulators Add the PMC8380 regulator data found on the Qualcomm SA8775P platform. The tables are imported from the Linux driver. Signed-off-by: Varadarajan Narayanan Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250324113030.2597986-1-quic_varada@quicinc.com Signed-off-by: Caleb Connolly --- drivers/power/regulator/qcom-rpmh-regulator.c | 45 +++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c index cd2b1a654c1..954deca5ed7 100644 --- a/drivers/power/regulator/qcom-rpmh-regulator.c +++ b/drivers/power/regulator/qcom-rpmh-regulator.c @@ -466,6 +466,25 @@ static const struct rpmh_vreg_hw_data pmic5_nldo515 = { .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo), }; +static const struct rpmh_vreg_hw_data pmic5_ftsmps527 = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), + .n_voltages = 215, + .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_pldo515_mv = { + .regulator_type = VRM, + .ops = &rpmh_regulator_vrm_drms_ops, + .voltage_range = REGULATOR_LINEAR_RANGE(1800000, 0, 187, 8000), + .n_voltages = 188, + .hpm_min_load_uA = 10000, + .pmic_mode_map = pmic_mode_map_pmic5_ldo, + .n_modes = ARRAY_SIZE(pmic_mode_map_pmic5_ldo), +}; + #define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \ { \ .name = _name, \ @@ -558,6 +577,28 @@ static const struct rpmh_vreg_init_data pmc8380_vreg_data[] = { {} }; +static const struct rpmh_vreg_init_data pmm8654au_vreg_data[] = { + RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps527, "vdd-s1"), + RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps527, "vdd-s2"), + RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps527, "vdd-s3"), + RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps527, "vdd-s4"), + RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps527, "vdd-s5"), + RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps527, "vdd-s6"), + RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps527, "vdd-s7"), + RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps527, "vdd-s8"), + RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps527, "vdd-s9"), + RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l2-l3"), + RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo515, "vdd-s9"), + RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo515, "vdd-l6-l7"), + RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l6-l7"), + RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo515_mv, "vdd-l8-l9"), + RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l8-l9"), + {} +}; + /* probe an individual regulator */ static int rpmh_regulator_probe(struct udevice *dev) { @@ -688,6 +729,10 @@ static const struct udevice_id rpmh_regulator_ids[] = { .compatible = "qcom,pmc8380-rpmh-regulators", .data = (ulong)pmc8380_vreg_data, }, + { + .compatible = "qcom,pmm8654au-rpmh-regulators", + .data = (ulong)pmm8654au_vreg_data, + }, { /* sentinal */ }, }; -- cgit v1.3.1 From 5effb1e62556e5d84c2fc037f7020d26cdf3b9ca Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Mon, 24 Mar 2025 13:35:03 +0530 Subject: pinctrl: qcom: add driver for SA8775P SoC Add pinctrl and GPIO driver for SA8775P. Driver code is based on the similar U-Boot and Linux drivers. Signed-off-by: Varadarajan Narayanan Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250324080504.2385747-1-quic_varada@quicinc.com Signed-off-by: Caleb Connolly --- drivers/pinctrl/qcom/Kconfig | 8 +- drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-sa8775p.c | 623 +++++++++++++++++++++++++++++++++ 3 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/qcom/pinctrl-sa8775p.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index f4a3942ee2f..e24287c978f 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -48,12 +48,18 @@ config PINCTRL_QCOM_QCS404 Say Y here to enable support for pinctrl on the Snapdragon QCS404 SoC, as well as the associated GPIO driver. +config PINCTRL_QCOM_SA8775P + bool "Qualcomm SA8775P Pinctrl" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the Snapdragon SA8775P SoC, + as well as the associated GPIO driver. + config PINCTRL_QCOM_SC7280 bool "Qualcomm SC7280/QCM6490 Pinctrl" select PINCTRL_QCOM help Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC, - as well as the associated GPIO driver. config PINCTRL_QCOM_SDM845 bool "Qualcomm SDM845 Pinctrl" diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 94cdc6e4a62..65d1845ea54 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -9,6 +9,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_SA8775P) += pinctrl-sa8775p.o obj-$(CONFIG_PINCTRL_QCOM_SC7280) += pinctrl-sc7280.o obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o diff --git a/drivers/pinctrl/qcom/pinctrl-sa8775p.c b/drivers/pinctrl/qcom/pinctrl-sa8775p.c new file mode 100644 index 00000000000..cb2496ff1fb --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sa8775p.c @@ -0,0 +1,623 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#include + +#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 SA8775_PIN_OFFSET 0x100000 + +#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, \ + } + +enum sa8775p_functions { + msm_mux_gpio, + msm_mux_atest_char, + msm_mux_atest_usb2, + msm_mux_audio_ref, + msm_mux_cam_mclk, + msm_mux_cci_async, + msm_mux_cci_i2c, + msm_mux_cci_timer0, + msm_mux_cci_timer1, + msm_mux_cci_timer2, + msm_mux_cci_timer3, + msm_mux_cci_timer4, + msm_mux_cci_timer5, + msm_mux_cci_timer6, + msm_mux_cci_timer7, + msm_mux_cci_timer8, + msm_mux_cci_timer9, + msm_mux_cri_trng, + msm_mux_cri_trng0, + msm_mux_cri_trng1, + msm_mux_dbg_out, + msm_mux_ddr_bist, + msm_mux_ddr_pxi0, + msm_mux_ddr_pxi1, + msm_mux_ddr_pxi2, + msm_mux_ddr_pxi3, + msm_mux_ddr_pxi4, + msm_mux_ddr_pxi5, + msm_mux_edp0_hot, + msm_mux_edp0_lcd, + msm_mux_edp1_hot, + msm_mux_edp1_lcd, + msm_mux_edp2_hot, + msm_mux_edp2_lcd, + msm_mux_edp3_hot, + msm_mux_edp3_lcd, + msm_mux_emac0_mcg0, + msm_mux_emac0_mcg1, + msm_mux_emac0_mcg2, + msm_mux_emac0_mcg3, + msm_mux_emac0_mdc, + msm_mux_emac0_mdio, + msm_mux_emac0_ptp_aux, + msm_mux_emac0_ptp_pps, + msm_mux_emac1_mcg0, + msm_mux_emac1_mcg1, + msm_mux_emac1_mcg2, + msm_mux_emac1_mcg3, + msm_mux_emac1_mdc, + msm_mux_emac1_mdio, + msm_mux_emac1_ptp_aux, + msm_mux_emac1_ptp_pps, + msm_mux_gcc_gp1, + msm_mux_gcc_gp2, + msm_mux_gcc_gp3, + msm_mux_gcc_gp4, + msm_mux_gcc_gp5, + msm_mux_hs0_mi2s, + msm_mux_hs1_mi2s, + msm_mux_hs2_mi2s, + msm_mux_ibi_i3c, + msm_mux_jitter_bist, + msm_mux_mdp0_vsync0, + msm_mux_mdp0_vsync1, + msm_mux_mdp0_vsync2, + msm_mux_mdp0_vsync3, + msm_mux_mdp0_vsync4, + msm_mux_mdp0_vsync5, + msm_mux_mdp0_vsync6, + msm_mux_mdp0_vsync7, + msm_mux_mdp0_vsync8, + msm_mux_mdp1_vsync0, + msm_mux_mdp1_vsync1, + msm_mux_mdp1_vsync2, + msm_mux_mdp1_vsync3, + msm_mux_mdp1_vsync4, + msm_mux_mdp1_vsync5, + msm_mux_mdp1_vsync6, + msm_mux_mdp1_vsync7, + msm_mux_mdp1_vsync8, + msm_mux_mdp_vsync, + msm_mux_mi2s1_data0, + msm_mux_mi2s1_data1, + msm_mux_mi2s1_sck, + msm_mux_mi2s1_ws, + msm_mux_mi2s2_data0, + msm_mux_mi2s2_data1, + msm_mux_mi2s2_sck, + msm_mux_mi2s2_ws, + msm_mux_mi2s_mclk0, + msm_mux_mi2s_mclk1, + msm_mux_pcie0_clkreq, + msm_mux_pcie1_clkreq, + msm_mux_phase_flag, + msm_mux_pll_bist, + msm_mux_pll_clk, + msm_mux_prng_rosc0, + msm_mux_prng_rosc1, + msm_mux_prng_rosc2, + msm_mux_prng_rosc3, + msm_mux_qdss_cti, + msm_mux_qdss_gpio, + msm_mux_qup0_se0, + msm_mux_qup0_se1, + msm_mux_qup0_se2, + msm_mux_qup0_se3, + msm_mux_qup0_se4, + msm_mux_qup0_se5, + msm_mux_qup1_se0, + msm_mux_qup1_se1, + msm_mux_qup1_se2, + msm_mux_qup1_se3, + msm_mux_qup1_se4, + msm_mux_qup1_se5, + msm_mux_qup1_se6, + msm_mux_qup2_se0, + msm_mux_qup2_se1, + msm_mux_qup2_se2, + msm_mux_qup2_se3, + msm_mux_qup2_se4, + msm_mux_qup2_se5, + msm_mux_qup2_se6, + msm_mux_qup3_se0, + msm_mux_sail_top, + msm_mux_sailss_emac0, + msm_mux_sailss_ospi, + msm_mux_sgmii_phy, + msm_mux_tb_trig, + msm_mux_tgu_ch0, + msm_mux_tgu_ch1, + msm_mux_tgu_ch2, + msm_mux_tgu_ch3, + msm_mux_tgu_ch4, + msm_mux_tgu_ch5, + msm_mux_tsense_pwm1, + msm_mux_tsense_pwm2, + msm_mux_tsense_pwm3, + msm_mux_tsense_pwm4, + msm_mux_usb2phy_ac, + msm_mux_vsense_trigger, + 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(atest_char), + MSM_PIN_FUNCTION(atest_usb2), + MSM_PIN_FUNCTION(audio_ref), + MSM_PIN_FUNCTION(cam_mclk), + MSM_PIN_FUNCTION(cci_async), + MSM_PIN_FUNCTION(cci_i2c), + MSM_PIN_FUNCTION(cci_timer0), + MSM_PIN_FUNCTION(cci_timer1), + MSM_PIN_FUNCTION(cci_timer2), + MSM_PIN_FUNCTION(cci_timer3), + MSM_PIN_FUNCTION(cci_timer4), + MSM_PIN_FUNCTION(cci_timer5), + MSM_PIN_FUNCTION(cci_timer6), + MSM_PIN_FUNCTION(cci_timer7), + MSM_PIN_FUNCTION(cci_timer8), + MSM_PIN_FUNCTION(cci_timer9), + MSM_PIN_FUNCTION(cri_trng), + MSM_PIN_FUNCTION(cri_trng0), + MSM_PIN_FUNCTION(cri_trng1), + MSM_PIN_FUNCTION(dbg_out), + MSM_PIN_FUNCTION(ddr_bist), + MSM_PIN_FUNCTION(ddr_pxi0), + MSM_PIN_FUNCTION(ddr_pxi1), + MSM_PIN_FUNCTION(ddr_pxi2), + MSM_PIN_FUNCTION(ddr_pxi3), + MSM_PIN_FUNCTION(ddr_pxi4), + MSM_PIN_FUNCTION(ddr_pxi5), + MSM_PIN_FUNCTION(edp0_hot), + MSM_PIN_FUNCTION(edp0_lcd), + MSM_PIN_FUNCTION(edp1_hot), + MSM_PIN_FUNCTION(edp1_lcd), + MSM_PIN_FUNCTION(edp2_hot), + MSM_PIN_FUNCTION(edp2_lcd), + MSM_PIN_FUNCTION(edp3_hot), + MSM_PIN_FUNCTION(edp3_lcd), + MSM_PIN_FUNCTION(emac0_mcg0), + MSM_PIN_FUNCTION(emac0_mcg1), + MSM_PIN_FUNCTION(emac0_mcg2), + MSM_PIN_FUNCTION(emac0_mcg3), + MSM_PIN_FUNCTION(emac0_mdc), + MSM_PIN_FUNCTION(emac0_mdio), + MSM_PIN_FUNCTION(emac0_ptp_aux), + MSM_PIN_FUNCTION(emac0_ptp_pps), + MSM_PIN_FUNCTION(emac1_mcg0), + MSM_PIN_FUNCTION(emac1_mcg1), + MSM_PIN_FUNCTION(emac1_mcg2), + MSM_PIN_FUNCTION(emac1_mcg3), + MSM_PIN_FUNCTION(emac1_mdc), + MSM_PIN_FUNCTION(emac1_mdio), + MSM_PIN_FUNCTION(emac1_ptp_aux), + MSM_PIN_FUNCTION(emac1_ptp_pps), + MSM_PIN_FUNCTION(gcc_gp1), + MSM_PIN_FUNCTION(gcc_gp2), + MSM_PIN_FUNCTION(gcc_gp3), + MSM_PIN_FUNCTION(gcc_gp4), + MSM_PIN_FUNCTION(gcc_gp5), + MSM_PIN_FUNCTION(hs0_mi2s), + MSM_PIN_FUNCTION(hs1_mi2s), + MSM_PIN_FUNCTION(hs2_mi2s), + MSM_PIN_FUNCTION(ibi_i3c), + MSM_PIN_FUNCTION(jitter_bist), + MSM_PIN_FUNCTION(mdp0_vsync0), + MSM_PIN_FUNCTION(mdp0_vsync1), + MSM_PIN_FUNCTION(mdp0_vsync2), + MSM_PIN_FUNCTION(mdp0_vsync3), + MSM_PIN_FUNCTION(mdp0_vsync4), + MSM_PIN_FUNCTION(mdp0_vsync5), + MSM_PIN_FUNCTION(mdp0_vsync6), + MSM_PIN_FUNCTION(mdp0_vsync7), + MSM_PIN_FUNCTION(mdp0_vsync8), + MSM_PIN_FUNCTION(mdp1_vsync0), + MSM_PIN_FUNCTION(mdp1_vsync1), + MSM_PIN_FUNCTION(mdp1_vsync2), + MSM_PIN_FUNCTION(mdp1_vsync3), + MSM_PIN_FUNCTION(mdp1_vsync4), + MSM_PIN_FUNCTION(mdp1_vsync5), + MSM_PIN_FUNCTION(mdp1_vsync6), + MSM_PIN_FUNCTION(mdp1_vsync7), + MSM_PIN_FUNCTION(mdp1_vsync8), + MSM_PIN_FUNCTION(mdp_vsync), + MSM_PIN_FUNCTION(mi2s1_data0), + MSM_PIN_FUNCTION(mi2s1_data1), + MSM_PIN_FUNCTION(mi2s1_sck), + MSM_PIN_FUNCTION(mi2s1_ws), + MSM_PIN_FUNCTION(mi2s2_data0), + MSM_PIN_FUNCTION(mi2s2_data1), + MSM_PIN_FUNCTION(mi2s2_sck), + MSM_PIN_FUNCTION(mi2s2_ws), + MSM_PIN_FUNCTION(mi2s_mclk0), + MSM_PIN_FUNCTION(mi2s_mclk1), + MSM_PIN_FUNCTION(pcie0_clkreq), + MSM_PIN_FUNCTION(pcie1_clkreq), + MSM_PIN_FUNCTION(phase_flag), + MSM_PIN_FUNCTION(pll_bist), + MSM_PIN_FUNCTION(pll_clk), + MSM_PIN_FUNCTION(prng_rosc0), + MSM_PIN_FUNCTION(prng_rosc1), + MSM_PIN_FUNCTION(prng_rosc2), + MSM_PIN_FUNCTION(prng_rosc3), + MSM_PIN_FUNCTION(qdss_cti), + MSM_PIN_FUNCTION(qdss_gpio), + MSM_PIN_FUNCTION(qup0_se0), + MSM_PIN_FUNCTION(qup0_se1), + MSM_PIN_FUNCTION(qup0_se2), + MSM_PIN_FUNCTION(qup0_se3), + MSM_PIN_FUNCTION(qup0_se4), + MSM_PIN_FUNCTION(qup0_se5), + MSM_PIN_FUNCTION(qup1_se0), + MSM_PIN_FUNCTION(qup1_se1), + MSM_PIN_FUNCTION(qup1_se2), + MSM_PIN_FUNCTION(qup1_se3), + MSM_PIN_FUNCTION(qup1_se4), + MSM_PIN_FUNCTION(qup1_se5), + MSM_PIN_FUNCTION(qup1_se6), + MSM_PIN_FUNCTION(qup2_se0), + MSM_PIN_FUNCTION(qup2_se1), + MSM_PIN_FUNCTION(qup2_se2), + MSM_PIN_FUNCTION(qup2_se3), + MSM_PIN_FUNCTION(qup2_se4), + MSM_PIN_FUNCTION(qup2_se5), + MSM_PIN_FUNCTION(qup2_se6), + MSM_PIN_FUNCTION(qup3_se0), + MSM_PIN_FUNCTION(sail_top), + MSM_PIN_FUNCTION(sailss_emac0), + MSM_PIN_FUNCTION(sailss_ospi), + MSM_PIN_FUNCTION(sgmii_phy), + MSM_PIN_FUNCTION(tb_trig), + MSM_PIN_FUNCTION(tgu_ch0), + MSM_PIN_FUNCTION(tgu_ch1), + MSM_PIN_FUNCTION(tgu_ch2), + MSM_PIN_FUNCTION(tgu_ch3), + MSM_PIN_FUNCTION(tgu_ch4), + MSM_PIN_FUNCTION(tgu_ch5), + MSM_PIN_FUNCTION(tsense_pwm1), + MSM_PIN_FUNCTION(tsense_pwm2), + MSM_PIN_FUNCTION(tsense_pwm3), + MSM_PIN_FUNCTION(tsense_pwm4), + MSM_PIN_FUNCTION(usb2phy_ac), + MSM_PIN_FUNCTION(vsense_trigger), +}; + +static const msm_pin_function sa8775p_pin_functions[] = { + [0] = PINGROUP(0, _, _, _, _, _, _, _, _, _), + [1] = PINGROUP(1, pcie0_clkreq, _, _, _, _, _, _, _, _), + [2] = PINGROUP(2, _, _, _, _, _, _, _, _, _), + [3] = PINGROUP(3, pcie1_clkreq, _, _, _, _, _, _, _, _), + [4] = PINGROUP(4, _, _, _, _, _, _, _, _, _), + [5] = PINGROUP(5, _, _, _, _, _, _, _, _, _), + [6] = PINGROUP(6, emac0_ptp_aux, emac0_ptp_pps, emac1_ptp_aux, + emac1_ptp_pps, _, _, _, _, _), + [7] = PINGROUP(7, sgmii_phy, _, _, _, _, _, _, _, _), + [8] = PINGROUP(8, emac0_mdc, _, _, _, _, _, _, _, _), + [9] = PINGROUP(9, emac0_mdio, _, _, _, _, _, _, _, _), + [10] = PINGROUP(10, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, + emac1_ptp_aux, emac1_ptp_pps, _, _, _, _), + [11] = PINGROUP(11, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, + emac1_ptp_aux, emac1_ptp_pps, _, _, _, _), + [12] = PINGROUP(12, usb2phy_ac, emac0_ptp_aux, emac0_ptp_pps, + emac1_ptp_aux, emac1_ptp_pps, emac0_mcg0, _, _, _), + [13] = PINGROUP(13, qup3_se0, emac0_mcg1, _, _, sail_top, _, _, _, _), + [14] = PINGROUP(14, qup3_se0, emac0_mcg2, _, _, sail_top, _, _, _, _), + [15] = PINGROUP(15, qup3_se0, emac0_mcg3, _, _, sail_top, _, _, _, _), + [16] = PINGROUP(16, qup3_se0, emac1_mcg0, _, _, sail_top, _, _, _, _), + [17] = PINGROUP(17, qup3_se0, tb_trig, tb_trig, emac1_mcg1, _, _, _, _, _), + [18] = PINGROUP(18, qup3_se0, emac1_mcg2, _, _, sailss_ospi, sailss_emac0, _, _, _), + [19] = PINGROUP(19, qup3_se0, emac1_mcg3, _, _, sailss_ospi, sailss_emac0, _, _, _), + [20] = PINGROUP(20, qup0_se0, emac1_mdc, qdss_gpio, _, _, _, _, _, _), + [21] = PINGROUP(21, qup0_se0, emac1_mdio, qdss_gpio, _, _, _, _, _, _), + [22] = PINGROUP(22, qup0_se0, qdss_gpio, _, _, _, _, _, _, _), + [23] = PINGROUP(23, qup0_se0, qdss_gpio, _, _, _, _, _, _, _), + [24] = PINGROUP(24, qup0_se1, qdss_gpio, _, _, _, _, _, _, _), + [25] = PINGROUP(25, qup0_se1, phase_flag, _, qdss_gpio, _, _, _, _, _), + [26] = PINGROUP(26, sgmii_phy, qup0_se1, qdss_cti, phase_flag, _, _, _, _, _), + [27] = PINGROUP(27, qup0_se1, qdss_cti, phase_flag, _, atest_char, _, _, _, _), + [28] = PINGROUP(28, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), + [29] = PINGROUP(29, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), + [30] = PINGROUP(30, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), + [31] = PINGROUP(31, qup0_se3, phase_flag, _, qdss_gpio, _, _, _, _, _), + [32] = PINGROUP(32, qup0_se4, phase_flag, _, _, _, _, _, _, _), + [33] = PINGROUP(33, qup0_se4, gcc_gp4, _, ddr_pxi0, _, _, _, _, _), + [34] = PINGROUP(34, qup0_se4, gcc_gp5, _, ddr_pxi0, _, _, _, _, _), + [35] = PINGROUP(35, qup0_se4, phase_flag, _, _, _, _, _, _, _), + [36] = PINGROUP(36, qup0_se2, qup0_se5, phase_flag, tgu_ch2, _, _, _, _, _), + [37] = PINGROUP(37, qup0_se2, qup0_se5, phase_flag, tgu_ch3, _, _, _, _, _), + [38] = PINGROUP(38, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch4, _, _, _, _), + [39] = PINGROUP(39, qup0_se5, qup0_se2, qdss_cti, phase_flag, tgu_ch5, _, _, _, _), + [40] = PINGROUP(40, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync0, _, _, _, _, _), + [41] = PINGROUP(41, qup1_se0, qup1_se1, ibi_i3c, mdp1_vsync1, _, _, _, _, _), + [42] = PINGROUP(42, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync2, gcc_gp5, _, _, _, _), + [43] = PINGROUP(43, qup1_se1, qup1_se0, ibi_i3c, mdp1_vsync3, _, _, _, _, _), + [44] = PINGROUP(44, qup1_se2, qup1_se3, edp0_lcd, _, _, _, _, _, _), + [45] = PINGROUP(45, qup1_se2, qup1_se3, edp1_lcd, _, _, _, _, _, _), + [46] = PINGROUP(46, qup1_se3, qup1_se2, mdp1_vsync4, tgu_ch0, _, _, _, _, _), + [47] = PINGROUP(47, qup1_se3, qup1_se2, mdp1_vsync5, tgu_ch1, _, _, _, _, _), + [48] = PINGROUP(48, qup1_se4, qdss_cti, edp2_lcd, _, _, _, _, _, _), + [49] = PINGROUP(49, qup1_se4, qdss_cti, edp3_lcd, _, _, _, _, _, _), + [50] = PINGROUP(50, qup1_se4, cci_async, qdss_cti, mdp1_vsync8, _, _, _, _, _), + [51] = PINGROUP(51, qup1_se4, qdss_cti, mdp1_vsync6, gcc_gp1, _, _, _, _, _), + [52] = PINGROUP(52, qup1_se5, cci_timer4, cci_i2c, mdp1_vsync7, gcc_gp2, _, ddr_pxi1, _, _), + [53] = PINGROUP(53, qup1_se5, cci_timer5, cci_i2c, gcc_gp3, _, ddr_pxi1, _, _, _), + [54] = PINGROUP(54, qup1_se5, cci_timer6, cci_i2c, _, _, _, _, _, _), + [55] = PINGROUP(55, qup1_se5, cci_timer7, cci_i2c, gcc_gp4, _, ddr_pxi2, _, _, _), + [56] = PINGROUP(56, qup1_se6, qup1_se6, cci_timer8, cci_i2c, phase_flag, ddr_bist, _, _, _), + [57] = PINGROUP(57, qup1_se6, qup1_se6, cci_timer9, cci_i2c, + mdp0_vsync0, phase_flag, ddr_bist, _, _), + [58] = PINGROUP(58, cci_i2c, mdp0_vsync1, ddr_bist, _, atest_usb2, atest_char, _, _, _), + [59] = PINGROUP(59, cci_i2c, mdp0_vsync2, ddr_bist, _, atest_usb2, atest_char, _, _, _), + [60] = PINGROUP(60, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [61] = PINGROUP(61, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [62] = PINGROUP(62, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [63] = PINGROUP(63, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [64] = PINGROUP(64, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [65] = PINGROUP(65, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [66] = PINGROUP(66, cci_i2c, cci_async, qdss_gpio, _, _, _, _, _, _), + [67] = PINGROUP(67, cci_i2c, qdss_gpio, _, _, _, _, _, _, _), + [68] = PINGROUP(68, cci_timer0, cci_async, _, _, _, _, _, _, _), + [69] = PINGROUP(69, cci_timer1, cci_async, _, _, _, _, _, _, _), + [70] = PINGROUP(70, cci_timer2, cci_async, _, _, _, _, _, _, _), + [71] = PINGROUP(71, cci_timer3, cci_async, _, _, _, _, _, _, _), + [72] = PINGROUP(72, cam_mclk, _, _, _, _, _, _, _, _), + [73] = PINGROUP(73, cam_mclk, _, _, _, _, _, _, _, _), + [74] = PINGROUP(74, cam_mclk, _, _, _, _, _, _, _, _), + [75] = PINGROUP(75, cam_mclk, _, _, _, _, _, _, _, _), + [76] = PINGROUP(76, _, _, _, _, _, _, _, _, _), + [77] = PINGROUP(77, _, _, _, _, _, _, _, _, _), + [78] = PINGROUP(78, _, _, _, _, _, _, _, _, _), + [79] = PINGROUP(79, _, _, _, _, _, _, _, _, _), + [80] = PINGROUP(80, qup2_se0, ibi_i3c, mdp0_vsync3, _, _, _, _, _, _), + [81] = PINGROUP(81, qup2_se0, ibi_i3c, mdp0_vsync4, _, _, _, _, _, _), + [82] = PINGROUP(82, qup2_se0, mdp_vsync, gcc_gp1, _, _, _, _, _, _), + [83] = PINGROUP(83, qup2_se0, mdp_vsync, gcc_gp2, _, _, _, _, _, _), + [84] = PINGROUP(84, qup2_se1, qup2_se5, ibi_i3c, mdp_vsync, gcc_gp3, _, _, _, _), + [85] = PINGROUP(85, qup2_se1, qup2_se5, ibi_i3c, _, _, _, _, _, _), + [86] = PINGROUP(86, qup2_se2, jitter_bist, atest_usb2, ddr_pxi2, _, _, _, _, _), + [87] = PINGROUP(87, qup2_se2, pll_clk, atest_usb2, ddr_pxi3, _, _, _, _, _), + [88] = PINGROUP(88, qup2_se2, _, atest_usb2, ddr_pxi3, _, _, _, _, _), + [89] = PINGROUP(89, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _), + [90] = PINGROUP(90, qup2_se2, _, atest_usb2, ddr_pxi4, atest_char, _, _, _, _), + [91] = PINGROUP(91, qup2_se3, mdp0_vsync5, _, atest_usb2, _, _, _, _, _), + [92] = PINGROUP(92, qup2_se3, mdp0_vsync6, _, atest_usb2, _, _, _, _, _), + [93] = PINGROUP(93, qup2_se3, mdp0_vsync7, _, atest_usb2, _, _, _, _, _), + [94] = PINGROUP(94, qup2_se3, mdp0_vsync8, _, atest_usb2, _, _, _, _, _), + [95] = PINGROUP(95, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _), + [96] = PINGROUP(96, qup2_se4, qup2_se6, _, atest_usb2, _, _, _, _, _), + [97] = PINGROUP(97, qup2_se6, qup2_se4, cri_trng0, _, atest_usb2, _, _, _, _), + [98] = PINGROUP(98, qup2_se6, qup2_se4, phase_flag, cri_trng1, _, _, _, _, _), + [99] = PINGROUP(99, qup2_se5, qup2_se1, phase_flag, cri_trng, _, _, _, _, _), + [100] = PINGROUP(100, qup2_se5, qup2_se1, _, _, _, _, _, _, _), + [101] = PINGROUP(101, edp0_hot, prng_rosc0, tsense_pwm4, _, _, _, _, _, _), + [102] = PINGROUP(102, edp1_hot, prng_rosc1, tsense_pwm3, _, _, _, _, _, _), + [103] = PINGROUP(103, edp3_hot, prng_rosc2, tsense_pwm2, _, _, _, _, _, _), + [104] = PINGROUP(104, edp2_hot, prng_rosc3, tsense_pwm1, _, _, _, _, _, _), + [105] = PINGROUP(105, mi2s_mclk0, _, qdss_gpio, atest_usb2, _, _, _, _, _), + [106] = PINGROUP(106, mi2s1_sck, phase_flag, _, qdss_gpio, _, _, _, _, _), + [107] = PINGROUP(107, mi2s1_ws, phase_flag, _, qdss_gpio, _, _, _, _, _), + [108] = PINGROUP(108, mi2s1_data0, phase_flag, _, qdss_gpio, _, _, _, _, _), + [109] = PINGROUP(109, mi2s1_data1, phase_flag, _, qdss_gpio, _, _, _, _, _), + [110] = PINGROUP(110, mi2s2_sck, phase_flag, _, qdss_gpio, _, _, _, _, _), + [111] = PINGROUP(111, mi2s2_ws, phase_flag, _, qdss_gpio, vsense_trigger, _, _, _, _), + [112] = PINGROUP(112, mi2s2_data0, phase_flag, _, qdss_gpio, _, _, _, _, _), + [113] = PINGROUP(113, mi2s2_data1, audio_ref, phase_flag, _, qdss_gpio, _, _, _, _), + [114] = PINGROUP(114, hs0_mi2s, pll_bist, phase_flag, _, qdss_gpio, _, _, _, _), + [115] = PINGROUP(115, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _), + [116] = PINGROUP(116, hs0_mi2s, _, qdss_gpio, _, _, _, _, _, _), + [117] = PINGROUP(117, hs0_mi2s, mi2s_mclk1, _, qdss_gpio, _, _, _, _, _), + [118] = PINGROUP(118, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _), + [119] = PINGROUP(119, hs1_mi2s, _, qdss_gpio, ddr_pxi5, _, _, _, _, _), + [120] = PINGROUP(120, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), + [121] = PINGROUP(121, hs1_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), + [122] = PINGROUP(122, hs2_mi2s, phase_flag, _, qdss_gpio, _, _, _, _, _), + [123] = PINGROUP(123, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), + [124] = PINGROUP(124, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), + [125] = PINGROUP(125, hs2_mi2s, phase_flag, _, _, _, _, _, _, _), + [126] = PINGROUP(126, _, _, _, _, _, _, _, _, _), + [127] = PINGROUP(127, _, _, _, _, _, _, _, _, _), + [128] = PINGROUP(128, _, _, _, _, _, _, _, _, _), + [129] = PINGROUP(129, _, _, _, _, _, _, _, _, _), + [130] = PINGROUP(130, _, _, _, _, _, _, _, _, _), + [131] = PINGROUP(131, _, _, _, _, _, _, _, _, _), + [132] = PINGROUP(132, _, _, _, _, _, _, _, _, _), + [133] = PINGROUP(133, _, _, _, _, _, _, _, _, _), + [134] = PINGROUP(134, _, _, _, _, _, _, _, _, _), + [135] = PINGROUP(135, _, _, _, _, _, _, _, _, _), + [136] = PINGROUP(136, _, _, _, _, _, _, _, _, _), + [137] = PINGROUP(137, _, _, _, _, _, _, _, _, _), + [138] = PINGROUP(138, _, _, _, _, _, _, _, _, _), + [139] = PINGROUP(139, _, _, _, _, _, _, _, _, _), + [140] = PINGROUP(140, _, _, _, _, _, _, _, _, _), + [141] = PINGROUP(141, _, _, _, _, _, _, _, _, _), + [142] = PINGROUP(142, _, _, _, _, _, _, _, _, _), + [143] = PINGROUP(143, _, _, _, _, _, _, _, _, _), + [144] = PINGROUP(144, dbg_out, _, _, _, _, _, _, _, _), + [145] = PINGROUP(145, _, _, _, _, _, _, _, _, _), + [146] = PINGROUP(146, _, _, _, _, _, _, _, _, _), + [147] = PINGROUP(147, _, _, _, _, _, _, _, _, _), + [148] = PINGROUP(148, _, _, _, _, _, _, _, _, _), +}; + +static const struct msm_special_pin_data msm_special_pins_data[] = { + [0] = UFS_RESET("ufs_reset", 0x1a2000), + [1] = SDC_QDSD_PINGROUP("sdc1_rclk", 0x199000, 15, 0), + [2] = SDC_QDSD_PINGROUP("sdc1_clk", 0x199000, 13, 6), + [3] = SDC_QDSD_PINGROUP("sdc1_cmd", 0x199000, 11, 3), + [4] = SDC_QDSD_PINGROUP("sdc1_data", 0x199000, 9, 0), +}; + +static const char *sa8775p_get_function_name(struct udevice *dev, + unsigned int selector) +{ + return msm_pinctrl_functions[selector].name; +} + +static const char *sa8775p_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + if (selector >= 149 && selector <= 155) + snprintf(pin_name, MAX_PIN_NAME_LEN, + msm_special_pins_data[selector - 149].name); + else + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); + + return pin_name; +} + +static int sa8775p_get_function_mux(__maybe_unused unsigned int pin, + unsigned int selector) +{ + unsigned int i; + const msm_pin_function *func = sa8775p_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 unsigned int sa8775p_pin_offsets[] = { + [0] = SA8775_PIN_OFFSET, [1] = SA8775_PIN_OFFSET, [2] = SA8775_PIN_OFFSET, + [3] = SA8775_PIN_OFFSET, [4] = SA8775_PIN_OFFSET, [5] = SA8775_PIN_OFFSET, + [6] = SA8775_PIN_OFFSET, [7] = SA8775_PIN_OFFSET, [8] = SA8775_PIN_OFFSET, + [9] = SA8775_PIN_OFFSET, [10] = SA8775_PIN_OFFSET, [11] = SA8775_PIN_OFFSET, + [12] = SA8775_PIN_OFFSET, [13] = SA8775_PIN_OFFSET, [14] = SA8775_PIN_OFFSET, + [15] = SA8775_PIN_OFFSET, [16] = SA8775_PIN_OFFSET, [17] = SA8775_PIN_OFFSET, + [18] = SA8775_PIN_OFFSET, [19] = SA8775_PIN_OFFSET, [20] = SA8775_PIN_OFFSET, + [21] = SA8775_PIN_OFFSET, [22] = SA8775_PIN_OFFSET, [23] = SA8775_PIN_OFFSET, + [24] = SA8775_PIN_OFFSET, [25] = SA8775_PIN_OFFSET, [26] = SA8775_PIN_OFFSET, + [27] = SA8775_PIN_OFFSET, [28] = SA8775_PIN_OFFSET, [29] = SA8775_PIN_OFFSET, + [30] = SA8775_PIN_OFFSET, [31] = SA8775_PIN_OFFSET, [32] = SA8775_PIN_OFFSET, + [33] = SA8775_PIN_OFFSET, [34] = SA8775_PIN_OFFSET, [35] = SA8775_PIN_OFFSET, + [36] = SA8775_PIN_OFFSET, [37] = SA8775_PIN_OFFSET, [38] = SA8775_PIN_OFFSET, + [39] = SA8775_PIN_OFFSET, [40] = SA8775_PIN_OFFSET, [41] = SA8775_PIN_OFFSET, + [42] = SA8775_PIN_OFFSET, [43] = SA8775_PIN_OFFSET, [44] = SA8775_PIN_OFFSET, + [45] = SA8775_PIN_OFFSET, [46] = SA8775_PIN_OFFSET, [47] = SA8775_PIN_OFFSET, + [48] = SA8775_PIN_OFFSET, [49] = SA8775_PIN_OFFSET, [50] = SA8775_PIN_OFFSET, + [51] = SA8775_PIN_OFFSET, [52] = SA8775_PIN_OFFSET, [53] = SA8775_PIN_OFFSET, + [54] = SA8775_PIN_OFFSET, [55] = SA8775_PIN_OFFSET, [56] = SA8775_PIN_OFFSET, + [57] = SA8775_PIN_OFFSET, [58] = SA8775_PIN_OFFSET, [59] = SA8775_PIN_OFFSET, + [60] = SA8775_PIN_OFFSET, [61] = SA8775_PIN_OFFSET, [62] = SA8775_PIN_OFFSET, + [63] = SA8775_PIN_OFFSET, [64] = SA8775_PIN_OFFSET, [65] = SA8775_PIN_OFFSET, + [66] = SA8775_PIN_OFFSET, [67] = SA8775_PIN_OFFSET, [68] = SA8775_PIN_OFFSET, + [69] = SA8775_PIN_OFFSET, [70] = SA8775_PIN_OFFSET, [71] = SA8775_PIN_OFFSET, + [72] = SA8775_PIN_OFFSET, [73] = SA8775_PIN_OFFSET, [74] = SA8775_PIN_OFFSET, + [75] = SA8775_PIN_OFFSET, [76] = SA8775_PIN_OFFSET, [77] = SA8775_PIN_OFFSET, + [78] = SA8775_PIN_OFFSET, [79] = SA8775_PIN_OFFSET, [80] = SA8775_PIN_OFFSET, + [81] = SA8775_PIN_OFFSET, [82] = SA8775_PIN_OFFSET, [83] = SA8775_PIN_OFFSET, + [84] = SA8775_PIN_OFFSET, [85] = SA8775_PIN_OFFSET, [86] = SA8775_PIN_OFFSET, + [87] = SA8775_PIN_OFFSET, [88] = SA8775_PIN_OFFSET, [89] = SA8775_PIN_OFFSET, + [90] = SA8775_PIN_OFFSET, [91] = SA8775_PIN_OFFSET, [92] = SA8775_PIN_OFFSET, + [93] = SA8775_PIN_OFFSET, [94] = SA8775_PIN_OFFSET, [95] = SA8775_PIN_OFFSET, + [96] = SA8775_PIN_OFFSET, [97] = SA8775_PIN_OFFSET, [98] = SA8775_PIN_OFFSET, + [99] = SA8775_PIN_OFFSET, [100] = SA8775_PIN_OFFSET, [101] = SA8775_PIN_OFFSET, + [102] = SA8775_PIN_OFFSET, [103] = SA8775_PIN_OFFSET, [104] = SA8775_PIN_OFFSET, + [105] = SA8775_PIN_OFFSET, [106] = SA8775_PIN_OFFSET, [107] = SA8775_PIN_OFFSET, + [108] = SA8775_PIN_OFFSET, [109] = SA8775_PIN_OFFSET, [110] = SA8775_PIN_OFFSET, + [111] = SA8775_PIN_OFFSET, [112] = SA8775_PIN_OFFSET, [113] = SA8775_PIN_OFFSET, + [114] = SA8775_PIN_OFFSET, [115] = SA8775_PIN_OFFSET, [116] = SA8775_PIN_OFFSET, + [117] = SA8775_PIN_OFFSET, [118] = SA8775_PIN_OFFSET, [119] = SA8775_PIN_OFFSET, + [120] = SA8775_PIN_OFFSET, [121] = SA8775_PIN_OFFSET, [122] = SA8775_PIN_OFFSET, + [123] = SA8775_PIN_OFFSET, [124] = SA8775_PIN_OFFSET, [125] = SA8775_PIN_OFFSET, + [126] = SA8775_PIN_OFFSET, [127] = SA8775_PIN_OFFSET, [128] = SA8775_PIN_OFFSET, + [129] = SA8775_PIN_OFFSET, [130] = SA8775_PIN_OFFSET, [131] = SA8775_PIN_OFFSET, + [132] = SA8775_PIN_OFFSET, [133] = SA8775_PIN_OFFSET, [134] = SA8775_PIN_OFFSET, + [135] = SA8775_PIN_OFFSET, [136] = SA8775_PIN_OFFSET, [137] = SA8775_PIN_OFFSET, + [138] = SA8775_PIN_OFFSET, [139] = SA8775_PIN_OFFSET, [140] = SA8775_PIN_OFFSET, + [141] = SA8775_PIN_OFFSET, [142] = SA8775_PIN_OFFSET, [143] = SA8775_PIN_OFFSET, + [144] = SA8775_PIN_OFFSET, [145] = SA8775_PIN_OFFSET, [146] = SA8775_PIN_OFFSET, + [147] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET, [148] = SA8775_PIN_OFFSET, + [149] = SA8775_PIN_OFFSET, [150] = SA8775_PIN_OFFSET, [151] = SA8775_PIN_OFFSET, + [152] = SA8775_PIN_OFFSET, [153] = SA8775_PIN_OFFSET, [154] = SA8775_PIN_OFFSET, +}; + +static const struct msm_pinctrl_data sa8775p_data = { + .pin_data = { + .pin_count = 155, + .special_pins_start = 149, + .special_pins_data = msm_special_pins_data, + .pin_offsets = sa8775p_pin_offsets, + }, + .functions_count = ARRAY_SIZE(msm_pinctrl_functions), + .get_function_name = sa8775p_get_function_name, + .get_function_mux = sa8775p_get_function_mux, + .get_pin_name = sa8775p_get_pin_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,sa8775p-tlmm", .data = (ulong)&sa8775p_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_sa8775p) = { + .name = "pinctrl_sa8775p", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit v1.3.1 From 55fee70fb0889831cc3fa6b33799b54c24517486 Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Mon, 24 Mar 2025 13:35:04 +0530 Subject: qcom_defconfig: enable pinctrl for SA8775P Enable the pinctrl driver for SA8775P Signed-off-by: Varadarajan Narayanan Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250324080504.2385747-2-quic_varada@quicinc.com Signed-off-by: Caleb Connolly --- configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index 3dce271ee2d..a2b54b95f19 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -103,6 +103,7 @@ 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_SDM845=y CONFIG_PINCTRL_QCOM_SM6115=y -- cgit v1.3.1 From 2c1462e38b771c547a1f3ee8bbea5aa9d3719885 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 17 Mar 2025 16:15:02 +0000 Subject: clk/qcom: sc7280: add missing UFS and MMC clocks These are all usually enabled, hence we don't (yet) bother configuring their RCG src clocks. Add them to remove the errors about missing clocks when the UFS and MMC drivers probe. Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250317-sc7280-mmc-ufs-clocks-v1-2-38e05c16511b@linaro.org Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-sc7280.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c index 8691f08109b..9aff8a847ad 100644 --- a/drivers/clk/qcom/clock-sc7280.c +++ b/drivers/clk/qcom/clock-sc7280.c @@ -107,6 +107,17 @@ static const struct gate_clk sc7280_clks[] = { 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_S3_CLK, 0x52008, BIT(13)), + 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)), + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)), + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)), + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77020, BIT(0)), + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770b8, BIT(0)), + GATE_CLK(GCC_UFS_1_CLKREF_EN, 0x8c000, BIT(0)), + GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, BIT(0)), + GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, BIT(0)), }; static int sc7280_enable(struct clk *clk) -- cgit v1.3.1 From 1a02b7aa58ae1558e2fd5c29e85c20bdf1becaae Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 28 Mar 2025 09:53:21 +0100 Subject: spmi: msm: use real number of channels for v5 & v7 The SPMI_MAX_CHANNELS_Vx are only the maximum channels supported by the controller, but the real number of channels mapped on this system can be read from a register, so take this info. This allows no to overlap on the second controller present on the V7 SPMI arbiter, otherwise we would also parse the mapping of the second SPMI bus and we would bet the wrong IDs. Signed-off-by: Neil Armstrong Tested-by: caleb.connolly@linaro.org # sdm845 Link: https://lore.kernel.org/r/20250328-topic-sm8x50-spmi-fix-v1-1-a7548d3aef0d@linaro.org Signed-off-by: Caleb Connolly --- drivers/spmi/spmi-msm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 5cc5a9e654c..08be4517df1 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -24,6 +24,9 @@ DECLARE_GLOBAL_DATA_PTR; #define PMIC_ARB_VERSION_V5_MIN 0x50000000 #define PMIC_ARB_VERSION_V7_MIN 0x70000000 +#define PMIC_ARB_FEATURES 0x0004 +#define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) + #define APID_MAP_OFFSET_V1_V2_V3 (0x800) #define APID_MAP_OFFSET_V5 (0x900) #define APID_MAP_OFFSET_V7 (0x2000) @@ -271,13 +274,17 @@ static int msm_spmi_probe(struct udevice *dev) } else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) { priv->arb_ver = V5; priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5; - priv->max_channels = SPMI_MAX_CHANNELS_V5; + priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK, + SPMI_MAX_CHANNELS_V5); priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg"); } else { /* TOFIX: handle second bus */ priv->arb_ver = V7; priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7; - priv->max_channels = SPMI_MAX_CHANNELS_V7; + priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK, + SPMI_MAX_CHANNELS_V7); priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg"); } -- cgit v1.3.1 From f252350623326d35a7f7cdf88e1db279f019f5d7 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 28 Mar 2025 09:53:22 +0100 Subject: spmi: msm: factor out channel mapping for v5 & v7 The handling of the table mapping for V5 & V7 needs more work to handle the duplicate read-only & read-write mappings, so to make code cleaner add a switch/case and move the v5 & v7 mapping handler in a separate function. Signed-off-by: Neil Armstrong Tested-by: caleb.connolly@linaro.org # sdm845 Link: https://lore.kernel.org/r/20250328-topic-sm8x50-spmi-fix-v1-2-a7548d3aef0d@linaro.org Signed-off-by: Caleb Connolly --- drivers/spmi/spmi-msm.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 08be4517df1..9b2be1c1b9e 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -249,6 +249,18 @@ static struct dm_spmi_ops msm_spmi_ops = { .write = msm_spmi_write, }; +static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i, + uint8_t slave_id, uint8_t pid) +{ + /* Mark channels read-only when from different owner */ + uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); + uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); + + priv->channel_map[slave_id][pid] = i; + if (owner != priv->owner) + priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY; +} + static int msm_spmi_probe(struct udevice *dev) { struct msm_spmi_priv *priv = dev_get_priv(dev); @@ -304,15 +316,16 @@ static int msm_spmi_probe(struct udevice *dev) uint8_t slave_id = (periph & 0xf0000) >> 16; uint8_t pid = (periph & 0xff00) >> 8; - priv->channel_map[slave_id][pid] = i; - - /* Mark channels read-only when from different owner */ - if (priv->arb_ver == V5 || priv->arb_ver == V7) { - uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); - uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); + switch (priv->arb_ver) { + case V2: + case V3: + priv->channel_map[slave_id][pid] = i; + break; - if (owner != priv->owner) - priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY; + case V5: + case V7: + msm_spmi_channel_map_v5(priv, i, slave_id, pid); + break; } } return 0; -- cgit v1.3.1 From 69400a696cb823075990048eac5c4ed857229daf Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 28 Mar 2025 09:53:23 +0100 Subject: spmi: msm: introduce SPMI_CHANNEL_VALID flag Introduce the SPMI_CHANNEL_VALID flag so we can check if a mapping exists for a SPMI command. Signed-off-by: Neil Armstrong Tested-by: caleb.connolly@linaro.org # sdm845 Link: https://lore.kernel.org/r/20250328-topic-sm8x50-spmi-fix-v1-3-a7548d3aef0d@linaro.org Signed-off-by: Caleb Connolly --- drivers/spmi/spmi-msm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 9b2be1c1b9e..ee3feaf8b50 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -63,6 +63,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SPMI_MAX_PERIPH 256 #define SPMI_CHANNEL_READ_ONLY BIT(31) +#define SPMI_CHANNEL_VALID BIT(30) #define SPMI_CHANNEL_MASK 0xffff enum arb_ver { @@ -117,6 +118,8 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off, return -EIO; if (pid >= SPMI_MAX_PERIPH) return -EIO; + if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID)) + return -EINVAL; if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY) return -EPERM; @@ -186,6 +189,8 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off) return -EIO; if (pid >= SPMI_MAX_PERIPH) return -EIO; + if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID)) + return -EINVAL; channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK; @@ -256,7 +261,7 @@ static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i, uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); - priv->channel_map[slave_id][pid] = 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; } @@ -319,7 +324,7 @@ static int msm_spmi_probe(struct udevice *dev) switch (priv->arb_ver) { case V2: case V3: - priv->channel_map[slave_id][pid] = i; + priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; break; case V5: -- cgit v1.3.1 From 5b233442afacde1aca2556c543b1cd8e22946690 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 28 Mar 2025 09:53:24 +0100 Subject: spmi: msm: correctly handle multiple mapping entries On v5 & v7 controllers, multiple mapping for different Execution Environment exists, if the mapping owner is for a different Execution Environment we can only read and not write any data. To allow us to find a Write mapping for our Execution Environment, we can overwritte a mapping if we encounter a new one which we own. Implement this logic, the result is the same mapping table as in Linux. Signed-off-by: Neil Armstrong Tested-by: caleb.connolly@linaro.org # sdm845 Link: https://lore.kernel.org/r/20250328-topic-sm8x50-spmi-fix-v1-4-a7548d3aef0d@linaro.org Signed-off-by: Caleb Connolly --- drivers/spmi/spmi-msm.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index ee3feaf8b50..faae54e9fef 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -254,16 +254,30 @@ static struct dm_spmi_ops msm_spmi_ops = { .write = msm_spmi_write, }; +/* + * In order to allow multiple EEs to write to a single PPID in arbiter + * version 5 and 7, there is more than one APID mapped to each PPID. + * The owner field for each of these mappings specifies the EE which is + * allowed to write to the APID. + */ static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i, uint8_t slave_id, uint8_t pid) { /* Mark channels read-only when from different owner */ uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); - - priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; - if (owner != priv->owner) - priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY; + bool prev_valid = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_VALID; + uint32_t prev_read_only = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_READ_ONLY; + + if (!prev_valid) { + /* First PPID mapping */ + 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 */ + priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID; + } } static int msm_spmi_probe(struct udevice *dev) -- cgit v1.3.1 From 602ceb0c9279e15f94e160c70d471da6c4300841 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 12:43:18 +0200 Subject: mach-snapdragon: of_fixup: fix condition check in ft_board_setup() The fdt_node_check_compatible() function returns 0 on success which is pretty confusing, and we were using it wrong! Invert the condition check and refactor things to be more readable. Additionally, add the check for the RB1 which needs the same fixup as the RB2. Reported-by: Sam Day Fixes: e64503f1fcdf ("mach-snapdragon: implement ft_board_setup() for USB role selection") Tested-by: Alexey Minnekhanov Tested-by: Sam Day Link: https://lore.kernel.org/r/20250331104327.321339-1-caleb.connolly@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/mach-snapdragon/of_fixup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index ea956a4791d..1ea0c18c2f2 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -161,14 +161,14 @@ int ft_board_setup(void *blob, struct bd_info __maybe_unused *bd) struct fdt_header *fdt = blob; int node; - /* We only want to do this fix-up for the RB1 board, quick return for all others */ - if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2")) - return 0; - - fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") { - log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL)); - fdt_setprop_string(fdt, node, "dr_mode", "otg"); - break; + /* On RB1/2 we need to fix-up the dr_mode */ + if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2") || + !fdt_node_check_compatible(fdt, 0, "qcom,qrb2210-rb1")) { + fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") { + log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL)); + fdt_setprop_string(fdt, node, "dr_mode", "otg"); + break; + } } return 0; -- cgit v1.3.1 From c5e05651b1a89e83250936df41c0569b65f0ab93 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Wed, 2 Apr 2025 16:28:03 +0200 Subject: hmibsc_defconfig: disable DM_USB_GADGET As with the db410c this breaks linking as it conflicts with the USB controller used by these platforms. This fixes building after DM_USB_GADGET was enabled by default for mach-snapdragon. Fixes: 7235dbedfce3 (mach-snapdragon: enable DM_USB_GADGET by default) Reviewed-by: Sumit Garg Link: https://lore.kernel.org/r/20250402142812.368168-1-caleb.connolly@linaro.org Signed-off-by: Caleb Connolly --- configs/hmibsc_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/hmibsc_defconfig b/configs/hmibsc_defconfig index 88c9c70a639..4550eba71ab 100644 --- a/configs/hmibsc_defconfig +++ b/configs/hmibsc_defconfig @@ -70,6 +70,7 @@ CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_USB=y +# CONFIG_DM_USB_GADGET is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MSM=y CONFIG_USB_ULPI_VIEWPORT=y -- cgit v1.3.1 From f933b5a704be45e8f6f97560293a5ce7e64af82d Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 7 Apr 2025 19:56:13 +0200 Subject: board: qualcomm: dragonboard820c: update readme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update build instructions. Be sure to use the u-boot-nodtb.bin image, as the Snapdragon platform prioritizes the embedded Device Tree Blob (DTB) when present, rather than the external one. The external DTB—modified by LK—is the version required by the DB820c. Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Neil Armstrong Reviewed-by: Christopher Obbard Reviewed-by: Link: https://lore.kernel.org/r/20250407175617.3494506-1-jorge.ramirez@oss.qualcomm.com Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard820c/readme.txt | 47 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/board/qualcomm/dragonboard820c/readme.txt b/board/qualcomm/dragonboard820c/readme.txt index 966e9520e85..a01d24122cb 100644 --- a/board/qualcomm/dragonboard820c/readme.txt +++ b/board/qualcomm/dragonboard820c/readme.txt @@ -16,10 +16,7 @@ Build & Run instructions ================================================================================ -1) Install mkbootimg and dtbTool from Codeaurora: - - git://codeaurora.org/quic/kernel/skales - commit 8492547e404e969262d9070dee9bdd15668bb70f worked for me. +1) Install mkbootimg 2) Setup CROSS_COMPILE to aarch64 compiler or if you use ccache just do CROSS_COMPILE="ccache aarch64-linux-gnu-" @@ -33,15 +30,15 @@ $ touch rd -5) Generate qualcomm device tree table with dtbTool +5) Append the dtb to the u-boot binary discarding the internal dtb. - $ dtbTool -o dt.img arch/arm/dts + $ gzip u-boot-nodtb.bin + $ cat u-boot.dtb >> u-boot-nodtb.bin.gz 6) Generate Android boot image with mkbootimg: - $ mkbootimg --kernel=u-boot-dtb.bin \ + $ mkbootimg --kernel=u-boot-nodtb.bin.gz \ --output=u-boot.img \ - --dt=dt.img \ --pagesize 4096 \ --base 0x80000000 \ --ramdisk=rd \ @@ -251,44 +248,42 @@ Wait for 5 seconds before proceeding [5300] booting linux @ 0x80080000, ramdisk @ 0x82200000 (0), tags/device tree @ 0x82000000 [5310] Jumping to kernel via monitor -U-Boot 2017.11-00145-ge895117 (Nov 29 2017 - 10:04:06 +0100) +U-Boot 2025.04-rc5-00020-g40a61ca0e7eb-dirty (Apr 07 2025 - 09:37:03 +0200) Qualcomm-DragonBoard 820C -DRAM: 3 GiB -PSCI: v1.0 -MMC: sdhci@74a4900: 0 +DRAM: 3.5 GiB (effective 3 GiB) +Core: 136 devices, 18 uclasses, devicetree: board +MMC: Bulk clocks not available (-19), trying core clock +mmc@74a4900: 0 +Loading Environment from EXT4... OK In: serial@75b0000 Out: serial@75b0000 Err: serial@75b0000 -Net: Net Initialization Skipped -No ethernet found. +Net: No ethernet found. Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0:1... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf -433 bytes read in 71 ms (5.9 KiB/s) 1: nfs root - +Enter choice: 1: nfs root Retrieving file: /uImage -19397184 bytes read in 2024 ms (9.1 MiB/s) -append: root=/dev/nfs rw nfsroot=192.168.1.2:/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlycon=msm_serial_dm,0x75b0000 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.ver0 - +append: root=/dev/nfs rw nfsroot=192.168.1.6:/home/jramirez/Src/qualcomm-lt/db820c/rootfs,v3,tcp rootwait ip=dhcp consoleblank=0 console=tty0 console=ttyMSM0,115200n8 earlyprintk earlyco0 Retrieving file: /apq8096-db820c.dtb -38134 bytes read in 37 ms (1005.9 KiB/s) - -## Booting kernel from Legacy Image at 95000000 ... +## Booting kernel from Legacy Image at 155000000 ... Image Name: Dragonboard820c Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 19397120 Bytes = 18.5 MiB Load Address: 80080000 Entry Point: 80080000 Verifying Checksum ... OK -## Flattened Device Tree blob at 93000000 - Booting using the fdt blob at 0x93000000 - Loading Kernel Image ... OK - Using Device Tree in place at 0000000093000000, end 000000009300c4f5 +## Flattened Device Tree blob at 148600000 + Booting using the fdt blob at 0x148600000 +Working FDT set to 148600000 + Loading Kernel Image to 80080000 + Using Device Tree in place at 0000000148600000, end 000000014860c4f5 +Working FDT set to 148600000 Starting kernel ... -- cgit v1.3.1 From 1561b01a0851e9ada026778c5518f0bef8caa3e3 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 7 Apr 2025 19:56:14 +0200 Subject: clk/qcom: apq8096: fix set rate for the uart clock The function should return a valid rate. Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Neil Armstrong Reviewed-by: Caleb Connolly Reviewed-by: Link: https://lore.kernel.org/r/20250407175617.3494506-2-jorge.ramirez@oss.qualcomm.com Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-apq8096.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index c77d69128b0..bc00826a5e8 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -87,7 +87,8 @@ static ulong apq8096_clk_set_rate(struct clk *clk, ulong rate) return clk_init_sdc(priv, rate); break; case GCC_BLSP2_UART2_APPS_CLK: /*UART2*/ - return clk_init_uart(priv); + clk_init_uart(priv); + return 7372800; default: return 0; } -- cgit v1.3.1 From 8fc48d1a01acec2568b48b2afd6303397af593c8 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 7 Apr 2025 19:56:15 +0200 Subject: clk/qcom: apq8096: fix the sdhci clock Select the right clock for sdhci. Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Caleb Connolly Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250407175617.3494506-3-jorge.ramirez@oss.qualcomm.com Signed-off-by: Caleb Connolly --- drivers/clk/qcom/clock-apq8096.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c index bc00826a5e8..551f52d5197 100644 --- a/drivers/clk/qcom/clock-apq8096.c +++ b/drivers/clk/qcom/clock-apq8096.c @@ -83,7 +83,7 @@ static ulong apq8096_clk_set_rate(struct clk *clk, ulong rate) struct msm_clk_priv *priv = dev_get_priv(clk->dev); switch (clk->id) { - case GCC_SDCC1_APPS_CLK: /* SDC1 */ + case GCC_SDCC2_APPS_CLK: /* SDC2 */ return clk_init_sdc(priv, rate); break; case GCC_BLSP2_UART2_APPS_CLK: /*UART2*/ -- cgit v1.3.1 From 7afddbee3b1f667b9ff752e9779d1eb9e2992ba4 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 7 Apr 2025 19:56:16 +0200 Subject: clk: stub: add qcom,glink-smd-rpm Add support for the resource power manager clocks over SMD/GLINK to be stubbed. Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Sumit Garg Reviewed-by: Neil Armstrong Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250407175617.3494506-4-jorge.ramirez@oss.qualcomm.com Signed-off-by: Caleb Connolly --- drivers/clk/clk-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c index 521ecfc5917..5f5aca41d5b 100644 --- a/drivers/clk/clk-stub.c +++ b/drivers/clk/clk-stub.c @@ -14,7 +14,7 @@ static const struct udevice_id nop_parent_ids[] = { { .compatible = "qcom,rpm-proc" }, { .compatible = "qcom,glink-rpm" }, - { .compatible = "qcom,rpm-sm6115" }, + { .compatible = "qcom,glink-smd-rpm" }, { } }; -- cgit v1.3.1 From adb79d308273ad9d6278a17459d61e8310077986 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 7 Apr 2025 19:56:17 +0200 Subject: configs: dragonboard820: updates Configure GPIO and CLK_STUBS CLK_STUBS is required for MMC initialization Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407175617.3494506-5-jorge.ramirez@oss.qualcomm.com Signed-off-by: Caleb Connolly --- configs/dragonboard820c_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/dragonboard820c_defconfig b/configs/dragonboard820c_defconfig index e29bea7deb2..2a5b7212f74 100644 --- a/configs/dragonboard820c_defconfig +++ b/configs/dragonboard820c_defconfig @@ -45,4 +45,6 @@ CONFIG_PINCTRL_QCOM_APQ8096=y CONFIG_DM_PMIC=y CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y +CONFIG_MSM_GPIO=y CONFIG_SPMI_MSM=y +CONFIG_CLK_STUB=y -- cgit v1.3.1 From 49cf3b29134cd9d0feac25999be966070972d3c0 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 10 Apr 2025 13:30:26 +0530 Subject: qcom_defconfig: Disable MMC HS200 mode support Currently the msm_sdhci doesn't yet support DLL configurations which are required to enable bus speeds greater that 100MHz. So disable HS200 mode support as of now as it requires bus speeds of 200MHz. This should fix eMMC issues reported on RB1/RB2 although it should fix issues for all Qcom platforms but it's not seen there as mostly SD cards available don't support HS200 mode. The SD cards usually works in high speed mode whose performance remains unaffected by this change. It only affects RB1/RB2 as eMMC flash on these support HS200 mode but the U-Boot driver currently is incapable of supporting that. Reviewed-by: Caleb Connolly Signed-off-by: Sumit Garg Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410080027.208674-2-sumit.garg@kernel.org Signed-off-by: Caleb Connolly --- configs/qcom_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index a2b54b95f19..537806450dc 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -81,7 +81,6 @@ CONFIG_QCOM_HYP_SMMU=y CONFIG_MISC=y CONFIG_NVMEM=y CONFIG_I2C_EEPROM=y -CONFIG_MMC_HS200_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_MSM=y -- cgit v1.3.1 From 45acd9d2d4ec84775d09c73aab75a4fd989beb41 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 10 Apr 2025 13:30:27 +0530 Subject: phy: phy-qcom-qusb2: Fix USB PHY power on sequence Recent addition of support for SDM660 inadvertently broke USB PHY power on sequence on RB1/RB2 and others with following error: starting USB... Bus usb@4e00000: QUSB2PHY pll lock failed: status reg = 0 qcom-qusb2-phy phy@1613000: PHY: Failed to power on phy@1613000: -16. Can't power on PHY0 probe failed, error -16 No USB controllers found The root cause was the addition of flag se_clk_scheme_default which was configured correctly for SDM660 but incorrect for all other supported SoC. Fix that by properly assignment as per upstream Linux driver. Fixes: 475497dc3c15 ("phy: Add SDM660 support to Qualcomm QUSB2 phy") Signed-off-by: Sumit Garg Reviewed-by: Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410080027.208674-3-sumit.garg@kernel.org Signed-off-by: Caleb Connolly --- drivers/phy/qcom/phy-qcom-qusb2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/phy/qcom/phy-qcom-qusb2.c b/drivers/phy/qcom/phy-qcom-qusb2.c index cabd05bf5a6..d98f6108e69 100644 --- a/drivers/phy/qcom/phy-qcom-qusb2.c +++ b/drivers/phy/qcom/phy-qcom-qusb2.c @@ -230,6 +230,7 @@ static const struct qusb2_phy_cfg sm6115_phy_cfg = { .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), @@ -256,6 +257,7 @@ static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = { POWER_DOWN), .mask_core_ready = CORE_READY_STATUS, .has_pll_override = true, + .se_clk_scheme_default = true, .autoresume_en = BIT(0), .update_tune1_with_efuse = true, }; -- cgit v1.3.1 From 0708bdd34d4fdd0680706d2719de34704402719d Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 1 Apr 2025 09:45:19 +0200 Subject: gpio: msm: fix get_function return for special pins The get_function callback wrongly returns 0 for special pins, return the appropriate pin function by probing into the special pins data fields to find if the pin is gpio capable. Fixes: f9bb539460d ("gpio: msm: add support for special pins") Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250401-topic-sm8x50-msm-gpio-special-fixes-v1-1-a1148a02bb16@linaro.org Signed-off-by: Caleb Connolly --- drivers/gpio/msm_gpio.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index cea073b3297..f208eec7e56 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -192,13 +192,41 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio) return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN); } +static int msm_gpio_get_function_special(struct msm_gpio_bank *priv, + unsigned int gpio) +{ + unsigned int offset = gpio - priv->pin_data->special_pins_start; + const struct msm_special_pin_data *data; + + if (!priv->pin_data->special_pins_data) + return GPIOF_UNKNOWN; + + data = &priv->pin_data->special_pins_data[offset]; + + /* No I/O fields, cannot control/read the I/O value */ + if (!data->io_reg || (data->out_bit >= 31 && data->in_bit >= 31)) + return GPIOF_FUNC; + + /* No Output-Enable register, cannot control I/O direction */ + if (!data->ctl_reg || data->oe_bit >= 31) { + if (data->out_bit >= 31) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; + } + + if (readl(priv->base + data->ctl_reg) & BIT(data->oe_bit)) + return GPIOF_OUTPUT; + + return GPIOF_INPUT; +} + static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); - /* Always NOP for special pins, assume they're in the correct state */ if (qcom_is_special_pin(priv->pin_data, gpio)) - return 0; + return msm_gpio_get_function_special(priv, gpio); if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE) return GPIOF_OUTPUT; -- cgit v1.3.1 From 8803cd6dd782cd66f5978e79da022aa2de9710d9 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 1 Apr 2025 09:45:20 +0200 Subject: gpio: msm: return correct value return for special output pins When a special pin is output only, the current code would return 0, but if the pin is output only we can get the output value. Try to return the output value and in all the other cases return an error instead of 0. Fixes: f9bb539460d ("gpio: msm: add support for special pins") Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250401-topic-sm8x50-msm-gpio-special-fixes-v1-2-a1148a02bb16@linaro.org Signed-off-by: Caleb Connolly --- drivers/gpio/msm_gpio.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index f208eec7e56..54afd44fbd3 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -172,12 +172,19 @@ static int msm_gpio_get_value_special(struct msm_gpio_bank *priv, unsigned int g const struct msm_special_pin_data *data; if (!priv->pin_data->special_pins_data) - return 0; + return -EINVAL; data = &priv->pin_data->special_pins_data[offset]; - if (!data->io_reg || data->in_bit >= 31) - return 0; + if (!data->io_reg) + return -EINVAL; + + if (data->in_bit >= 31) { + if (data->out_bit >= 31) + return -EINVAL; + + return !!(readl(priv->base + data->io_reg) >> data->out_bit); + } return !!(readl(priv->base + data->io_reg) >> data->in_bit); } -- cgit v1.3.1 From b4420a0c9ed446a9dbb5439d543d7c74344a5099 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Mon, 31 Mar 2025 18:55:31 +0300 Subject: drivers: pinctrl: Add Qualcomm SDM630/660 TLMM driver Add support for TLMM pin controller block (Top Level Mode Multiplexer) on SDM630/660 SoCs, with support for special pins. Correct pin configuration is required for working debug UART and eMMC/SD cards. SDM630 and SDM660 TLMM blocks are the same. Signed-off-by: Alexey Minnekhanov Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250331155531.3638165-1-alexeymin@postmarketos.org Signed-off-by: Caleb Connolly --- drivers/pinctrl/qcom/Kconfig | 7 ++ drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-sdm660.c | 226 ++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-sdm660.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index e24287c978f..e567cb113a3 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -61,6 +61,13 @@ config PINCTRL_QCOM_SC7280 help Say Y here to enable support for pinctrl on the Snapdragon SC7280 SoC, +config PINCTRL_QCOM_SDM660 + bool "Qualcomm SDM630/660 Pinctrl" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the Snapdragon 630/636/660 + SoCs, as well as the associated GPIO driver. + config PINCTRL_QCOM_SDM845 bool "Qualcomm SDM845 Pinctrl" select PINCTRL_QCOM diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 65d1845ea54..6ffc6d48c15 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.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 obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o diff --git a/drivers/pinctrl/qcom/pinctrl-sdm660.c b/drivers/pinctrl/qcom/pinctrl-sdm660.c new file mode 100644 index 00000000000..646d848ffa4 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sdm660.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm SDM630/660 TLMM pinctrl + * + */ + +#include +#include "pinctrl-qcom.h" + +#define TLMM_BASE 0x03100000 +#define SOUTH (0x03100000 - TLMM_BASE) /* 0x0 */ +#define CENTER (0x03500000 - TLMM_BASE) /* 0x400000 */ +#define NORTH (0x03900000 - TLMM_BASE) /* 0x800000 */ + +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); + +static const struct pinctrl_function sdm660_pinctrl_functions[] = { + { "gpio", 0 }, + { "blsp_uart2", 3 }, /* gpio 4 and 5, used for debug uart */ +}; + +static const unsigned int sdm660_pin_offsets[] = { + [0] = SOUTH, + [1] = SOUTH, + [2] = SOUTH, + [3] = SOUTH, + [4] = NORTH, + [5] = SOUTH, + [6] = SOUTH, + [7] = SOUTH, + [8] = NORTH, + [9] = NORTH, + [10] = NORTH, + [11] = NORTH, + [12] = NORTH, + [13] = NORTH, + [14] = NORTH, + [15] = NORTH, + [16] = CENTER, + [17] = CENTER, + [18] = CENTER, + [19] = CENTER, + [20] = SOUTH, + [21] = SOUTH, + [22] = CENTER, + [23] = CENTER, + [24] = NORTH, + [25] = NORTH, + [26] = NORTH, + [27] = NORTH, + [28] = CENTER, + [29] = CENTER, + [30] = CENTER, + [31] = CENTER, + [32] = SOUTH, + [33] = SOUTH, + [34] = SOUTH, + [35] = SOUTH, + [36] = SOUTH, + [37] = SOUTH, + [38] = SOUTH, + [39] = SOUTH, + [40] = SOUTH, + [41] = SOUTH, + [42] = SOUTH, + [43] = SOUTH, + [44] = SOUTH, + [45] = SOUTH, + [46] = SOUTH, + [47] = SOUTH, + [48] = SOUTH, + [49] = SOUTH, + [50] = SOUTH, + [51] = SOUTH, + [52] = SOUTH, + [53] = NORTH, + [54] = NORTH, + [55] = SOUTH, + [56] = SOUTH, + [57] = SOUTH, + [58] = SOUTH, + [59] = NORTH, + [60] = NORTH, + [61] = NORTH, + [62] = NORTH, + [63] = NORTH, + [64] = SOUTH, + [65] = SOUTH, + [66] = NORTH, + [67] = NORTH, + [68] = NORTH, + [69] = NORTH, + [70] = NORTH, + [71] = NORTH, + [72] = NORTH, + [73] = NORTH, + [74] = NORTH, + [75] = NORTH, + [76] = NORTH, + [77] = NORTH, + [78] = NORTH, + [79] = SOUTH, + [80] = SOUTH, + [81] = CENTER, + [82] = CENTER, + [83] = SOUTH, + [84] = SOUTH, + [85] = SOUTH, + [86] = SOUTH, + [87] = SOUTH, + [88] = SOUTH, + [89] = SOUTH, + [90] = SOUTH, + [91] = SOUTH, + [92] = SOUTH, + [93] = SOUTH, + [94] = SOUTH, + [95] = SOUTH, + [96] = SOUTH, + [97] = SOUTH, + [98] = SOUTH, + [99] = SOUTH, + [100] = SOUTH, + [101] = SOUTH, + [102] = SOUTH, + [103] = SOUTH, + [104] = SOUTH, + [105] = SOUTH, + [106] = SOUTH, + [107] = SOUTH, + [108] = SOUTH, + [109] = SOUTH, + [110] = SOUTH, + [111] = SOUTH, + [112] = SOUTH, + [113] = SOUTH, +}; + +/* + * Special pins - eMMC/SD related: [114..120], in total 7 special pins + */ + +#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, \ + } + +/* All SDC pins are in the NORTH tile */ +static const struct msm_special_pin_data sdm660_special_pins_data[] = { + SDC_QDSD_PINGROUP("sdc1_clk", NORTH + 0x9a000, 13, 6), + SDC_QDSD_PINGROUP("sdc1_cmd", NORTH + 0x9a000, 11, 3), + SDC_QDSD_PINGROUP("sdc1_data", NORTH + 0x9a000, 9, 0), + SDC_QDSD_PINGROUP("sdc2_clk", NORTH + 0x9b000, 14, 6), + SDC_QDSD_PINGROUP("sdc2_cmd", NORTH + 0x9b000, 11, 3), + SDC_QDSD_PINGROUP("sdc2_data", NORTH + 0x9b000, 9, 0), + SDC_QDSD_PINGROUP("sdc1_rclk", NORTH + 0x9a000, 15, 0), +}; + +static const char *sdm660_get_function_name(struct udevice *dev, unsigned int selector) +{ + return sdm660_pinctrl_functions[selector].name; +} + +static const char *sdm660_get_pin_name(struct udevice *dev, unsigned int selector) +{ + static const char * const special_pins_names[] = { + "sdc1_clk", "sdc1_cmd", "sdc1_data", + "sdc2_clk", "sdc2_cmd", "sdc2_data", + "sdc1_rclk" + }; + + if (selector >= 114 && selector <= 120) + snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 114]); + else + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); + + return pin_name; +} + +static int sdm660_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector) +{ + if (selector >= 0 && selector < ARRAY_SIZE(sdm660_pinctrl_functions)) + return sdm660_pinctrl_functions[selector].val; + return -EINVAL; +} + +struct msm_pinctrl_data sdm660_data = { + .pin_data = { + .pin_offsets = sdm660_pin_offsets, + .pin_count = ARRAY_SIZE(sdm660_pin_offsets) + ARRAY_SIZE(sdm660_special_pins_data), + .special_pins_start = 114, + .special_pins_data = sdm660_special_pins_data, + }, + .functions_count = ARRAY_SIZE(sdm660_pinctrl_functions), + .get_function_name = sdm660_get_function_name, + .get_function_mux = sdm660_get_function_mux, + .get_pin_name = sdm660_get_pin_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { + .compatible = "qcom,sdm630-pinctrl", + .data = (ulong)&sdm660_data + }, + { + .compatible = "qcom,sdm660-pinctrl", + .data = (ulong)&sdm660_data + }, + { /* Sentinel */ } +}; + +U_BOOT_DRIVER(pinctrl_ssdm660) = { + .name = "pinctrl_sdm660", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, +}; -- cgit v1.3.1 From fd775fb7aff82b55832f1d345d0ac07d7bd448e8 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:18 +0200 Subject: board/qualcomm: introduce phone config Phones don't have keyboards! Introduce a phone-specific config fragment and associated environment file to make U-Boot more useful on these devices. This allows for navigating via the buttons and enabling various USB gadget modes or displaying info about U-Boot. Reviewed-by: Simon Glass Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-1-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/qcom-phone.config | 29 +++++++++++++++++++++++++ board/qualcomm/qcom-phone.env | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 board/qualcomm/qcom-phone.config create mode 100644 board/qualcomm/qcom-phone.env diff --git a/board/qualcomm/qcom-phone.config b/board/qualcomm/qcom-phone.config new file mode 100644 index 00000000000..913c91757c1 --- /dev/null +++ b/board/qualcomm/qcom-phone.config @@ -0,0 +1,29 @@ +# Settings for phones +CONFIG_DEFAULT_ENV_FILE="board/qualcomm/qcom-phone.env" +# Hang on panic so the error message can be read +CONFIG_PANIC_HANG=y +# We use pause in various places to allow text to be read +# before it scrolls off the screen +CONFIG_CMD_PAUSE=y +CONFIG_BOOT_RETRY=y +CONFIG_BOOT_RETRY_TIME=1 +CONFIG_BUTTON_REMAP_PHONE_KEYS=y +CONFIG_RETRY_BOOTCMD=y +CONFIG_FASTBOOT_BUF_ADDR=0x1A000000 +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_USB_FUNCTION_ACM=y +CONFIG_CMD_UMS_ABORT_KEYED=y + +# Record all console output and let it be dumped via fastboot +CONFIG_CONSOLE_RECORD=y +CONFIG_CONSOLE_RECORD_INIT_F=y +CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 +CONFIG_FASTBOOT_CMD_OEM_CONSOLE=y + +# Only MMC is supported by fastboot currently, but this is still useful. +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_OEM_RUN=y + +# Many phones don't actually define a serial port in their DTS +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set diff --git a/board/qualcomm/qcom-phone.env b/board/qualcomm/qcom-phone.env new file mode 100644 index 00000000000..e91ae3ecdfb --- /dev/null +++ b/board/qualcomm/qcom-phone.env @@ -0,0 +1,47 @@ +bootdelay=0 +bootretry=1 +stdin=serial,button-kbd +stdout=serial,vidconsole +stderr=serial,vidconsole + +# Fastboot is keen to use the address from kconfig, but we +# allocate its buffer at runtime. +fastboot=fastboot -l $fastboot_addr_r usb 0 + +# Always probe for UFS storage, though it should be done by board code. +preboot=scsi scan + +# Shortcut to enable USB serial gadget and disable bootretry +serial_gadget=setenv stdin serial,button-kbd,usbacm; \ + setenv stdout serial,vidconsole,usbacm; \ + setenv stderr serial,vidconsole,usbacm; \ + setenv bootretry -1; \ + echo Enabled U-Boot console serial gadget + +# bootretry will run this command over and over, if we fail once +# then bail out to the boot menu instead (with a pause to read +# the error message) +bootcmd=bootefi bootmgr; pause; run menucmd + +# When entering the menu (either from button press or failed boot) +# remap bootcmd so it will re-open the menu and we won't get stuck +# at the console with no way to type +menucmd=setenv bootcmd run menucmd; bootmenu -1 + +# Pause is used so the output can be read on the display +bootmenu_0=Boot=bootefi bootmgr; pause +bootmenu_1=Enable serial console gadget=run serial_gadget +bootmenu_2=Enable USB mass storage=echo "Press any key to exit UMS mode"; ums 0 scsi 0 +bootmenu_3=Enable fastboot mode=run fastboot +# Disabling bootretry means we'll just drop the shell +bootmenu_4=Drop to shell=setenv bootretry -1 +bootmenu_5=Reset device=reset +bootmenu_6=Dump clocks=clk dump; pause +bootmenu_7=Dump environment=printenv; pause +bootmenu_8=Board info=bdinfo; pause +bootmenu_9=Dump bootargs=fdt print /chosen bootargs; pause + +# Allow holding the volume down button while U-Boot loads to enter +# the boot menu +button_cmd_0_name=Volume Down +button_cmd_0=run menucmd -- cgit v1.3.1 From 657e19f8f2dd279d3db6744d3d6859952d67c8c9 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:19 +0200 Subject: cli_hush: support running bootcmd on boot retry Introduce a new config option: RETRY_BOOTCMD. When enabled this causes hush shell to re-run "bootcmd" when the auto-boot counter times out. Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-2-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- boot/Kconfig | 7 +++++++ common/cli_hush.c | 6 ++++-- common/cli_hush_upstream.c | 6 ++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/boot/Kconfig b/boot/Kconfig index f101200ba7a..fb37d912bc9 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1704,6 +1704,13 @@ config RESET_TO_RETRY After the countdown timed out, the board will be reset to restart again. +config RETRY_BOOTCMD + bool "Run bootcmd on retry" + depends on BOOT_RETRY && HUSH_PARSER && !RESET_TO_RETRY + help + If this option is enabled, the "bootcmd" will be run after the + countdown times out. + endmenu menu "Image support" diff --git a/common/cli_hush.c b/common/cli_hush.c index 9f437ae5f47..7bd6943d3ed 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -1028,8 +1028,10 @@ static void get_user_input(struct in_str *i) puts("\nTimeout waiting for command\n"); # ifdef CONFIG_RESET_TO_RETRY do_reset(NULL, 0, 0, NULL); -# else -# error "This currently only works with CONFIG_RESET_TO_RETRY enabled" +# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) + strcpy(console_buffer, "run bootcmd\n"); +# else +# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" # endif } #endif diff --git a/common/cli_hush_upstream.c b/common/cli_hush_upstream.c index ab5aa5f9b36..748ef60ac90 100644 --- a/common/cli_hush_upstream.c +++ b/common/cli_hush_upstream.c @@ -2907,8 +2907,10 @@ static void get_user_input(struct in_str *i) puts("\nTimeout waiting for command\n"); # ifdef CONFIG_RESET_TO_RETRY do_reset(NULL, 0, 0, NULL); -# else -# error "This currently only works with CONFIG_RESET_TO_RETRY enabled" +# elif IS_ENABLED(CONFIG_RETRY_BOOTCMD) + strcpy(console_buffer, "run bootcmd\n"); +# else +# error "This only works with CONFIG_RESET_TO_RETRY or CONFIG_BOOT_RETRY_COMMAND enabled" # endif } # endif -- cgit v1.3.1 From aa5ef3c0a752701abffe071690a6246193be9d1c Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:20 +0200 Subject: bootretry: check for bootretry variable changes To enable more complex sequencing of the bootmenu, autoboot, and bootretry, handle changes to the bootretry variable between tries. This makes it possible to turn bootretry off (e.g. to drop to a shell) and then back on again. This makes it possible to have a persistent bootmenu (the only way to navigate U-Boot on devices like smartphones which lack a physical keyboard) by having bootcmd be defined to launch the bootmenu. This allows for menu options like enabling USB mass storage gadget to return back to the boot menu once the gadget is shut down. Reviewed-by: Tom Rini Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-3-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- boot/bootretry.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/bootretry.c b/boot/bootretry.c index 587b2de7d6b..a60767eaa2e 100644 --- a/boot/bootretry.c +++ b/boot/bootretry.c @@ -37,6 +37,8 @@ void bootretry_init_cmd_timeout(void) */ void bootretry_reset_cmd_timeout(void) { + /* Parse changes to bootretry */ + bootretry_init_cmd_timeout(); endtime = endtick(retry_time); } -- cgit v1.3.1 From 4509f8183970267de12ca1478b4c9f054b411c5f Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:21 +0200 Subject: doc: board/qualcomm: describe phone support and bringup Add some documentation which attempts to describe Qualcomm smartphone support with the qcom-phone.config fragment, as well as a high level debugging guide for diagnosing U-Boot issues when UART and framebuffer are unavailable. Reviewed-by: Simon Glass Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-4-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- doc/board/qualcomm/board.rst | 5 ++ doc/board/qualcomm/index.rst | 1 + doc/board/qualcomm/phones.rst | 144 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 doc/board/qualcomm/phones.rst diff --git a/doc/board/qualcomm/board.rst b/doc/board/qualcomm/board.rst index 4d793209f9e..003d59a18eb 100644 --- a/doc/board/qualcomm/board.rst +++ b/doc/board/qualcomm/board.rst @@ -90,6 +90,11 @@ Or for db410c (and other boards not supported by the generic target):: make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig make O=.output -j$(nproc) +Or for smartphones:: + + make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config + make O=.output -j$(nproc) + - gzip u-boot:: gzip u-boot-nodtb.bin diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst index 66bc922033a..e2fcbfa19c2 100644 --- a/doc/board/qualcomm/index.rst +++ b/doc/board/qualcomm/index.rst @@ -9,5 +9,6 @@ Qualcomm dragonboard410c rb3gen2 board + phones debugging rdp diff --git a/doc/board/qualcomm/phones.rst b/doc/board/qualcomm/phones.rst new file mode 100644 index 00000000000..1d27196cf54 --- /dev/null +++ b/doc/board/qualcomm/phones.rst @@ -0,0 +1,144 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Caleb Connolly + +====================================== +Booting U-Boot on Qualcomm smartphones +====================================== + +About this +---------- + +This page attempts to the describe U-Boot support for Qualcomm phones, as a user guide but also a +technical introduction to How Stuff Works to help new porters. + +In broad strokes, U-Boot should boot if the SoC is supported, and the device is already capable of +booting an upstream Linux kernel. + +The list of supported Qualcomm SoCs changes often, for now it is best to look in +``drivers/clk/qcom/`` to get a rough idea. + +For building instructions, see :doc:`board`. + +Phone bringup +------------- + +It is usually easier to get Linux booting first, there are many good resources for this such as the +`postmarketOS wiki`_. Once the device can boot Linux with logs on the display and ideally USB gadget +support, it is highly likely that U-Boot will boot as well. + +For logs on display, you should have a simple framebuffer node defined in your DT, newer devices +require that this follow the downstream naming scheme (that the DTB is compiled with labels enabled +and the framebuffer reserved-memory region is labelled ``cont_splash``). Once this is working in +Linux it should also work in U-Boot. + +In practise, U-Boot still has many more papercuts than Linux, which can be sticking points when +porting a new device. In particular, drivers failing to bind/probe (especially pre-relocation) can +be tricky to debug without UART since U-Boot will simply panic with no way to inform you of +the error. As a result, bringing up a new device can be quite frustrating, but there are quite a few +things you can try. + +The phone config +^^^^^^^^^^^^^^^^ + +Since most phones lack a physical keyboard or serial port, a special config fragment and environment +file can be used to provide a more seamless experience. This can be enabled by generating the config +with:: + + make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config + +The config and associated environment file can be found in board/qualcomm/. The main changes are: + +- Panic on hang (so the panic message can be read on the display) +- Boot retry (to automatically open and re-open the bootmenu) +- A boot menu with helpful shortcuts (including USB console gadget) +- Launch the boot menu if power is held during boot or on boot failure + +Fastboot mode +------------- + +U-Boot's fastboot implementation is much more limited than Qualcomm's, and currently does not have a +backend for UFS storage. If your device uses eMMC or has an sdcard slot, fastboot will use that by +default. + +You may need to run the fastboot command on your PC as root since the USB product/vendor ID may not +match the android udev rules. + +You can also use fastboot to run arbitrary U-Boot commands with ``fastboot oem run`` + +Retrieving early logs +^^^^^^^^^^^^^^^^^^^^^ + +U-Boot is configured to save it's internal log to a buffer, this can help with debugging some driver +bind/probe issues. If your device can boot and has working USB, you can enable fastboot mode (either +via the U-Boot menu or by adding ``run fastboot`` to the end of the ``preboot=`` config in +``board/qualcomm/qcom-phone.env``). + +You can then retrieve U-Boot's log buffer with the ``fastboot oem log`` command on your PC. + +Hang/crash bisection +-------------------- + +Without a way to get logs, we can still get quite far with only a few bits of information: what +happens when you ``fastboot boot u-boot.img``? + +Does the device disconnect? +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This can be verified by watching ``dmesg -w``. If it stays connected, it likely means the boot image +doesn't match what the bootloader expected, use ``unpack_bootimg`` to compare it with a known-good +boot image (ideally one with an upstream kernel). + +Does the device hang? +^^^^^^^^^^^^^^^^^^^^^ + +If it stays on a black screen and does nothing, then that's a hang! Since ``qcom-phone.config`` +enables CONFIG_PANIC_HANG, this likely means that you're successfully executing U-Boot code (yay!), +but something is causing a panic. + +It could also be due to a bad memory or register access triggering a secure interrupt, it's worth +waiting for around a minute to see if the device eventually reboots or goes to crashdump mode. You +can also disable CONFIG_PANIC_HANG and see if that causes the device to reboot instead, if so then +it is definitely a U-Boot panic. + +With enough time and patience, it should be possible to narrow down the cause of the panic by +inserting calls to ``reset_cpu()`` (with CONFIG_PANIC_HANG enabled). Then if the device resets you +know it executed the ``reset_cpu()`` call. + +A good place to start is ``board_fdt_blob_setup()`` in ``arch/arm/mach-snapdragon/board.c``, this +function is called extremely early so adding a reset call is a good way to validate that U-Boot is +definitely running. + +You can then do a binary search starting from the end of ``board_init_f()`` / start of +``board_init_r()`` and work from there using the init sequences for reference. + +The Qualcomm RAM parsing code is a likely culprit, as ABL is known to sometimes give bogus entries +in the memory node which can trip U-Boot up. + +To rule out crashes that might be caused by specific drivers, it's a good idea to disable them and +re-enable them one by one. Here is a non-exhaustive list of drivers to disable: + +- pinctrl +- mmc +- scsi/ufs +- usb (dwc3) +- phy (usb, ufs) +- clk (remove clock references from your framebuffer node in DT) + +Ideally, it would be possible to use the framebuffer as an early console / debug output, at the time +of writing there are out of tree patches for this but they haven't been submitted upstream yet. + +Does the device reboot or go to crashdump mode? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On many devices crashdump mode is disabled, so they will reboot instead (maybe after some delay). +The same approach as suggested above can be used to figure out where the crash occurs. + +If the device is rebooting, you can insert calls to ``hang()`` instead of ``reset_cpu()`` when +following the instructions above. + +The most likely cause of a crashdump is the pinctrl/gpio driver or the SMMU driver, ensure that the +``apps_smmu`` node in your SoCs devicetree file has one of its compatible strings referenced in +``drivers/iommu/qcom-hyp-smmu.c``, you can also try disabling the pinctrl driver for your SoC (or +``CONFIG_PINCTRL`` altogether). + +.. _`postmarketOS wiki`: https://wiki.postmarketos.org/wiki/Mainlining -- cgit v1.3.1 From 8f5685d5d32f50e8a3634686218e3fd143075d93 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:22 +0200 Subject: button: qcom-pmic: prettify and standardise button labels Boards using gpio-keys for volume buttons label them "Volume Down", let's match that here, and make the power button nicer too. This simplifies configuring button_cmds in a board-agnostic way. Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-5-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.c | 2 +- board/qualcomm/dragonboard820c/dragonboard820c.c | 2 +- drivers/button/button-qcom-pmic.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index fcbf2c3fe60..d0d82489f53 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -72,7 +72,7 @@ int misc_init_r(void) int ret; enum button_state_t state; - ret = button_get_by_label("vol_down", &btn); + ret = button_get_by_label("Volume Down", &btn); if (ret < 0) { printf("Couldn't find power button!\n"); return ret; diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c index d3333a59db0..12a9273ec4b 100644 --- a/board/qualcomm/dragonboard820c/dragonboard820c.c +++ b/board/qualcomm/dragonboard820c/dragonboard820c.c @@ -106,7 +106,7 @@ int misc_init_r(void) int ret; enum button_state_t state; - ret = button_get_by_label("pwrkey", &btn); + ret = button_get_by_label("Power Button", &btn); if (ret < 0) { printf("Couldn't find power button!\n"); return ret; diff --git a/drivers/button/button-qcom-pmic.c b/drivers/button/button-qcom-pmic.c index f9f0948ae09..e3bb9bd758a 100644 --- a/drivers/button/button-qcom-pmic.c +++ b/drivers/button/button-qcom-pmic.c @@ -73,25 +73,25 @@ static const struct qcom_pmic_btn_data qcom_pmic_btn_data_table[] = { .compatible = "qcom,pm8941-pwrkey", .status_bit = PON_KPDPWR_N_SET, .code = KEY_ENTER, - .label = "pwrkey", + .label = "Power Button", }, { .compatible = "qcom,pm8941-resin", .status_bit = PON_RESIN_N_SET, .code = KEY_DOWN, - .label = "vol_down", + .label = "Volume Down", }, { .compatible = "qcom,pmk8350-pwrkey", .status_bit = PON_GEN3_KPDPWR_N_SET, .code = KEY_ENTER, - .label = "pwrkey", + .label = "Power Button", }, { .compatible = "qcom,pmk8350-resin", .status_bit = PON_GEN3_RESIN_N_SET, .code = KEY_DOWN, - .label = "vol_down", + .label = "Volume Down", }, }; -- cgit v1.3.1 From 9c607005c51976b5e0301461bfc0f38d5bdebd0e Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Mon, 31 Mar 2025 14:23:23 +0200 Subject: button: make button_get_by_label() case insensitive This function is already doing a fuzzy match, since there are no guarantees that a given label is unique. Ignoring case makes it much easier to catch "Volume down" or "Volume Down" in board-agnostic code. Tested-by: Danila Tikhonov # google-sunfish Tested-by: Jens Reidel # xiaomi-davinci Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250331-qcom-phones-v4-6-f52e57d3b8c6@linaro.org Signed-off-by: Caleb Connolly --- drivers/button/button-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/button/button-uclass.c b/drivers/button/button-uclass.c index 729983d5870..025917887e8 100644 --- a/drivers/button/button-uclass.c +++ b/drivers/button/button-uclass.c @@ -21,7 +21,7 @@ int button_get_by_label(const char *label, struct udevice **devp) struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); /* Ignore the top-level button node */ - if (uc_plat->label && !strcmp(label, uc_plat->label)) + if (uc_plat->label && !strcasecmp(label, uc_plat->label)) return uclass_get_device_tail(dev, 0, devp); } -- cgit v1.3.1 From 91ba4976c05882f88232eaa4fc5eb9192701dbe3 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Thu, 10 Apr 2025 10:52:38 +0200 Subject: pinctrl: qcom: handle reserved ranges Some Qualcomm boards feature reserved ranges of pins which are protected by firmware. Attempting to read or write any registers associated with these pins results the board resetting. Add support for parsing these ranges from devicetree and ensure that the pinctrl and GPIO drivers don't try to interact with these pins. Signed-off-by: Neil Armstrong Reviewed-by: Sumit Garg Link: https://lore.kernel.org/r/20250410-topic-sm8x50-pinctrl-reserved-ranges-v2-1-654488392b9a@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/mach-snapdragon/include/mach/gpio.h | 15 +++++++ drivers/gpio/msm_gpio.c | 10 +++++ drivers/pinctrl/qcom/pinctrl-qcom.c | 67 ++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/arch/arm/mach-snapdragon/include/mach/gpio.h b/arch/arm/mach-snapdragon/include/mach/gpio.h index cc8f405e20b..11e8104baf2 100644 --- a/arch/arm/mach-snapdragon/include/mach/gpio.h +++ b/arch/arm/mach-snapdragon/include/mach/gpio.h @@ -46,4 +46,19 @@ static inline bool qcom_is_special_pin(const struct msm_pin_data *pindata, unsig return pindata->special_pins_start && pin >= pindata->special_pins_start; } +struct udevice; + +/** + * msm_pinctrl_is_reserved() - Check if a pin lies in a reserved range + * + * @dev: pinctrl device + * @pin: Pin number + * + * Returns: true if pin is reserved, otherwise false + * + * Call using dev_get_parent() from the GPIO device, it is a child of + * the pinctrl device. + */ +bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin); + #endif /* _QCOM_GPIO_H_ */ diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index 54afd44fbd3..6783fc756f4 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -151,6 +151,9 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio, static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags) { + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return -EPERM; + if (flags & GPIOD_IS_OUT_ACTIVE) { return msm_gpio_direction_output(dev, gpio, 1); } else if (flags & GPIOD_IS_OUT) { @@ -193,6 +196,9 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return -EPERM; + if (qcom_is_special_pin(priv->pin_data, gpio)) return msm_gpio_get_value_special(priv, gpio); @@ -232,6 +238,10 @@ static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return GPIOF_UNKNOWN; + + /* Always NOP for special pins, assume they're in the correct state */ if (qcom_is_special_pin(priv->pin_data, gpio)) return msm_gpio_get_function_special(priv, gpio); diff --git a/drivers/pinctrl/qcom/pinctrl-qcom.c b/drivers/pinctrl/qcom/pinctrl-qcom.c index 24d031947a3..c95db56bc47 100644 --- a/drivers/pinctrl/qcom/pinctrl-qcom.c +++ b/drivers/pinctrl/qcom/pinctrl-qcom.c @@ -15,14 +15,18 @@ #include #include #include +#include #include #include #include "pinctrl-qcom.h" +#define MSM_PINCTRL_MAX_PINS 256 + struct msm_pinctrl_priv { phys_addr_t base; struct msm_pinctrl_data *data; + DECLARE_BITMAP(reserved_map, MSM_PINCTRL_MAX_PINS); }; #define GPIO_CONFIG_REG(priv, x) \ @@ -71,13 +75,60 @@ static const char *msm_get_function_name(struct udevice *dev, return priv->data->get_function_name(dev, selector); } +static int msm_pinctrl_parse_ranges(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + ofnode node = dev_ofnode(dev); + int ret, count, i; + u32 *ranges; + + if (ofnode_read_prop(node, "gpio-reserved-ranges", &count)) { + if (count % 2 == 1) { + dev_err(dev, "gpio-reserved-ranges must be a multiple of 2\n"); + return -EINVAL; + } + + ranges = malloc(count); + if (!ranges) + return -ENOMEM; + + ret = ofnode_read_u32_array(node, "gpio-reserved-ranges", ranges, count / 4); + if (ret) { + dev_err(dev, "failed to read gpio-reserved-ranges array (%d)\n", ret); + return ret; + } + + for (i = 0; i < count / 4; i += 2) { + if (ranges[i] >= MSM_PINCTRL_MAX_PINS || + (ranges[i] + ranges[i + 1]) >= MSM_PINCTRL_MAX_PINS) { + dev_err(dev, "invalid reserved-range (%d;%d)\n", + ranges[i], ranges[i + 1]); + return -EINVAL; + } + + bitmap_set(priv->reserved_map, ranges[i], ranges[i + 1]); + } + + free(ranges); + } + + return 0; +} + static int msm_pinctrl_probe(struct udevice *dev) { struct msm_pinctrl_priv *priv = dev_get_priv(dev); + int ret; priv->base = dev_read_addr(dev); priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev); + ret = msm_pinctrl_parse_ranges(dev); + if (ret) { + printf("Couldn't parse reserved GPIO ranges!\n"); + return ret; + } + return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; } @@ -97,6 +148,9 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector, if (func < 0) return func; + if (msm_pinctrl_is_reserved(dev, pin_selector)) + return -EPERM; + /* Always NOP for special pins, assume they're in the correct state */ if (qcom_is_special_pin(&priv->data->pin_data, pin_selector)) return 0; @@ -145,6 +199,9 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, { struct msm_pinctrl_priv *priv = dev_get_priv(dev); + if (msm_pinctrl_is_reserved(dev, pin_selector)) + return -EPERM; + if (qcom_is_special_pin(&priv->data->pin_data, pin_selector)) return msm_pinconf_set_special(priv, pin_selector, param, argument); @@ -241,3 +298,13 @@ U_BOOT_DRIVER(pinctrl_qcom) = { .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, }; + +bool msm_pinctrl_is_reserved(struct udevice *dev, unsigned int pin) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + if (pin >= MSM_PINCTRL_MAX_PINS) + return false; + + return test_bit(pin, priv->reserved_map); +} -- cgit v1.3.1 From fa9eb2f1e6a4feb28f2fa489e153fac249b117fb Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:22 +0200 Subject: mach-snapdragon: Fix EL2 boot on DragonBoard 410c The workaround for the "PSCI bug" on DragonBoard 410c implemented in arch/arm/mach-snapdragon/include/mach/boot0.h clobbers the x0 register by storing the CurrentEL in there. When running in EL1, the mode switch sequence implemented there later clears the register again, but this is skipped when U-Boot is booted in EL2. This causes crashes in the mach-snapdragon board_fdt_blob_setup() later, because the invalid address stored in x0 gets dereferenced to check if it points to a valid DTB. We can't rely on having a valid values in the CPU registers for the first stage bootloader configuration on DB410c, and nothing would place a DTB there anyway. Skip selecting the SAVE_PREV_BL_FDT_ADDR option for the boot0 hook case to avoid crashing with the clobbered register value. Fixes: 059d526af312 ("mach-snapdragon: generalise board support") Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-1-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6e234af4ac9..d8c99d3ab19 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1120,7 +1120,7 @@ config ARCH_SNAPDRAGON select SPMI select BOARD_LATE_INIT select OF_BOARD - select SAVE_PREV_BL_FDT_ADDR + select SAVE_PREV_BL_FDT_ADDR if !ENABLE_ARM_SOC_BOOT0_HOOK select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK select SYSRESET select SYSRESET_PSCI -- cgit v1.3.1 From c53664c68105bc0a183b516f1cf77fdfd7a1e1a5 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:23 +0200 Subject: board: dragonboard410c: Fix RAM size DB410c has exactly 1 GiB of RAM. Some of it is reserved, but this is described separately in the DT. This was fixed before in commit 1d667227ea51 ("board: dragonboard410c: Fix PHYS_SDRAM_1_SIZE"), but was reintroduced when DB410c was converted to use the upstream device tree. Note that there are variants of apq8016-sbc with 2 GiB RAM (e.g. the Geniatech DB4). They need the WIP SMEM memory map parsing [1] to use the full amount of RAM. [1]: https://lore.kernel.org/u-boot/20241124-b4-modernise-smem-v1-0-b7852c11b67c@linaro.org/T/ Fixes: ed8fbd2889fc ("dts: msm8916: replace with upstream DTS") Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-2-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- arch/arm/dts/apq8016-sbc-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/apq8016-sbc-u-boot.dtsi b/arch/arm/dts/apq8016-sbc-u-boot.dtsi index 585d54d2962..c8a46ed1448 100644 --- a/arch/arm/dts/apq8016-sbc-u-boot.dtsi +++ b/arch/arm/dts/apq8016-sbc-u-boot.dtsi @@ -6,7 +6,7 @@ / { /* When running as a first-stage bootloader this isn't filled in automatically */ memory@80000000 { - reg = <0 0x80000000 0 0x3da00000>; + reg = <0 0x80000000 0 0x40000000>; }; }; -- cgit v1.3.1 From 2cc2dc23360144129ab2f5e39356fae93c479dcc Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:24 +0200 Subject: board: dragonboard410c: Fix BD address local-bd-address in the device tree needs to be formatted with the least significant byte first (i.e. little endian). We're not doing this when adding it to the DT, which means the MAC address ends up being reversed in Linux. Fix this by reversing the array before setting it in the DT. We're also flipping the wrong bit when generating the BD address. Before reversing the array, the least significant bit is in the last byte. Fixes: ff06dc240325 ("db410: alter WLAN/BT MAC address fixup") Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-3-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.c | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index d0d82489f53..744ac4fda8e 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -97,9 +97,9 @@ int qcom_late_init(void) return 0; } -/* Fixup of DTB for Linux Kernel - * 1. Fixup installed DRAM. - * 2. Fixup WLAN/BT Mac address: +/* + * Fixup of DTB for Linux Kernel + * 1. Fixup WLAN/BT Mac address: * First, check if MAC addresses for WLAN/BT exists as environemnt * variables wlanaddr,btaddr. if not, generate a unique address. */ @@ -107,6 +107,7 @@ int qcom_late_init(void) int ft_board_setup(void *blob, struct bd_info *bd) { u8 mac[ARP_HLEN]; + int i; if (!eth_env_get_enetaddr("wlanaddr", mac)) { msm_generate_mac_addr(mac); @@ -118,12 +119,24 @@ int ft_board_setup(void *blob, struct bd_info *bd) if (!eth_env_get_enetaddr("btaddr", mac)) { msm_generate_mac_addr(mac); -/* The BD address is same as WLAN MAC address but with - * least significant bit flipped. - */ - mac[0] ^= 0x01; + /* + * The BD address is same as WLAN MAC address but with + * least significant bit flipped. + */ + mac[ARP_HLEN - 1] ^= 0x01; }; + /* + * Reverse array since local-bd-address is formatted with least + * significant byte first (little endian). + */ + for (i = 0; i < ARP_HLEN / 2; ++i) { + u8 tmp = mac[i]; + + mac[i] = mac[ARP_HLEN - 1 - i]; + mac[ARP_HLEN - 1 - i] = tmp; + } + do_fixup_by_compat(blob, "qcom,wcnss-bt", "local-bd-address", mac, ARP_HLEN, 1); return 0; -- cgit v1.3.1 From f7d3009b39d4f0ba0300e9312f51387d3ed343e2 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:25 +0200 Subject: board: dragonboard410c: Drop UNSTUFF_BITS() macro This was originally taken from Linux, but at this point it's an inline function upstream and no longer a macro. Given that we just want to extract the serial number from the MMC CID, let's just inline that specifically. This is also the style used in the MMC core code within U-Boot. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-4-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index 744ac4fda8e..b3f9a097e78 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -22,21 +22,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* UNSTUFF_BITS macro taken from Linux Kernel: drivers/mmc/core/sd.c */ -#define UNSTUFF_BITS(resp, start, size) \ - ({ \ - const int __size = size; \ - const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ - const int __off = 3 - ((start) / 32); \ - const int __shft = (start) & 31; \ - u32 __res; \ - \ - __res = resp[__off] >> __shft; \ - if (__size + __shft > 32) \ - __res |= resp[__off - 1] << ((32 - __shft) % 32); \ - __res & __mask; \ - }) - static u32 msm_board_serial(void) { struct mmc *mmc_dev; @@ -48,7 +33,8 @@ static u32 msm_board_serial(void) if (mmc_init(mmc_dev)) return 0; - return UNSTUFF_BITS(mmc_dev->cid, 16, 32); + /* MMC serial number */ + return mmc_dev->cid[2] << 16 | mmc_dev->cid[3] >> 16; } static void msm_generate_mac_addr(u8 *mac) -- cgit v1.3.1 From 49f2e9780bbcb728d5ea8217bd0704aa95dee072 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:26 +0200 Subject: board: dragonboard410c: Drop reflash functionality This is broken ever since we switched to using U-Boot as first stage bootloader. Since no one seems to test this actively, let's just drop this entirely. There are other tools available for re-flashing the DB410c. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-5-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.env | 26 ---------------------- 1 file changed, 26 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.env b/board/qualcomm/dragonboard410c/dragonboard410c.env index 9d9a575a0c3..57a30031f74 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.env +++ b/board/qualcomm/dragonboard410c/dragonboard410c.env @@ -1,30 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0+ */ - -/* Does what recovery does */ -#define REFLASH(file, partnum) \ -part start mmc 0 partnum start && \ -part size mmc 0 partnum size && \ -tftp $loadaddr file && \ -mmc write $loadaddr $start $size && - -reflash= -mmc dev 0 && -usb start && -dhcp && -tftp $loadaddr dragonboard/rescue/gpt_both0.bin && -mmc write $loadaddr 0 43 && -mmc rescan && -REFLASH(dragonboard/rescue/NON-HLOS.bin, 1) -REFLASH(dragonboard/rescue/sbl1.mbn, 2) -REFLASH(dragonboard/rescue/rpm.mbn, 3) -REFLASH(dragonboard/rescue/tz.mbn, 4) -REFLASH(dragonboard/rescue/hyp.mbn, 5) -REFLASH(dragonboard/rescue/sec.dat, 6) -REFLASH(dragonboard/rescue/emmc_appsboot.mbn, 7) -REFLASH(dragonboard/u-boot.img, 8) -usb stop && -echo Reflash completed - loadaddr=0x81000000 initrd_high=0xffffffffffffffff linux_image=Image -- cgit v1.3.1 From 7fde40768c1e14a47025b21c1460aa9c07f0a8ed Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:27 +0200 Subject: board: dragonboard410c: Drop unused linux_image This does not seem to be used anywhere. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-6-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.env | 1 - 1 file changed, 1 deletion(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.env b/board/qualcomm/dragonboard410c/dragonboard410c.env index 57a30031f74..eb42c0abcf1 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.env +++ b/board/qualcomm/dragonboard410c/dragonboard410c.env @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ loadaddr=0x81000000 initrd_high=0xffffffffffffffff -linux_image=Image kernel_addr_r=0x81000000 fdtfile=qcom/apq8016-sbc.dtb fdt_addr_r=0x83000000 -- cgit v1.3.1 From 39ae0bc73eefd5b71f358eceb393cacfd514056d Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:28 +0200 Subject: board: dragonboard410c: Use dynamically allocated load addresses The generic Qualcomm board code allocates addresses for loading the kernel, ramdisk, DT, fastboot etc. This also happens on the DB410c and already overrides these definitions defined in the default env. So let's just drop the static ones, since the dynamic ones work just fine. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-7-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.c | 2 +- board/qualcomm/dragonboard410c/dragonboard410c.env | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index b3f9a097e78..83862f117a2 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -66,7 +66,7 @@ int misc_init_r(void) state = button_get_state(btn); if (state == BUTTON_ON) { - env_set("preboot", "setenv preboot; fastboot 0"); + env_set("preboot", "setenv preboot; run fastboot"); printf("vol_down pressed - Starting fastboot.\n"); } diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.env b/board/qualcomm/dragonboard410c/dragonboard410c.env index eb42c0abcf1..0032dc3592a 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.env +++ b/board/qualcomm/dragonboard410c/dragonboard410c.env @@ -1,9 +1,3 @@ /* SPDX-License-Identifier: GPL-2.0+ */ -loadaddr=0x81000000 initrd_high=0xffffffffffffffff -kernel_addr_r=0x81000000 -fdtfile=qcom/apq8016-sbc.dtb -fdt_addr_r=0x83000000 -ramdisk_addr_r=0x84000000 -scriptaddr=0x90000000 -pxefile_addr_r=0x90100000 +fastboot=fastboot -l $fastboot_addr_r usb 0 -- cgit v1.3.1 From c68ef4484f6aebfb3c0d4fc8a5ced05d8b09b8a7 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:29 +0200 Subject: board: dragonboard410c: Fix counter frequency The actual counter frequency is 19.2 MHz, not 19.0 MHz. This isn't really used so far though, since probably no one (except me) ever tried using U-Boot in EL3 where we need to program the counter frequency. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-8-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- configs/dragonboard410c_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 5870aae83b4..b7f284b4fa2 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_SYS_BOARD="dragonboard410c" -CONFIG_COUNTER_FREQUENCY=19000000 +CONFIG_COUNTER_FREQUENCY=19200000 CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y CONFIG_ARCH_SNAPDRAGON=y CONFIG_TEXT_BASE=0x8f600000 -- cgit v1.3.1 From 69aa453d29ee46aa425326caeb5d873dbc70cd83 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:30 +0200 Subject: board: dragonboard410c: Enable RTL8152 ethernet The Geniatech DB4 V3 [1] has a RTL8152 onboard for Ethernet. I don't have one to test if that works, but the other USB Ethernet drivers work pretty much as-is, so just enable it with the assumption it will work out fine. [1]: https://www.96boards.org/product/db4/ Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-9-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- configs/dragonboard410c_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index b7f284b4fa2..da1ec4bfc60 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -69,6 +69,7 @@ CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_ASIX88179=y CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y CONFIG_USB_ETHER_SMSC95XX=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_VENDOR_NUM=0x18d1 -- cgit v1.3.1 From cfd27d130b3693eb2e0959befca6e1c739ed1f2d Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:31 +0200 Subject: board: dragonboard410c: Use BOOTSTD instead of DISTRO_DEFAULTS Reduce the environment size by using standard boot instead of distro boot. It uses faster bootdevs first by default (eMMC -> SD -> USB -> Network), so set "boot_targets" to keep the current ordering (USB -> SD -> eMMC -> Network). Perhaps this should be changed for consistency, but for now this keeps the behavior similar to before. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-10-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.env | 1 + configs/dragonboard410c_defconfig | 3 ++- include/configs/dragonboard410c.h | 11 ----------- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.env b/board/qualcomm/dragonboard410c/dragonboard410c.env index 0032dc3592a..71f929b646c 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.env +++ b/board/qualcomm/dragonboard410c/dragonboard410c.env @@ -1,3 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0+ */ initrd_high=0xffffffffffffffff fastboot=fastboot -l $fastboot_addr_r usb 0 +boot_targets=usb mmc1 mmc0 pxe diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index da1ec4bfc60..62fc42c9460 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -16,7 +16,7 @@ CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C" CONFIG_REMAKE_ELF=y # CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_FIT=y -CONFIG_DISTRO_DEFAULTS=y +CONFIG_BOOTSTD_FULL=y CONFIG_OF_BOARD_SETUP=y CONFIG_USE_PREBOOT=y CONFIG_SYS_CBSIZE=512 @@ -35,6 +35,7 @@ CONFIG_CMD_USB=y CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_CACHE=y CONFIG_CMD_TIMER=y +CONFIG_CMD_SYSBOOT=y CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_PART=2 diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h index 00102cd5c4f..c31c6c57c1a 100644 --- a/include/configs/dragonboard410c.h +++ b/include/configs/dragonboard410c.h @@ -18,15 +18,4 @@ #define PHYS_SDRAM_1_SIZE SZ_1G #define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1 -/* Environment */ -#define BOOT_TARGET_DEVICES(func) \ - func(USB, usb, 0) \ - func(MMC, mmc, 1) \ - func(MMC, mmc, 0) \ - func(DHCP, dhcp, na) - -#include - -#define CFG_EXTRA_ENV_SETTINGS BOOTENV - #endif -- cgit v1.3.1 From 268bfcd2160f9982b8277f5f400574ad52fab563 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:32 +0200 Subject: board: dragonboard410c: Enable support for Android boot images The U-Boot port for DB410c still has plenty of extra space available at this point, so avoid disabling features that would be normally enabled by default. In particular, this incldues support for Android boot images, which is quite likely to be used together with the USB Fastboot interface. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-11-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- configs/dragonboard410c_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 62fc42c9460..414dda6778c 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -14,7 +14,6 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_SYS_LOAD_ADDR=0x80080000 CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C" CONFIG_REMAKE_ELF=y -# CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_FIT=y CONFIG_BOOTSTD_FULL=y CONFIG_OF_BOARD_SETUP=y @@ -25,7 +24,6 @@ CONFIG_SYS_PBSIZE=548 # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_MISC_INIT_R=y CONFIG_SYS_PROMPT="dragonboard410c => " -# CONFIG_CMD_IMI is not set CONFIG_CMD_MD5SUM=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_GPIO=y -- cgit v1.3.1 From 359e1d4a57e06ab662ca7e008e881da27e9d3562 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:33 +0200 Subject: board: dragonboard410c: Use button_cmd instead of custom code Simplify the board code by using the new BUTTON_CMD functionality, instead of implementing this separately using C code. This allows disabling or customizing this functionality if wanted. Signed-off-by: Stephan Gerhold Reviewed-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-12-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/dragonboard410c.c | 22 ---------------------- board/qualcomm/dragonboard410c/dragonboard410c.env | 2 ++ configs/dragonboard410c_defconfig | 2 +- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c index 83862f117a2..4698b9d5e3e 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.c +++ b/board/qualcomm/dragonboard410c/dragonboard410c.c @@ -51,28 +51,6 @@ static void msm_generate_mac_addr(u8 *mac) put_unaligned_be32(msm_board_serial(), &mac[2]); } -/* Check for vol- button - if pressed - stop autoboot */ -int misc_init_r(void) -{ - struct udevice *btn; - int ret; - enum button_state_t state; - - ret = button_get_by_label("Volume Down", &btn); - if (ret < 0) { - printf("Couldn't find power button!\n"); - return ret; - } - - state = button_get_state(btn); - if (state == BUTTON_ON) { - env_set("preboot", "setenv preboot; run fastboot"); - printf("vol_down pressed - Starting fastboot.\n"); - } - - return 0; -} - int qcom_late_init(void) { char serial[16]; diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.env b/board/qualcomm/dragonboard410c/dragonboard410c.env index 71f929b646c..38399d65c64 100644 --- a/board/qualcomm/dragonboard410c/dragonboard410c.env +++ b/board/qualcomm/dragonboard410c/dragonboard410c.env @@ -2,3 +2,5 @@ initrd_high=0xffffffffffffffff fastboot=fastboot -l $fastboot_addr_r usb 0 boot_targets=usb mmc1 mmc0 pxe +button_cmd_0_name=vol_down +button_cmd_0=run fastboot diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 414dda6778c..449d48a3c00 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -14,6 +14,7 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_SYS_LOAD_ADDR=0x80080000 CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C" CONFIG_REMAKE_ELF=y +CONFIG_BUTTON_CMD=y CONFIG_FIT=y CONFIG_BOOTSTD_FULL=y CONFIG_OF_BOARD_SETUP=y @@ -22,7 +23,6 @@ CONFIG_SYS_CBSIZE=512 CONFIG_SYS_PBSIZE=548 # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_MISC_INIT_R=y CONFIG_SYS_PROMPT="dragonboard410c => " CONFIG_CMD_MD5SUM=y CONFIG_CMD_MEMINFO=y -- cgit v1.3.1 From f3563fc30356c8079527b90e532407050dff7c7b Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 7 Apr 2025 18:59:34 +0200 Subject: board: dragonboard410c: Update maintainers Ramon has been inactive on the U-Boot mailing list for over a year now and the DB410c port has not been updated much lately. I've been doing most of the DB410c-specific fixes/rework lately and try to test it every now and then, so add myself as new maintainer. Also add Sam as reviewer, since he's been doing lots of testing and reviews for MSM8916 recently. Cc: Sam Day Cc: Ramon Fried Signed-off-by: Stephan Gerhold Acked-by: Neil Armstrong Reviewed-by: Link: https://lore.kernel.org/r/20250407-db410c-fixes-v1-13-524aefbc8bb4@linaro.org Signed-off-by: Caleb Connolly --- board/qualcomm/dragonboard410c/MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/qualcomm/dragonboard410c/MAINTAINERS b/board/qualcomm/dragonboard410c/MAINTAINERS index e78f5b2d642..9c10fa3053b 100644 --- a/board/qualcomm/dragonboard410c/MAINTAINERS +++ b/board/qualcomm/dragonboard410c/MAINTAINERS @@ -1,5 +1,6 @@ DRAGONBOARD410C BOARD -M: Ramon Fried +M: Stephan Gerhold +R: Sam Day S: Maintained F: board/qualcomm/dragonboard410c/ F: include/configs/dragonboard410c.h -- cgit v1.3.1