All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/14] Qualcomm platform USB support
@ 2024-03-19 12:21 Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 01/14] mailmap: update Bhupesh's email address Caleb Connolly
                   ` (13 more replies)
  0 siblings, 14 replies; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:21 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot, Bhupesh Sharma, Bhupesh Sharma

This series enables USB on Qualcomm SDM845 platforms and lays the
foundation for future SoCs as well.

It introduces two new high-speed PHY drivers, one for SDM845 and one for
an upcoming platform. The SDM845 clock driver gains support for
configuring the USB clocks, and the GPIO driver is updated to use .set_flags
which fixes a strange bug where GPIOs would also be configured as input.

Support for super-speed USB modes is not currently available, however
configuring the device to be high-speed only requires modifications to
DT.

To improve compatibility with upstream DT, we switch Qualcomm platforms
over to OF_LIVE and apply fixups to the tree to remove references to the
super-speed phy, as well as configure the Qualcomm glue for high-speed
only mode.

The db845c requires a vbus-supply to be hooked up for its usb type-A
port. A U-Boot dtsi file is added to configure this.

With these patches, it is now also possible to run U-Boot on some SDM845
phones like the OnePlus 6 using a dtb from Linux, and access the U-Boot
shell via the CDC ACM USB serial gadget.

This series depends on the ("Qualcomm DWC3 USB support") series [1], as
well as Volodymyrs patches enabling power domain support [2].
A feature branch based on qcom-next with the necessary dependencies
for testing the Dragonboard845c can be found at [3].

[1]: https://lore.kernel.org/u-boot/20240319-b4-qcom-usb-v3-0-09ba1f86d259@linaro.org
[2]: https://lore.kernel.org/u-boot/20240311213334.3567389-1-volodymyr_babchuk@epam.com
[3]: https://git.codelinaro.org/linaro/qcomlt/u-boot/-/tree/b4/qcom-livetree

---
Changes in v3:
- Add back missing gadget options to qcom_defconfig (thanks Neil)
- Link to v2: https://lore.kernel.org/r/20240315-b4-qcom-livetree-v2-0-ab635774b2dc@linaro.org

Changes in v2:
- Fix incorrect order of NULL/0 parameters to of_write_prob() in
  fixup_qcom_dwc3()
- Move fixup_usb_nodes() to a separate file in preparation for future
  additions.
- Add missing break to switch case in sdm845_clk_enable()
- Remove rogue return statement in msm_gpio_set_flags()
- Rebase on Volodymyrs power domain patches.
- Link to v1: https://lore.kernel.org/r/20240131-b4-qcom-livetree-v1-0-4071c0787db0@linaro.org

---
Bhupesh Sharma (2):
      phy: qcom: add Qualcomm QUSB2 USB PHY driver
      phy: qcom: Add USB HS 7nm PHY driver

Caleb Connolly (12):
      mailmap: update Bhupesh's email address
      mach-snapdragon: disable power-domains for pre-reloc drivers
      clk/qcom: use offsets for RCG registers
      clk/qcom: sdm845: add gdscs
      clk/qcom: sdm845: add USB clocks
      gpio: msm_gpio: add .set_flags op
      serial: msm-geni: support livetree
      mach-snapdragon: fixup USB nodes
      mach-snapdragon: fixup power-domains
      dts: sdm845-db845c: add u-boot fixups
      qcom_defconfig: enable livetree
      qcom_defconfig: enable USB

 .mailmap                               |   1 +
 arch/arm/dts/sdm845-db845c-u-boot.dtsi |   8 +
 arch/arm/mach-snapdragon/Makefile      |   1 +
 arch/arm/mach-snapdragon/board.c       |   3 +
 arch/arm/mach-snapdragon/of_fixup.c    | 147 +++++++++++
 arch/arm/mach-snapdragon/qcom-priv.h   |  19 ++
 configs/qcom_defconfig                 |  52 ++--
 drivers/clk/qcom/clock-apq8016.c       |  39 +--
 drivers/clk/qcom/clock-apq8096.c       |  28 +-
 drivers/clk/qcom/clock-qcom.c          |  24 +-
 drivers/clk/qcom/clock-qcom.h          |  16 +-
 drivers/clk/qcom/clock-qcs404.c        | 121 ++-------
 drivers/clk/qcom/clock-sdm845.c        |  61 +++--
 drivers/gpio/msm_gpio.c                |  27 +-
 drivers/phy/qcom/Kconfig               |  15 ++
 drivers/phy/qcom/Makefile              |   2 +
 drivers/phy/qcom/phy-qcom-qusb2.c      | 468 +++++++++++++++++++++++++++++++++
 drivers/phy/qcom/phy-qcom-usb-hs-7nm.c | 295 +++++++++++++++++++++
 drivers/serial/serial_msm_geni.c       |  15 +-
 19 files changed, 1108 insertions(+), 234 deletions(-)
---
base-commit: 7194c72d0eef33d9b76555a281d808a0afe54ab5

// Caleb (they/them)


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v3 01/14] mailmap: update Bhupesh's email address
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver Caleb Connolly
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot, Bhupesh Sharma

Update Bhupesh's email to his new one.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---

Cc: Bhupesh Sharma <bhupesh.linux@gmail.com>
---
 .mailmap | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.mailmap b/.mailmap
index d1f08f3eca8a..f6e0847b2168 100644
--- a/.mailmap
+++ b/.mailmap
@@ -29,8 +29,9 @@ Ashok Reddy Soma <ashok.reddy.soma@amd.com> <ashok.reddy.soma@xilinx.com>
 Atish Patra <atishp@atishpatra.org> <atish.patra@wdc.com>
 Bharat Kumar Gogada <bharat.kumar.gogada@amd.com> <bharat.kumar.gogada@xilinx.com>
 Bharat Kumar Gogada <bharat.kumar.gogada@amd.com> <bharatku@xilinx.com>
 Bhargava Sreekantappa Gayathri <bhargava.sreekantappa-gayathri@amd.com> <bhargava.sreekantappa-gayathri@xilinx.com>
+Bhupesh Sharma <bhupesh.linux@gmail.com> <bhupesh.sharma@linaro.org>
 Bin Meng <bmeng.cn@gmail.com> <bin.meng@windriver.com>
 Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
 Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
 Christian Kohn <chris.kohn@amd.com> <christian.kohn@xilinx.com>

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 01/14] mailmap: update Bhupesh's email address Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:21   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 03/14] phy: qcom: Add USB HS 7nm " Caleb Connolly
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot, Bhupesh Sharma, Bhupesh Sharma

From: Bhupesh Sharma <bhupesh.linux@gmail.com>

The Snapdragon 845 and several other Qualcomm SoCs feature this
USB high-speed phy. Add a driver for it based on the Linux driver, with
support for the SDM845, and the QCM2290 and SM6115 SoCs which will gain
support in U-Boot in future patches.

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
[code cleanup, switch to clk_bulk]
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/phy/qcom/Kconfig          |   7 +
 drivers/phy/qcom/Makefile         |   1 +
 drivers/phy/qcom/phy-qcom-qusb2.c | 468 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 476 insertions(+)

diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
index f4ca174805a4..361dfb6e1126 100644
--- a/drivers/phy/qcom/Kconfig
+++ b/drivers/phy/qcom/Kconfig
@@ -11,8 +11,15 @@ config PHY_QCOM_IPQ4019_USB
 	depends on PHY && ARCH_IPQ40XX
 	help
 	  Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
 
+config PHY_QCOM_QUSB2
+	tristate "Qualcomm USB QUSB2 PHY driver"
+	depends on PHY && ARCH_SNAPDRAGON
+	help
+	  Enable this to support the Super-Speed USB transceiver on various
+	  Qualcomm chipsets.
+
 config PHY_QCOM_USB_HS_28NM
 	tristate "Qualcomm 28nm High-Speed PHY"
 	depends on PHY && ARCH_SNAPDRAGON
 	help
diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
index 2113f178c0c7..f6af985666a4 100644
--- a/drivers/phy/qcom/Makefile
+++ b/drivers/phy/qcom/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
 obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
+obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
 obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
 obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
diff --git a/drivers/phy/qcom/phy-qcom-qusb2.c b/drivers/phy/qcom/phy-qcom-qusb2.c
new file mode 100644
index 000000000000..5b654403a181
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-qusb2.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Bhupesh Sharma <bhupesh.sharma@linaro.org>
+ *
+ * Based on Linux driver
+ */
+
+#include <dm.h>
+#include <generic-phy.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <reset.h>
+#include <clk.h>
+#include <linux/delay.h>
+
+#include <dt-bindings/phy/phy-qcom-qusb2.h>
+
+#define QUSB2PHY_PLL 0x0
+#define QUSB2PHY_PLL_TEST 0x04
+#define CLK_REF_SEL BIT(7)
+
+#define QUSB2PHY_PLL_TUNE 0x08
+#define QUSB2PHY_PLL_USER_CTL1 0x0c
+#define QUSB2PHY_PLL_USER_CTL2 0x10
+#define QUSB2PHY_PLL_AUTOPGM_CTL1 0x1c
+#define QUSB2PHY_PLL_PWR_CTRL 0x18
+
+/* QUSB2PHY_PLL_STATUS register bits */
+#define PLL_LOCKED BIT(5)
+
+/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
+#define CORE_READY_STATUS BIT(0)
+
+/* QUSB2PHY_PORT_POWERDOWN register bits */
+#define CLAMP_N_EN BIT(5)
+#define FREEZIO_N BIT(1)
+#define POWER_DOWN BIT(0)
+
+/* QUSB2PHY_PWR_CTRL1 register bits */
+#define PWR_CTRL1_VREF_SUPPLY_TRIM BIT(5)
+#define PWR_CTRL1_CLAMP_N_EN BIT(1)
+
+#define QUSB2PHY_REFCLK_ENABLE BIT(0)
+
+#define PHY_CLK_SCHEME_SEL BIT(0)
+
+/* QUSB2PHY_INTR_CTRL register bits */
+#define DMSE_INTR_HIGH_SEL BIT(4)
+#define DPSE_INTR_HIGH_SEL BIT(3)
+#define CHG_DET_INTR_EN BIT(2)
+#define DMSE_INTR_EN BIT(1)
+#define DPSE_INTR_EN BIT(0)
+
+/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register bits */
+#define CORE_PLL_EN_FROM_RESET BIT(4)
+#define CORE_RESET BIT(5)
+#define CORE_RESET_MUX BIT(6)
+
+/* QUSB2PHY_IMP_CTRL1 register bits */
+#define IMP_RES_OFFSET_MASK GENMASK(5, 0)
+#define IMP_RES_OFFSET_SHIFT 0x0
+
+/* QUSB2PHY_PLL_BIAS_CONTROL_2 register bits */
+#define BIAS_CTRL2_RES_OFFSET_MASK GENMASK(5, 0)
+#define BIAS_CTRL2_RES_OFFSET_SHIFT 0x0
+
+/* QUSB2PHY_CHG_CONTROL_2 register bits */
+#define CHG_CTRL2_OFFSET_MASK GENMASK(5, 4)
+#define CHG_CTRL2_OFFSET_SHIFT 0x4
+
+/* QUSB2PHY_PORT_TUNE1 register bits */
+#define HSTX_TRIM_MASK GENMASK(7, 4)
+#define HSTX_TRIM_SHIFT 0x4
+#define PREEMPH_WIDTH_HALF_BIT BIT(2)
+#define PREEMPHASIS_EN_MASK GENMASK(1, 0)
+#define PREEMPHASIS_EN_SHIFT 0x0
+
+/* QUSB2PHY_PORT_TUNE2 register bits */
+#define HSDISC_TRIM_MASK GENMASK(1, 0)
+#define HSDISC_TRIM_SHIFT 0x0
+
+#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x04
+#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x18c
+#define QUSB2PHY_PLL_CMODE 0x2c
+#define QUSB2PHY_PLL_LOCK_DELAY 0x184
+#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
+#define QUSB2PHY_PLL_BIAS_CONTROL_1 0x194
+#define QUSB2PHY_PLL_BIAS_CONTROL_2 0x198
+#define QUSB2PHY_PWR_CTRL2 0x214
+#define QUSB2PHY_IMP_CTRL1 0x220
+#define QUSB2PHY_IMP_CTRL2 0x224
+#define QUSB2PHY_CHG_CTRL2 0x23c
+
+struct qusb2_phy_init_tbl {
+	unsigned int offset;
+	unsigned int val;
+	/*
+	 * register part of layout ?
+	 * if yes, then offset gives index in the reg-layout
+	 */
+	int in_layout;
+};
+
+struct qusb2_phy_cfg {
+	const struct qusb2_phy_init_tbl *tbl;
+	/* number of entries in the table */
+	unsigned int tbl_num;
+	/* offset to PHY_CLK_SCHEME register in TCSR map */
+	unsigned int clk_scheme_offset;
+
+	/* array of registers with different offsets */
+	const unsigned int *regs;
+	unsigned int mask_core_ready;
+	unsigned int disable_ctrl;
+	unsigned int autoresume_en;
+
+	/* true if PHY has PLL_TEST register to select clk_scheme */
+	bool has_pll_test;
+
+	/* true if TUNE1 register must be updated by fused value, else TUNE2 */
+	bool update_tune1_with_efuse;
+
+	/* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
+	bool has_pll_override;
+};
+
+/* set of registers with offsets different per-PHY */
+enum qusb2phy_reg_layout {
+	QUSB2PHY_PLL_CORE_INPUT_OVERRIDE,
+	QUSB2PHY_PLL_STATUS,
+	QUSB2PHY_PORT_TUNE1,
+	QUSB2PHY_PORT_TUNE2,
+	QUSB2PHY_PORT_TUNE3,
+	QUSB2PHY_PORT_TUNE4,
+	QUSB2PHY_PORT_TUNE5,
+	QUSB2PHY_PORT_TEST1,
+	QUSB2PHY_PORT_TEST2,
+	QUSB2PHY_PORT_POWERDOWN,
+	QUSB2PHY_INTR_CTRL,
+};
+
+#define QUSB2_PHY_INIT_CFG(o, v)       \
+	{                              \
+		.offset = o, .val = v, \
+	}
+
+#define QUSB2_PHY_INIT_CFG_L(o, v)                     \
+	{                                              \
+		.offset = o, .val = v, .in_layout = 1, \
+	}
+
+static const struct qusb2_phy_init_tbl sm6115_init_tbl[] = {
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x81),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x17),
+
+	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 unsigned int sm6115_regs_layout[] = {
+	[QUSB2PHY_PLL_STATUS] = 0x38,	  [QUSB2PHY_PORT_TUNE1] = 0x80,
+	[QUSB2PHY_PORT_TUNE2] = 0x84,	  [QUSB2PHY_PORT_TUNE3] = 0x88,
+	[QUSB2PHY_PORT_TUNE4] = 0x8c,	  [QUSB2PHY_PORT_TUNE5] = 0x90,
+	[QUSB2PHY_PORT_TEST1] = 0xb8,	  [QUSB2PHY_PORT_TEST2] = 0x9c,
+	[QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc,
+};
+
+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),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
+
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
+	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
+
+	QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
+};
+
+static const unsigned int qusb2_v2_regs_layout[] = {
+	[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
+	[QUSB2PHY_PLL_STATUS] = 0x1a0,
+	[QUSB2PHY_PORT_TUNE1] = 0x240,
+	[QUSB2PHY_PORT_TUNE2] = 0x244,
+	[QUSB2PHY_PORT_TUNE3] = 0x248,
+	[QUSB2PHY_PORT_TUNE4] = 0x24c,
+	[QUSB2PHY_PORT_TUNE5] = 0x250,
+	[QUSB2PHY_PORT_TEST1] = 0x254,
+	[QUSB2PHY_PORT_TEST2] = 0x258,
+	[QUSB2PHY_PORT_POWERDOWN] = 0x210,
+	[QUSB2PHY_INTR_CTRL] = 0x230,
+};
+
+static const struct qusb2_phy_cfg sm6115_phy_cfg = {
+	.tbl = sm6115_init_tbl,
+	.tbl_num = ARRAY_SIZE(sm6115_init_tbl),
+	.regs = sm6115_regs_layout,
+
+	.has_pll_test = true,
+	.disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
+	.mask_core_ready = PLL_LOCKED,
+	.autoresume_en = BIT(3),
+};
+
+static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
+	.tbl = qusb2_v2_init_tbl,
+	.tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl),
+	.regs = qusb2_v2_regs_layout,
+
+	.disable_ctrl = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
+			 POWER_DOWN),
+	.mask_core_ready = CORE_READY_STATUS,
+	.has_pll_override = true,
+	.autoresume_en = BIT(0),
+	.update_tune1_with_efuse = true,
+};
+
+/**
+ * struct qusb2_phy - structure holding qusb2 phy attributes
+ *
+ * @phy: generic phy
+ * @base: iomapped memory space for qubs2 phy
+ *
+ * @cfg_ahb_clk: AHB2PHY interface clock
+ * @phy_rst: phy reset control
+ *
+ * @cfg: phy config data
+ * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
+ */
+struct qusb2_phy {
+	struct phy *phy;
+	void __iomem *base;
+
+	struct clk cfg_ahb_clk;
+	struct reset_ctl phy_rst;
+
+	const struct qusb2_phy_cfg *cfg;
+	bool has_se_clk_scheme;
+};
+
+static inline void qusb2_write_mask(void __iomem *base, u32 offset, u32 val,
+				    u32 mask)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	reg &= ~mask;
+	reg |= val & mask;
+	writel(reg, base + offset);
+
+	/* Ensure above write is completed */
+	readl(base + offset);
+}
+
+static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	reg |= val;
+	writel(reg, base + offset);
+
+	/* Ensure above write is completed */
+	readl(base + offset);
+}
+
+static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
+{
+	u32 reg;
+
+	reg = readl(base + offset);
+	reg &= ~val;
+	writel(reg, base + offset);
+
+	/* Ensure above write is completed */
+	readl(base + offset);
+}
+
+static inline void qusb2_phy_configure(void __iomem *base,
+				       const unsigned int *regs,
+				       const struct qusb2_phy_init_tbl tbl[],
+				       int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		if (tbl[i].in_layout)
+			writel(tbl[i].val, base + regs[tbl[i].offset]);
+		else
+			writel(tbl[i].val, base + tbl[i].offset);
+	}
+}
+
+static int qusb2phy_do_reset(struct qusb2_phy *qphy)
+{
+	int ret;
+
+	ret = reset_assert(&qphy->phy_rst);
+	if (ret)
+		return ret;
+
+	udelay(10);
+
+	ret = reset_deassert(&qphy->phy_rst);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int qusb2phy_power_on(struct phy *phy)
+{
+	struct qusb2_phy *qphy = dev_get_priv(phy->dev);
+	const struct qusb2_phy_cfg *cfg = qphy->cfg;
+	int ret;
+	u32 val;
+
+	ret = qusb2phy_do_reset(qphy);
+	if (ret)
+		return ret;
+
+	/* Disable the PHY */
+	qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+		      qphy->cfg->disable_ctrl);
+
+	if (cfg->has_pll_test) {
+		/* save reset value to override reference clock scheme later */
+		val = readl(qphy->base + QUSB2PHY_PLL_TEST);
+	}
+
+	qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl, cfg->tbl_num);
+
+	/* Enable the PHY */
+	qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+		      POWER_DOWN);
+
+	/* Required to get phy pll lock successfully */
+	udelay(150);
+
+	if (cfg->has_pll_test) {
+		val |= CLK_REF_SEL;
+
+		writel(val, qphy->base + QUSB2PHY_PLL_TEST);
+
+		/* ensure above write is through */
+		readl(qphy->base + QUSB2PHY_PLL_TEST);
+	}
+
+	/* Required to get phy pll lock successfully */
+	udelay(100);
+
+	val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
+	if (!(val & cfg->mask_core_ready)) {
+		pr_err("QUSB2PHY pll lock failed: status reg = %x\n", val);
+		ret = -EBUSY;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int qusb2phy_power_off(struct phy *phy)
+{
+	struct qusb2_phy *qphy = dev_get_priv(phy->dev);
+
+	/* Disable the PHY */
+	qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
+		      qphy->cfg->disable_ctrl);
+
+	reset_assert(&qphy->phy_rst);
+
+	clk_disable(&qphy->cfg_ahb_clk);
+
+	return 0;
+}
+
+static int qusb2phy_clk_init(struct udevice *dev, struct qusb2_phy *qphy)
+{
+	int ret;
+
+	/* We ignore the ref clock as we currently lack a driver for rpmcc/rpmhcc where
+	 * it usually comes from - we assume it's always on.
+	 */
+	ret = clk_get_by_name(dev, "cfg_ahb", &qphy->cfg_ahb_clk);
+	if (ret == -ENOSYS || ret == -ENOENT)
+		return 0;
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&qphy->cfg_ahb_clk);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static int qusb2phy_probe(struct udevice *dev)
+{
+	struct qusb2_phy *qphy = dev_get_priv(dev);
+	int ret;
+
+	qphy->base = (void __iomem *)dev_read_addr(dev);
+	if (IS_ERR(qphy->base))
+		return PTR_ERR(qphy->base);
+
+	ret = qusb2phy_clk_init(dev, qphy);
+	if (ret) {
+		printf("%s: Couldn't get clocks: %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = reset_get_by_index(dev, 0, &qphy->phy_rst);
+	if (ret) {
+		printf("%s: Couldn't get resets: %d\n", __func__, ret);
+		return ret;
+	}
+
+	qphy->cfg = (const struct qusb2_phy_cfg *)dev_get_driver_data(dev);
+	if (!qphy->cfg) {
+		printf("%s: Couldn't get driver data\n", __func__);
+		return -EINVAL;
+	}
+
+	debug("%s success qusb phy cfg %p\n", __func__, qphy->cfg);
+	return 0;
+}
+
+static struct phy_ops qusb2phy_ops = {
+	.power_on = qusb2phy_power_on,
+	.power_off = qusb2phy_power_off,
+};
+
+static const struct udevice_id qusb2phy_ids[] = {
+	{ .compatible = "qcom,qusb2-phy" },
+	{ .compatible = "qcom,qcm2290-qusb2-phy",
+	  .data = (ulong)&sm6115_phy_cfg },
+	{ .compatible = "qcom,sm6115-qusb2-phy",
+	  .data = (ulong)&sm6115_phy_cfg },
+	{ .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
+	{}
+};
+
+U_BOOT_DRIVER(qcom_qusb2_phy) = {
+	.name = "qcom-qusb2-phy",
+	.id = UCLASS_PHY,
+	.of_match = qusb2phy_ids,
+	.ops = &qusb2phy_ops,
+	.probe = qusb2phy_probe,
+	.priv_auto = sizeof(struct qusb2_phy),
+};

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 03/14] phy: qcom: Add USB HS 7nm PHY driver
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 01/14] mailmap: update Bhupesh's email address Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:37   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers Caleb Connolly
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot, Bhupesh Sharma, Bhupesh Sharma

From: Bhupesh Sharma <bhupesh.linux@gmail.com>

Some Qualcomm SoCs newer than SDM845 feature a so-called "7nm phy"
driver, notable the SM8250 SoC which will gain U-Boot support in
upcoming patches.

Introduce a driver based on the Linux driver.

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
[code cleanup, switch to clk/reset_bulk APIs]
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/phy/qcom/Kconfig               |   8 +
 drivers/phy/qcom/Makefile              |   1 +
 drivers/phy/qcom/phy-qcom-usb-hs-7nm.c | 295 +++++++++++++++++++++++++++++++++
 3 files changed, 304 insertions(+)

diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
index 361dfb6e1126..3fc59dc65650 100644
--- a/drivers/phy/qcom/Kconfig
+++ b/drivers/phy/qcom/Kconfig
@@ -18,8 +18,16 @@ config PHY_QCOM_QUSB2
 	help
 	  Enable this to support the Super-Speed USB transceiver on various
 	  Qualcomm chipsets.
 
+config PHY_QCOM_USB_HS_7NM
+	tristate "Qualcomm 7nm High-Speed PHY"
+	depends on PHY && ARCH_SNAPDRAGON
+	help
+	  Enable this to support the Qualcomm Synopsys DesignWare Core 7nm
+	  High-Speed PHY driver. This driver supports the Hi-Speed PHY which
+	  is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
+
 config PHY_QCOM_USB_HS_28NM
 	tristate "Qualcomm 28nm High-Speed PHY"
 	depends on PHY && ARCH_SNAPDRAGON
 	help
diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
index f6af985666a4..39219ecd24aa 100644
--- a/drivers/phy/qcom/Makefile
+++ b/drivers/phy/qcom/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
 obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
 obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
+obj-$(CONFIG_PHY_QCOM_USB_HS_7NM) += phy-qcom-usb-hs-7nm.o
 obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
 obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
diff --git a/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c b/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c
new file mode 100644
index 000000000000..65128b45937b
--- /dev/null
+++ b/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Bhupesh Sharma <bhupesh.sharma@linaro.org>
+ *
+ * Based on Linux driver
+ */
+
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <generic-phy.h>
+#include <malloc.h>
+#include <reset.h>
+
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+
+#define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c)
+#define SLEEPM BIT(0)
+#define OPMODE_MASK GENMASK(4, 3)
+#define OPMODE_NORMAL (0x00)
+#define OPMODE_NONDRIVING BIT(3)
+#define TERMSEL BIT(5)
+
+#define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40)
+#define XCVRSEL BIT(0)
+
+#define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50)
+#define POR BIT(1)
+
+#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
+#define SIDDQ BIT(2)
+#define RETENABLEN BIT(3)
+#define FSEL_MASK GENMASK(6, 4)
+#define FSEL_DEFAULT (0x3 << 4)
+
+#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58)
+#define VBUSVLDEXTSEL0 BIT(4)
+#define PLLBTUNE BIT(5)
+
+#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2 (0x5c)
+#define VREGBYPASS BIT(0)
+
+#define USB2_PHY_USB_PHY_HS_PHY_CTRL1 (0x60)
+#define VBUSVLDEXT0 BIT(0)
+
+#define USB2_PHY_USB_PHY_HS_PHY_CTRL2 (0x64)
+#define USB2_AUTO_RESUME BIT(0)
+#define USB2_SUSPEND_N BIT(2)
+#define USB2_SUSPEND_N_SEL BIT(3)
+
+#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X0 (0x6c)
+#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1 (0x70)
+#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2 (0x74)
+#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X3 (0x78)
+#define PARAM_OVRD_MASK 0xFF
+
+#define USB2_PHY_USB_PHY_CFG0 (0x94)
+#define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0)
+#define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1)
+
+#define USB2_PHY_USB_PHY_REFCLK_CTRL (0xa0)
+#define REFCLK_SEL_MASK GENMASK(1, 0)
+#define REFCLK_SEL_DEFAULT (0x2 << 0)
+
+#define HS_DISCONNECT_MASK GENMASK(2, 0)
+#define SQUELCH_DETECTOR_MASK GENMASK(7, 5)
+
+#define HS_AMPLITUDE_MASK GENMASK(3, 0)
+#define PREEMPHASIS_DURATION_MASK BIT(5)
+#define PREEMPHASIS_AMPLITUDE_MASK GENMASK(7, 6)
+
+#define HS_RISE_FALL_MASK GENMASK(1, 0)
+#define HS_CROSSOVER_VOLTAGE_MASK GENMASK(3, 2)
+#define HS_OUTPUT_IMPEDANCE_MASK GENMASK(5, 4)
+
+#define LS_FS_OUTPUT_IMPEDANCE_MASK GENMASK(3, 0)
+
+#define SNPS_HS_NUM_VREGS ARRAY_SIZE(hs_7nm_vreg_names)
+
+struct override_param {
+	s32 value;
+	u8 reg_val;
+};
+
+struct override_param_map {
+	const char *prop_name;
+	const struct override_param *param_table;
+	u8 table_size;
+	u8 reg_offset;
+	u8 param_mask;
+};
+
+struct phy_override_seq {
+	bool need_update;
+	u8 offset;
+	u8 value;
+	u8 mask;
+};
+
+#define NUM_HSPHY_TUNING_PARAMS (9)
+
+/* struct hs_7nm_phy_cfg - per-PHY initialization config */
+struct hs_7nm_phy_cfg {
+	/* resets to be requested */
+	struct reset_ctl *resets;
+	int num_resets;
+
+	struct override_param_map *map_cfg;
+	struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS];
+};
+
+/**
+ * struct hs_7nm_phy_priv - snps hs phy attributes
+ */
+struct hs_7nm_phy_priv {
+	void __iomem *base;
+
+	/* clocks to be requested */
+	struct clk_bulk clks;
+
+	/* resets to be requested */
+	struct reset_ctl_bulk resets;
+
+	struct hs_7nm_phy_cfg *cfg;
+};
+
+static inline void hs_7nm_write_mask(void __iomem *base, u32 offset, u32 mask,
+				     u32 val)
+{
+	u32 reg;
+
+	reg = readl_relaxed(base + offset);
+
+	reg &= ~mask;
+	reg |= val & mask;
+	writel_relaxed(reg, base + offset);
+
+	/* Ensure above write is completed */
+	readl_relaxed(base + offset);
+}
+
+static int hs_7nm_usb_init(struct phy *phy)
+{
+	struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_CFG0,
+			  UTMI_PHY_CMN_CTRL_OVERRIDE_EN,
+			  UTMI_PHY_CMN_CTRL_OVERRIDE_EN);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
+			  FSEL_MASK, 0);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
+			  PLLBTUNE, PLLBTUNE);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_REFCLK_CTRL,
+			  REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
+			  VBUSVLDEXTSEL0, VBUSVLDEXTSEL0);
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1,
+			  VBUSVLDEXT0, VBUSVLDEXT0);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
+			  VREGBYPASS, VREGBYPASS);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
+			  USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
+			  USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL0, SLEEPM,
+			  SLEEPM);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
+			  SIDDQ, 0);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL5, POR, 0);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
+			  USB2_SUSPEND_N_SEL, 0);
+
+	hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_CFG0,
+			  UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0);
+
+	return 0;
+}
+
+static int hs_7nm_phy_power_on(struct phy *phy)
+{
+	struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
+	int ret;
+
+	clk_enable_bulk(&hs_7nm->clks);
+
+	ret = reset_deassert_bulk(&hs_7nm->resets);
+	if (ret)
+		return ret;
+
+	ret = hs_7nm_usb_init(phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hs_7nm_phy_power_off(struct phy *phy)
+{
+	struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
+
+	reset_assert_bulk(&hs_7nm->resets);
+	clk_disable_bulk(&hs_7nm->clks);
+
+	return 0;
+}
+
+static int hs_7nm_phy_clk_init(struct udevice *dev,
+			       struct hs_7nm_phy_priv *hs_7nm)
+{
+	int ret;
+
+	ret = clk_get_bulk(dev, &hs_7nm->clks);
+	/* We may have no clocks */
+	if (ret == -ENOENT) {
+		debug("%s: no clocks\n", __func__);
+		return 0;
+	}
+	if (ret < 0) {
+		printf("%s: Failed to get clocks %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int hs_7nm_phy_probe(struct udevice *dev)
+{
+	struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(dev);
+	int ret;
+
+	hs_7nm->base = (void __iomem *)dev_read_addr(dev);
+	if (IS_ERR(hs_7nm->base))
+		return PTR_ERR(hs_7nm->base);
+
+	hs_7nm->cfg = (struct hs_7nm_phy_cfg *)dev_get_driver_data(dev);
+
+	ret = hs_7nm_phy_clk_init(dev, hs_7nm);
+	if (ret) {
+		printf("%s: hs_7nm_phy_clk_init %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = reset_get_bulk(dev, &hs_7nm->resets);
+	if (ret < 0) {
+		printf("failed to get resets, ret = %d\n", ret);
+		return ret;
+	}
+
+	clk_enable_bulk(&hs_7nm->clks);
+	reset_deassert_bulk(&hs_7nm->resets);
+
+	return 0;
+}
+
+static struct phy_ops hs_7nm_phy_ops = {
+	.power_on = hs_7nm_phy_power_on,
+	.power_off = hs_7nm_phy_power_off,
+};
+
+static const struct udevice_id hs_7nm_phy_ids[] = {
+	{
+		.compatible = "qcom,sm8150-usb-hs-phy",
+	},
+	{
+		.compatible = "qcom,usb-snps-hs-5nm-phy",
+	},
+	{
+		.compatible = "qcom,usb-snps-hs-7nm-phy",
+	},
+	{
+		.compatible = "qcom,usb-snps-femto-v2-phy",
+	},
+	{}
+};
+
+U_BOOT_DRIVER(qcom_usb_hs_7nm) = {
+	.name = "qcom-usb-hs-7nm",
+	.id = UCLASS_PHY,
+	.of_match = hs_7nm_phy_ids,
+	.ops = &hs_7nm_phy_ops,
+	.probe = hs_7nm_phy_probe,
+	.priv_auto = sizeof(struct hs_7nm_phy_priv),
+};

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (2 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 03/14] phy: qcom: Add USB HS 7nm " Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:21   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 05/14] clk/qcom: use offsets for RCG registers Caleb Connolly
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

Some devices like the UART and clock controller reference an RPM(h)
power domain. We don't support this device in U-Boot, so add
DM_FLAG_DEFAULT_PD_CTRL_OFF to tell DM core not to try and enable the
power domain.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/clk/qcom/clock-qcom.c    | 2 ++
 drivers/clk/qcom/clock-sdm845.c  | 2 +-
 drivers/serial/serial_msm_geni.c | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 7a5938a06a34..6303dcbf8461 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -226,8 +226,9 @@ U_BOOT_DRIVER(qcom_clk) = {
 	.id		= UCLASS_CLK,
 	.ops		= &msm_clk_ops,
 	.priv_auto	= sizeof(struct msm_clk_priv),
 	.probe		= msm_clk_probe,
+	.flags		= DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
 
 int qcom_cc_bind(struct udevice *parent)
 {
@@ -410,5 +411,6 @@ U_BOOT_DRIVER(qcom_power) = {
 	.name = "qcom_power",
 	.id = UCLASS_POWER_DOMAIN,
 	.ops = &qcom_power_ops,
 	.probe = qcom_power_probe,
+	.flags = DM_FLAG_PRE_RELOC,
 };
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index 36ffee79d966..babd83119e2c 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -182,6 +182,6 @@ U_BOOT_DRIVER(gcc_sdm845) = {
 	.name		= "gcc_sdm845",
 	.id		= UCLASS_NOP,
 	.of_match	= gcc_sdm845_of_match,
 	.bind		= qcom_cc_bind,
-	.flags		= DM_FLAG_PRE_RELOC,
+	.flags		= DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
index e5c3dcffc1c6..4aa0bc8c72bc 100644
--- a/drivers/serial/serial_msm_geni.c
+++ b/drivers/serial/serial_msm_geni.c
@@ -602,9 +602,9 @@ U_BOOT_DRIVER(serial_msm_geni) = {
 	.of_to_plat = msm_serial_ofdata_to_platdata,
 	.priv_auto = sizeof(struct msm_serial_data),
 	.probe = msm_serial_probe,
 	.ops = &msm_serial_ops,
-	.flags = DM_FLAG_PRE_RELOC,
+	.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
 
 #ifdef CONFIG_DEBUG_UART_MSM_GENI
 

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 05/14] clk/qcom: use offsets for RCG registers
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (3 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:42   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 06/14] clk/qcom: sdm845: add gdscs Caleb Connolly
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

The RCG registers always have the same offsets, so only store the base
CMD register address and calculate the others relative to that.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/clk/qcom/clock-apq8016.c |  39 +------------
 drivers/clk/qcom/clock-apq8096.c |  28 +--------
 drivers/clk/qcom/clock-qcom.c    |  22 +++----
 drivers/clk/qcom/clock-qcom.h    |  16 +++---
 drivers/clk/qcom/clock-qcs404.c  | 121 +++++----------------------------------
 drivers/clk/qcom/clock-sdm845.c  |  16 +-----
 6 files changed, 39 insertions(+), 203 deletions(-)

diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
index e6647f7c41dd..5a5868169c89 100644
--- a/drivers/clk/qcom/clock-apq8016.c
+++ b/drivers/clk/qcom/clock-apq8016.c
@@ -22,13 +22,9 @@
 #define APCS_GPLL_ENA_VOTE		(0x45000)
 #define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
 
 #define SDCC_BCR(n)			((n * 0x1000) + 0x41000)
-#define SDCC_CMD_RCGR(n)		((n * 0x1000) + 0x41004)
-#define SDCC_CFG_RCGR(n)		((n * 0x1000) + 0x41008)
-#define SDCC_M(n)			((n * 0x1000) + 0x4100C)
-#define SDCC_N(n)			((n * 0x1000) + 0x41010)
-#define SDCC_D(n)			((n * 0x1000) + 0x41014)
+#define SDCC_CMD_RCGR(n)		(((n + 1) * 0x1000) + 0x41004)
 #define SDCC_APPS_CBCR(n)		((n * 0x1000) + 0x41018)
 #define SDCC_AHB_CBCR(n)		((n * 0x1000) + 0x4101C)
 
 /* BLSP1 AHB clock (root clock for BLSP) */
@@ -37,33 +33,12 @@
 /* Uart clock control registers */
 #define BLSP1_UART2_BCR			(0x3028)
 #define BLSP1_UART2_APPS_CBCR		(0x302C)
 #define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
-#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
-#define BLSP1_UART2_APPS_M		(0x303C)
-#define BLSP1_UART2_APPS_N		(0x3040)
-#define BLSP1_UART2_APPS_D		(0x3044)
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE BIT(17)
 
-static const struct bcr_regs sdc_regs[] = {
-	{
-	.cfg_rcgr = SDCC_CFG_RCGR(1),
-	.cmd_rcgr = SDCC_CMD_RCGR(1),
-	.M = SDCC_M(1),
-	.N = SDCC_N(1),
-	.D = SDCC_D(1),
-	},
-	{
-	.cfg_rcgr = SDCC_CFG_RCGR(2),
-	.cmd_rcgr = SDCC_CMD_RCGR(2),
-	.M = SDCC_M(2),
-	.N = SDCC_N(2),
-	.D = SDCC_D(2),
-	}
-};
-
 static struct pll_vote_clk gpll0_vote_clk = {
 	.status = GPLL0_STATUS,
 	.status_bit = GPLL0_STATUS_ACTIVE,
 	.ena_vote = APCS_GPLL_ENA_VOTE,
@@ -85,32 +60,24 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
 		div = 4;
 
 	clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
 	/* 800Mhz/div, gpll0 */
-	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
+	clk_rcg_set_rate_mnd(priv->base, SDCC_CMD_RCGR(slot), div, 0, 0,
 			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
 
 	return rate;
 }
 
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
-	.cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
-	.M = BLSP1_UART2_APPS_M,
-	.N = BLSP1_UART2_APPS_N,
-	.D = BLSP1_UART2_APPS_D,
-};
-
 /* UART: 115200 */
 int apq8016_clk_init_uart(phys_addr_t base)
 {
 	/* Enable AHB clock */
 	clk_enable_vote_clk(base, &gcc_blsp1_ahb_clk);
 
 	/* 7372800 uart block clock @ GPLL0 */
-	clk_rcg_set_rate_mnd(base, &uart2_regs, 1, 144, 15625,
+	clk_rcg_set_rate_mnd(base, BLSP1_UART2_APPS_CMD_RCGR, 1, 144, 15625,
 			     CFG_CLK_SRC_GPLL0, 16);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
index a4731613c5e0..479f9771a464 100644
--- a/drivers/clk/qcom/clock-apq8096.c
+++ b/drivers/clk/qcom/clock-apq8096.c
@@ -25,33 +25,17 @@
 #define SDCC2_BCR			(0x14000) /* block reset */
 #define SDCC2_APPS_CBCR			(0x14004) /* branch control */
 #define SDCC2_AHB_CBCR			(0x14008)
 #define SDCC2_CMD_RCGR			(0x14010)
-#define SDCC2_CFG_RCGR			(0x14014)
-#define SDCC2_M				(0x14018)
-#define SDCC2_N				(0x1401C)
-#define SDCC2_D				(0x14020)
 
 #define BLSP2_AHB_CBCR			(0x25004)
 #define BLSP2_UART2_APPS_CBCR		(0x29004)
 #define BLSP2_UART2_APPS_CMD_RCGR	(0x2900C)
-#define BLSP2_UART2_APPS_CFG_RCGR	(0x29010)
-#define BLSP2_UART2_APPS_M		(0x29014)
-#define BLSP2_UART2_APPS_N		(0x29018)
-#define BLSP2_UART2_APPS_D		(0x2901C)
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE		BIT(30)
 #define APCS_GPLL_ENA_VOTE_GPLL0	BIT(0)
 
-static const struct bcr_regs sdc_regs = {
-	.cfg_rcgr = SDCC2_CFG_RCGR,
-	.cmd_rcgr = SDCC2_CMD_RCGR,
-	.M = SDCC2_M,
-	.N = SDCC2_N,
-	.D = SDCC2_D,
-};
-
 static const struct pll_vote_clk gpll0_vote_clk = {
 	.status = GPLL0_STATUS,
 	.status_bit = GPLL0_STATUS_ACTIVE,
 	.ena_vote = APCS_GPLL_ENA_VOTE,
@@ -68,31 +52,23 @@ static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
 {
 	int div = 5;
 
 	clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
-	clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
+	clk_rcg_set_rate_mnd(priv->base, SDCC2_CMD_RCGR, div, 0, 0,
 			     CFG_CLK_SRC_GPLL0, 8);
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 	clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
 
 	return rate;
 }
 
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = BLSP2_UART2_APPS_CFG_RCGR,
-	.cmd_rcgr = BLSP2_UART2_APPS_CMD_RCGR,
-	.M = BLSP2_UART2_APPS_M,
-	.N = BLSP2_UART2_APPS_N,
-	.D = BLSP2_UART2_APPS_D,
-};
-
 static int clk_init_uart(struct msm_clk_priv *priv)
 {
 	/* Enable AHB clock */
 	clk_enable_vote_clk(priv->base, &gcc_blsp2_ahb_clk);
 
 	/* 7372800 uart block clock @ GPLL0 */
-	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
+	clk_rcg_set_rate_mnd(priv->base, BLSP2_UART2_APPS_CMD_RCGR, 1, 192, 15625,
 			     CFG_CLK_SRC_GPLL0, 16);
 
 	/* Vote for gpll0 clock */
 	clk_enable_gpll0(priv->base, &gpll0_vote_clk);
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index 6303dcbf8461..05e5ab7d094b 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -103,9 +103,9 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
 /*
  * root set rate for clocks with half integer and MND divider
  * div should be pre-calculated ((div * 2) - 1)
  */
-void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+void clk_rcg_set_rate_mnd(phys_addr_t base, uint32_t cmd_rcgr,
 			  int div, int m, int n, int source, u8 mnd_width)
 {
 	u32 cfg;
 	/* M value for MND divider. */
@@ -119,14 +119,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
 
 	debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
 
 	/* Program MND values */
-	writel(m_val & mask, base + regs->M);
-	writel(n_val & mask, base + regs->N);
-	writel(d_val & mask, base + regs->D);
+	writel(m_val & mask, base + cmd_rcgr + RCG_M_REG);
+	writel(n_val & mask, base + cmd_rcgr + RCG_N_REG);
+	writel(d_val & mask, base + cmd_rcgr + RCG_D_REG);
 
 	/* setup src select and divider */
-	cfg  = readl(base + regs->cfg_rcgr);
+	cfg  = readl(base + cmd_rcgr + RCG_CFG_REG);
 	cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK |
 		 CFG_SRC_DIV_MASK);
 	cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
 
@@ -135,22 +135,22 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
 
 	if (n && n != m)
 		cfg |= CFG_MODE_DUAL_EDGE;
 
-	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
+	writel(cfg, base + cmd_rcgr + RCG_CFG_REG); /* Write new clock configuration */
 
 	/* Inform h/w to start using the new config. */
-	clk_bcr_update(base + regs->cmd_rcgr);
+	clk_bcr_update(base + cmd_rcgr);
 }
 
 /* root set rate for clocks with half integer and mnd_width=0 */
-void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
+void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
 		      int source)
 {
 	u32 cfg;
 
 	/* setup src select and divider */
-	cfg  = readl(base + regs->cfg_rcgr);
+	cfg  = readl(base + cmd_rcgr + RCG_CFG_REG);
 	cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
 	cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
 
 	/*
@@ -159,12 +159,12 @@ void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
 	 */
 	if (div)
 		cfg |= (2 * div - 1) & CFG_SRC_DIV_MASK;
 
-	writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
+	writel(cfg, base + cmd_rcgr + RCG_CFG_REG); /* Write new clock configuration */
 
 	/* Inform h/w to start using the new config. */
-	clk_bcr_update(base + regs->cmd_rcgr);
+	clk_bcr_update(base + cmd_rcgr);
 }
 
 const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
 {
diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
index 12a1eaec2b2e..a7f833a4b6dd 100644
--- a/drivers/clk/qcom/clock-qcom.h
+++ b/drivers/clk/qcom/clock-qcom.h
@@ -11,8 +11,13 @@
 #define CFG_CLK_SRC_GPLL0 (1 << 8)
 #define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
 #define CFG_CLK_SRC_MASK  (7 << 8)
 
+#define RCG_CFG_REG		0x4
+#define RCG_M_REG		0x8
+#define RCG_N_REG		0xc
+#define RCG_D_REG		0x10
+
 struct pll_vote_clk {
 	uintptr_t status;
 	int status_bit;
 	uintptr_t ena_vote;
@@ -23,15 +28,8 @@ struct vote_clk {
 	uintptr_t cbcr_reg;
 	uintptr_t ena_vote;
 	int vote_bit;
 };
-struct bcr_regs {
-	uintptr_t cfg_rcgr;
-	uintptr_t cmd_rcgr;
-	uintptr_t M;
-	uintptr_t N;
-	uintptr_t D;
-};
 
 struct freq_tbl {
 	uint freq;
 	uint src;
@@ -87,11 +85,11 @@ void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
 void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
 void clk_enable_cbc(phys_addr_t cbcr);
 void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
 const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate);
-void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
+void clk_rcg_set_rate_mnd(phys_addr_t base, uint32_t cmd_rcgr,
 			  int div, int m, int n, int source, u8 mnd_width);
-void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
+void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
 		      int source);
 
 static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
 {
diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
index 958312b88842..64a0a2d36754 100644
--- a/drivers/clk/qcom/clock-qcs404.c
+++ b/drivers/clk/qcom/clock-qcs404.c
@@ -27,37 +27,24 @@
 /* Uart clock control registers */
 #define BLSP1_UART2_BCR			(0x3028)
 #define BLSP1_UART2_APPS_CBCR		(0x302C)
 #define BLSP1_UART2_APPS_CMD_RCGR	(0x3034)
-#define BLSP1_UART2_APPS_CFG_RCGR	(0x3038)
-#define BLSP1_UART2_APPS_M		(0x303C)
-#define BLSP1_UART2_APPS_N		(0x3040)
-#define BLSP1_UART2_APPS_D		(0x3044)
 
 /* I2C controller clock control registerss */
 #define BLSP1_QUP0_I2C_APPS_CBCR	(0x6028)
 #define BLSP1_QUP0_I2C_APPS_CMD_RCGR	(0x602C)
-#define BLSP1_QUP0_I2C_APPS_CFG_RCGR	(0x6030)
 #define BLSP1_QUP1_I2C_APPS_CBCR	(0x2008)
 #define BLSP1_QUP1_I2C_APPS_CMD_RCGR	(0x200C)
-#define BLSP1_QUP1_I2C_APPS_CFG_RCGR	(0x2010)
 #define BLSP1_QUP2_I2C_APPS_CBCR	(0x3010)
 #define BLSP1_QUP2_I2C_APPS_CMD_RCGR	(0x3000)
-#define BLSP1_QUP2_I2C_APPS_CFG_RCGR	(0x3004)
 #define BLSP1_QUP3_I2C_APPS_CBCR	(0x4020)
 #define BLSP1_QUP3_I2C_APPS_CMD_RCGR	(0x4000)
-#define BLSP1_QUP3_I2C_APPS_CFG_RCGR	(0x4004)
 #define BLSP1_QUP4_I2C_APPS_CBCR	(0x5020)
 #define BLSP1_QUP4_I2C_APPS_CMD_RCGR	(0x5000)
-#define BLSP1_QUP4_I2C_APPS_CFG_RCGR	(0x5004)
 
 /* SD controller clock control registers */
 #define SDCC_BCR(n)			(((n) * 0x1000) + 0x41000)
-#define SDCC_CMD_RCGR(n)		(((n) * 0x1000) + 0x41004)
-#define SDCC_CFG_RCGR(n)		(((n) * 0x1000) + 0x41008)
-#define SDCC_M(n)			(((n) * 0x1000) + 0x4100C)
-#define SDCC_N(n)			(((n) * 0x1000) + 0x41010)
-#define SDCC_D(n)			(((n) * 0x1000) + 0x41014)
+#define SDCC_CMD_RCGR(n)		(((n + 1) * 0x1000) + 0x41004)
 #define SDCC_APPS_CBCR(n)		(((n) * 0x1000) + 0x41018)
 #define SDCC_AHB_CBCR(n)		(((n) * 0x1000) + 0x4101C)
 
 /* USB-3.0 controller clock control registers */
@@ -69,12 +56,8 @@
 #define USB30_MOCK_UTMI_CBCR		(0x39014)
 #define USB30_MOCK_UTMI_CMD_RCGR	(0x3901C)
 #define USB30_MOCK_UTMI_CFG_RCGR	(0x39020)
 #define USB30_MASTER_CMD_RCGR		(0x39028)
-#define USB30_MASTER_CFG_RCGR		(0x3902C)
-#define USB30_MASTER_M			(0x39030)
-#define USB30_MASTER_N			(0x39034)
-#define USB30_MASTER_D			(0x39038)
 #define USB2A_PHY_SLEEP_CBCR		(0x4102C)
 #define USB_HS_PHY_CFG_AHB_CBCR		(0x41030)
 
 /* ETH controller clock control registers */
@@ -84,12 +67,8 @@
 #define ETH_AXI_CBCR			(0x4e010)
 #define EMAC_PTP_CMD_RCGR		(0x4e014)
 #define EMAC_PTP_CFG_RCGR		(0x4e018)
 #define EMAC_CMD_RCGR			(0x4e01c)
-#define EMAC_CFG_RCGR			(0x4e020)
-#define EMAC_M				(0x4e024)
-#define EMAC_N				(0x4e028)
-#define EMAC_D				(0x4e02c)
 
 
 /* GPLL0 clock control registers */
 #define GPLL0_STATUS_ACTIVE BIT(31)
@@ -102,24 +81,8 @@ static struct vote_clk gcc_blsp1_ahb_clk = {
 	.ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
 	.vote_bit = BIT(10) | BIT(5) | BIT(4),
 };
 
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
-	.cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
-	.M = BLSP1_UART2_APPS_M,
-	.N = BLSP1_UART2_APPS_N,
-	.D = BLSP1_UART2_APPS_D,
-};
-
-static const struct bcr_regs sdc_regs = {
-	.cfg_rcgr = SDCC_CFG_RCGR(1),
-	.cmd_rcgr = SDCC_CMD_RCGR(1),
-	.M = SDCC_M(1),
-	.N = SDCC_N(1),
-	.D = SDCC_D(1),
-};
-
 static struct pll_vote_clk gpll0_vote_clk = {
 	.status = GPLL0_STATUS,
 	.status_bit = GPLL0_STATUS_ACTIVE,
 	.ena_vote = APCS_GPLL_ENA_VOTE,
@@ -132,92 +95,38 @@ static struct pll_vote_clk gpll1_vote_clk = {
 	.ena_vote = APCS_GPLL_ENA_VOTE,
 	.vote_bit = BIT(1),
 };
 
-static const struct bcr_regs usb30_master_regs = {
-	.cfg_rcgr = USB30_MASTER_CFG_RCGR,
-	.cmd_rcgr = USB30_MASTER_CMD_RCGR,
-	.M = USB30_MASTER_M,
-	.N = USB30_MASTER_N,
-	.D = USB30_MASTER_D,
-};
-
-static const struct bcr_regs emac_regs = {
-	.cfg_rcgr = EMAC_CFG_RCGR,
-	.cmd_rcgr = EMAC_CMD_RCGR,
-	.M = EMAC_M,
-	.N = EMAC_N,
-	.D = EMAC_D,
-};
-
-static const struct bcr_regs emac_ptp_regs = {
-	.cfg_rcgr = EMAC_PTP_CFG_RCGR,
-	.cmd_rcgr = EMAC_PTP_CMD_RCGR,
-	.M = EMAC_M,
-	.N = EMAC_N,
-	.D = EMAC_D,
-};
-
-static const struct bcr_regs blsp1_qup0_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP0_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP0_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup1_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP1_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup2_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP2_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup3_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP3_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
-static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
-	.cmd_rcgr = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
-	.cfg_rcgr = BLSP1_QUP4_I2C_APPS_CFG_RCGR,
-	/* mnd_width = 0 */
-};
-
 static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
 {
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
 
 	switch (clk->id) {
 	case GCC_BLSP1_UART2_APPS_CLK:
 		/* UART: 1843200Hz for a fixed 115200 baudrate (19200000 * (12/125)) */
-		clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
+		clk_rcg_set_rate_mnd(priv->base, BLSP1_UART2_APPS_CMD_RCGR, 0, 12, 125,
 				     CFG_CLK_SRC_CXO, 16);
 		clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
 		return 1843200;
 	case GCC_SDCC1_APPS_CLK:
 		/* SDCC1: 200MHz */
-		clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 7, 0, 0,
+		clk_rcg_set_rate_mnd(priv->base, SDCC_CMD_RCGR(0), 7, 0, 0,
 				     CFG_CLK_SRC_GPLL0, 8);
 		clk_enable_gpll0(priv->base, &gpll0_vote_clk);
 		clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
 		return rate;
 	case GCC_ETH_RGMII_CLK:
 		if (rate == 250000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
+			clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 0, 0,
 					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 125000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 7, 0, 0,
+			clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 7, 0, 0,
 					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 50000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 19, 0, 0,
+			clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 19, 0, 0,
 					     CFG_CLK_SRC_GPLL1, 8);
 		else if (rate == 5000000)
-			clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 1, 50,
+			clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 1, 50,
 					     CFG_CLK_SRC_GPLL1, 8);
 		return rate;
 	}
 
@@ -236,9 +145,9 @@ static int qcs404_clk_enable(struct clk *clk)
 
 	switch (clk->id) {
 	case GCC_USB30_MASTER_CLK:
 		clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
-		clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 7, 0, 0,
+		clk_rcg_set_rate_mnd(priv->base, USB30_MASTER_CMD_RCGR, 7, 0, 0,
 				     CFG_CLK_SRC_GPLL0, 8);
 		break;
 	case GCC_SYS_NOC_USB3_CLK:
 		clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
@@ -258,16 +167,16 @@ static int qcs404_clk_enable(struct clk *clk)
 	case GCC_ETH_PTP_CLK:
 		/* SPEED_1000: freq -> 250MHz */
 		clk_enable_cbc(priv->base + ETH_PTP_CBCR);
 		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
-		clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 3, 0, 0,
+		clk_rcg_set_rate_mnd(priv->base, EMAC_PTP_CMD_RCGR, 3, 0, 0,
 				     CFG_CLK_SRC_GPLL1, 8);
 		break;
 	case GCC_ETH_RGMII_CLK:
 		/* SPEED_1000: freq -> 250MHz */
 		clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
 		clk_enable_gpll0(priv->base, &gpll1_vote_clk);
-		clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
+		clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 0, 0,
 				     CFG_CLK_SRC_GPLL1, 8);
 		break;
 	case GCC_ETH_SLAVE_AHB_CLK:
 		clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
@@ -279,29 +188,29 @@ static int qcs404_clk_enable(struct clk *clk)
 		clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
 		break;
 	case GCC_BLSP1_QUP0_I2C_APPS_CLK:
 		clk_enable_cbc(priv->base + BLSP1_QUP0_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup0_i2c_apps_regs, 0,
+		clk_rcg_set_rate(priv->base, BLSP1_QUP0_I2C_APPS_CMD_RCGR, 0,
 				 CFG_CLK_SRC_CXO);
 		break;
 	case GCC_BLSP1_QUP1_I2C_APPS_CLK:
 		clk_enable_cbc(priv->base + BLSP1_QUP1_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup1_i2c_apps_regs, 0,
+		clk_rcg_set_rate(priv->base, BLSP1_QUP1_I2C_APPS_CMD_RCGR, 0,
 				 CFG_CLK_SRC_CXO);
 		break;
 	case GCC_BLSP1_QUP2_I2C_APPS_CLK:
 		clk_enable_cbc(priv->base + BLSP1_QUP2_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup2_i2c_apps_regs, 0,
+		clk_rcg_set_rate(priv->base, BLSP1_QUP2_I2C_APPS_CMD_RCGR, 0,
 				 CFG_CLK_SRC_CXO);
 		break;
 	case GCC_BLSP1_QUP3_I2C_APPS_CLK:
 		clk_enable_cbc(priv->base + BLSP1_QUP3_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup3_i2c_apps_regs, 0,
+		clk_rcg_set_rate(priv->base, BLSP1_QUP3_I2C_APPS_CMD_RCGR, 0,
 				 CFG_CLK_SRC_CXO);
 		break;
 	case GCC_BLSP1_QUP4_I2C_APPS_CLK:
 		clk_enable_cbc(priv->base + BLSP1_QUP4_I2C_APPS_CBCR);
-		clk_rcg_set_rate(priv->base, &blsp1_qup4_i2c_apps_regs, 0,
+		clk_rcg_set_rate(priv->base, BLSP1_QUP4_I2C_APPS_CMD_RCGR, 0,
 				 CFG_CLK_SRC_CXO);
 		break;
 	case GCC_SDCC1_AHB_CLK:
 		clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index babd83119e2c..ccb0cf245d33 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -18,15 +18,9 @@
 #include <dt-bindings/clock/qcom,gcc-sdm845.h>
 
 #include "clock-qcom.h"
 
-#define SE9_AHB_CBCR		0x25004
-#define SE9_UART_APPS_CBCR	0x29004
 #define SE9_UART_APPS_CMD_RCGR	0x18148
-#define SE9_UART_APPS_CFG_RCGR	0x1814C
-#define SE9_UART_APPS_M		0x18150
-#define SE9_UART_APPS_N		0x18154
-#define SE9_UART_APPS_D		0x18158
 
 static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
 	F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
 	F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
@@ -45,25 +39,17 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
 	F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
 	{ }
 };
 
-static const struct bcr_regs uart2_regs = {
-	.cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
-	.cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
-	.M = SE9_UART_APPS_M,
-	.N = SE9_UART_APPS_N,
-	.D = SE9_UART_APPS_D,
-};
-
 static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
 {
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
 	const struct freq_tbl *freq;
 
 	switch (clk->id) {
 	case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
 		freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
-		clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
+		clk_rcg_set_rate_mnd(priv->base, SE9_UART_APPS_CMD_RCGR,
 				     freq->pre_div, freq->m, freq->n, freq->src, 16);
 		return freq->freq;
 	default:
 		return 0;

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 06/14] clk/qcom: sdm845: add gdscs
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (4 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 05/14] clk/qcom: use offsets for RCG registers Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:42   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks Caleb Connolly
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

Define the GDSC power domains for SDM845.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/clk/qcom/clock-sdm845.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index ccb0cf245d33..b7154360894a 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -145,13 +145,31 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = {
 	[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
 	[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
 };
 
+static const struct qcom_power_map sdm845_gdscs[] = {
+	[PCIE_0_GDSC] = { 0x6b004 },
+	[PCIE_1_GDSC] = { 0x8d004 },
+	[UFS_CARD_GDSC] = { 0x75004 },
+	[UFS_PHY_GDSC] = { 0x77004 },
+	[USB30_PRIM_GDSC] = { 0xf004 },
+	[USB30_SEC_GDSC] = { 0x10004 },
+	[HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC] = { 0x7d030 },
+	[HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC] = { 0x7d03c },
+	[HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC] = { 0x7d034 },
+	[HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC] = { 0x7d038 },
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = { 0x7d040 },
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = { 0x7d048 },
+	[HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = { 0x7d044 },
+};
+
 static struct msm_clk_data sdm845_clk_data = {
 	.resets = sdm845_gcc_resets,
 	.num_resets = ARRAY_SIZE(sdm845_gcc_resets),
 	.clks = sdm845_clks,
 	.num_clks = ARRAY_SIZE(sdm845_clks),
+	.power_domains = sdm845_gdscs,
+	.num_power_domains = ARRAY_SIZE(sdm845_gdscs),
 
 	.enable = sdm845_clk_enable,
 	.set_rate = sdm845_clk_set_rate,
 };

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (5 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 06/14] clk/qcom: sdm845: add gdscs Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:43   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op Caleb Connolly
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

Most devices only initialise the USB clocks for us if we boot via
"fastboot boot", add the missing clock configuration to get both USB
ports working regardless of the bootloader state.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/clk/qcom/clock-sdm845.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
index b7154360894a..e9c61eb480de 100644
--- a/drivers/clk/qcom/clock-sdm845.c
+++ b/drivers/clk/qcom/clock-sdm845.c
@@ -20,8 +20,12 @@
 #include "clock-qcom.h"
 
 #define SE9_UART_APPS_CMD_RCGR	0x18148
 
+#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf018
+#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf030
+#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf05c
+
 static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
 	F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
 	F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
 	F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
@@ -56,8 +60,10 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
 	}
 }
 
 static const struct gate_clk sdm845_clks[] = {
+	GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK,		0x82020, 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),
 	GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK,		0x5200c, 0x00001000),
 	GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK,		0x5200c, 0x00002000),
@@ -120,8 +126,27 @@ static int sdm845_clk_enable(struct clk *clk)
 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
 
 	debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name);
 
+	switch (clk->id) {
+	case GCC_USB30_PRIM_MASTER_CLK:
+		qcom_gate_clk_en(priv, GCC_USB_PHY_CFG_AHB2PHY_CLK);
+		/* These numbers are just pulled from the frequency tables in the Linux driver */
+		clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
+				     (4.5 * 2) - 1, 0, 0, 1 << 8, 8);
+		clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR,
+				     1, 0, 0, 0, 8);
+		clk_rcg_set_rate_mnd(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR,
+				     1, 0, 0, 0, 8);
+		break;
+	case GCC_USB30_SEC_MASTER_CLK:
+		qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
+
+		qcom_gate_clk_en(priv, GCC_USB3_SEC_CLKREF_CLK);
+		qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
+		break;
+	}
+
 	qcom_gate_clk_en(priv, clk->id);
 
 	return 0;
 }

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (6 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:44   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 09/14] serial: msm-geni: support livetree Caleb Connolly
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

The .direction_input and .direction_output ops are deprecated, and don't
seem to behave properly for us. Implement our own .set_flags op to
handle this correctly.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/gpio/msm_gpio.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 5e57b0cbde75..f5d9ab54e817 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -34,21 +34,21 @@ struct msm_gpio_bank {
 
 #define GPIO_IN_OUT_REG(dev, x) \
 	(GPIO_CONFIG_REG(dev, x) + 0x4)
 
-static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
+static void msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
 	/* Always NOP for special pins, assume they're in the correct state */
 	if (qcom_is_special_pin(priv->pin_data, gpio))
-		return 0;
+		return;
 
 	/* Disable OE bit */
 	clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
 			GPIO_OE_MASK, GPIO_OE_DISABLE);
 
-	return 0;
+	return;
 }
 
 static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
 {
@@ -83,8 +83,25 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
 
 	return 0;
 }
 
+static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags)
+{
+	if (flags & GPIOD_IS_OUT_ACTIVE) {
+		return msm_gpio_direction_output(dev, gpio, 1);
+	} else if (flags & GPIOD_IS_OUT) {
+		return msm_gpio_direction_output(dev, gpio, 0);
+	} else if (flags & GPIOD_IS_IN) {
+		msm_gpio_direction_input(dev, gpio);
+		if (flags & GPIOD_PULL_UP)
+			return msm_gpio_set_value(dev, gpio, 1);
+		else if (flags & GPIOD_PULL_DOWN)
+			return msm_gpio_set_value(dev, gpio, 0);
+	}
+
+	return 0;
+}
+
 static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
 {
 	struct msm_gpio_bank *priv = dev_get_priv(dev);
 
@@ -109,12 +126,10 @@ static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
 	return GPIOF_INPUT;
 }
 
 static const struct dm_gpio_ops gpio_msm_ops = {
-	.direction_input	= msm_gpio_direction_input,
-	.direction_output	= msm_gpio_direction_output,
+	.set_flags		= msm_gpio_set_flags,
 	.get_value		= msm_gpio_get_value,
-	.set_value		= msm_gpio_set_value,
 	.get_function		= msm_gpio_get_function,
 };
 
 static int msm_gpio_probe(struct udevice *dev)

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 09/14] serial: msm-geni: support livetree
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (7 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:44   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 10/14] mach-snapdragon: fixup USB nodes Caleb Connolly
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

When using OF_LIVE, the debug UART driver won't be probed if it's a
subnode of the geni-se-qup controller. Add a NOP driver for the
controller to correctly discover its child nodes.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 drivers/serial/serial_msm_geni.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
index 4aa0bc8c72bc..5260474fb9a4 100644
--- a/drivers/serial/serial_msm_geni.c
+++ b/drivers/serial/serial_msm_geni.c
@@ -605,8 +605,21 @@ U_BOOT_DRIVER(serial_msm_geni) = {
 	.ops = &msm_serial_ops,
 	.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };
 
+static const struct udevice_id geniqup_ids[] = {
+	{ .compatible = "qcom,geni-se-qup" },
+	{ }
+};
+
+U_BOOT_DRIVER(geni_se_qup) = {
+	.name = "geni-se-qup",
+	.id = UCLASS_NOP,
+	.of_match = geniqup_ids,
+	.bind = dm_scan_fdt_dev,
+	.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
+
 #ifdef CONFIG_DEBUG_UART_MSM_GENI
 
 static struct msm_serial_data init_serial_data = {
 	.base = CONFIG_VAL(DEBUG_UART_BASE)

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 10/14] mach-snapdragon: fixup USB nodes
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (8 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 09/14] serial: msm-geni: support livetree Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-19 13:49   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 11/14] mach-snapdragon: fixup power-domains Caleb Connolly
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

We don't support USB super-speed in U-Boot yet, we lack the SS PHY
drivers, however from my testing even with a PHY driver there seem to be
other issues when talking to super-speed peripherals.

In pursuit of maintaining upstream DT compatibility, and simplifying
porting for new devices, let's implement the DT fixups necessary to
configure USB in high-speed only mode at runtime. The pattern is
identical for all Qualcomm boards that use the Synaptics DWC3
controller:

* Add an additional property on the Qualcomm wrapper node
* Remove the super-speed phy phandle and phy-name entries.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 arch/arm/mach-snapdragon/Makefile    |   1 +
 arch/arm/mach-snapdragon/board.c     |   3 +
 arch/arm/mach-snapdragon/of_fixup.c  | 115 +++++++++++++++++++++++++++++++++++
 arch/arm/mach-snapdragon/qcom-priv.h |  19 ++++++
 4 files changed, 138 insertions(+)

diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index 857171e593da..7a4495c8108f 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -2,4 +2,5 @@
 #
 # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
 
 obj-y += board.o
+obj-$(CONFIG_OF_LIVE) += of_fixup.o
diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index 6f762fc948bf..65e4c61e866a 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -27,8 +27,10 @@
 #include <fdt_support.h>
 #include <usb.h>
 #include <sort.h>
 
+#include "qcom-priv.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
 
@@ -159,8 +161,9 @@ void __weak qcom_board_init(void)
 
 int board_init(void)
 {
 	show_psci_version();
+	qcom_of_fixup_nodes();
 	qcom_board_init();
 	return 0;
 }
 
diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
new file mode 100644
index 000000000000..6810c8617cc0
--- /dev/null
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OF_LIVE devicetree fixup.
+ *
+ * This file implements runtime fixups for Qualcomm DT to improve
+ * compatibility with U-Boot. This includes adjusting the USB nodes
+ * to only use USB high-speed, as well as remapping volume buttons
+ * to behave as up/down for navigating U-Boot.
+ *
+ * We use OF_LIVE for this rather than early FDT fixup for a couple
+ * of reasons: it has a much nicer API, is most likely more efficient,
+ * and our changes are only applied to U-Boot. This allows us to use a
+ * DT designed for Linux, run U-Boot with a modified version, and then
+ * boot Linux with the original FDT.
+ *
+ * Copyright (c) 2024 Linaro Ltd.
+ *   Author: Caleb Connolly <caleb.connolly@linaro.org>
+ */
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dm/of_access.h>
+#include <dm/of.h>
+#include <fdt_support.h>
+#include <linux/errno.h>
+
+/* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
+ * USB controllers. Rather than requiring source level DT changes, we fix up
+ * DT here. This improves compatibility with upstream DT and simplifies the
+ * porting process for new devices.
+ */
+static int fixup_qcom_dwc3(struct device_node *glue_np)
+{
+	struct device_node *dwc3;
+	int ret, len, hsphy_idx = 1;
+	const __be32 *phandles;
+	const char *second_phy_name;
+
+	debug("Fixing up %s\n", glue_np->name);
+
+	/* Tell the glue driver to configure the wrapper for high-speed only operation */
+	ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
+	if (ret) {
+		log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret);
+		return ret;
+	}
+
+	/* Find the DWC3 node itself */
+	dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3");
+	if (!dwc3) {
+		log_err("Failed to find dwc3 node\n");
+		return -ENOENT;
+	}
+
+	phandles = of_get_property(dwc3, "phys", &len);
+	len /= sizeof(*phandles);
+	if (len == 1) {
+		log_debug("Only one phy, not a superspeed controller\n");
+		return 0;
+	}
+
+	/* Figure out if the superspeed phy is present and if so then which phy is it? */
+	ret = of_property_read_string_index(dwc3, "phy-names", 1, &second_phy_name);
+	if (ret == -ENODATA) {
+		log_debug("Only one phy, not a super-speed controller\n");
+		return 0;
+	} else if (ret) {
+		log_err("Failed to read second phy name: %d\n", ret);
+		return ret;
+	}
+
+	if (!strncmp("usb3-phy", second_phy_name, strlen("usb3-phy"))) {
+		log_debug("Second phy isn't superspeed (is '%s') assuming first phy is SS\n",
+			  second_phy_name);
+		hsphy_idx = 0;
+	}
+
+	/* Overwrite the "phys" property to only contain the high-speed phy */
+	ret = of_write_prop(dwc3, "phys", sizeof(*phandles), phandles + hsphy_idx);
+	if (ret) {
+		log_err("Failed to overwrite 'phys' property: %d\n", ret);
+		return ret;
+	}
+
+	/* Overwrite "phy-names" to only contain a single entry */
+	ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "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");
+	if (ret) {
+		log_err("Failed to set 'maximum-speed' property: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void fixup_usb_nodes(void)
+{
+	struct device_node *glue_np = NULL;
+	int ret;
+
+	while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) {
+		ret = fixup_qcom_dwc3(glue_np);
+		if (ret)
+			log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
+	}
+}
+
+void qcom_of_fixup_nodes(void)
+{
+	fixup_usb_nodes();
+}
diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h
new file mode 100644
index 000000000000..d18fd1883b7f
--- /dev/null
+++ b/arch/arm/mach-snapdragon/qcom-priv.h
@@ -0,0 +1,19 @@
+
+#ifndef __QCOM_PRIV_H__
+#define __QCOM_PRIV_H__
+
+#if CONFIG_IS_ENABLED(OF_LIVE)
+/**
+ * qcom_of_fixup_nodes() - Fixup Qualcomm DT nodes
+ *
+ * Adjusts nodes in the live tree to improve compatibility with U-Boot.
+ */
+void qcom_of_fixup_nodes(void);
+#else
+static inline void qcom_of_fixup_nodes(void)
+{
+	log_debug("Unable to dynamically fixup USB nodes, please enable CONFIG_OF_LIVE\n");
+}
+#endif /* OF_LIVE */
+
+#endif /* __QCOM_PRIV_H__ */

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 11/14] mach-snapdragon: fixup power-domains
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (9 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 10/14] mach-snapdragon: fixup USB nodes Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-19 13:51   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups Caleb Connolly
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

We don't support the RPM(h)PD power domains in U-Boot, and we don't need
to - the necessary resources are on, and we aren't going to enter any
low power modes.

We could try using a no-op device, but this requires adding a compatible
for every platform, and just pollutes the driver model. So instead let's
just remove every "power-domains" property that references the RPM(h)pd
power controller. This takes <1ms as we're using OF_LIVE.

Of note, this only applies to drivers which are loading post-relocation.
Drivers loaded pre-reloc that reference the rpm(h)pd still need
DM_FLAG_DEFAULT_PD_CTRL_OFF in their flags.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 arch/arm/mach-snapdragon/of_fixup.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
index 6810c8617cc0..49f1fc1948f3 100644
--- a/arch/arm/mach-snapdragon/of_fixup.c
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -21,8 +21,9 @@
 #include <dm/of_access.h>
 #include <dm/of.h>
 #include <fdt_support.h>
 #include <linux/errno.h>
+#include <stdlib.h>
 
 /* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
  * USB controllers. Rather than requiring source level DT changes, we fix up
  * DT here. This improves compatibility with upstream DT and simplifies the
@@ -108,8 +109,39 @@ static void fixup_usb_nodes(void)
 			log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
 	}
 }
 
+/* Remove all references to the rpmhpd device */
+static void fixup_power_domains(void)
+{
+	struct device_node *pd = NULL, *np = NULL;
+	struct property *prop;
+	const __be32 *val;
+
+	/* All Qualcomm platforms name the rpm(h)pd "power-controller" */
+	for_each_of_allnodes(pd) {
+		if (pd->name && !strcmp("power-controller", pd->name))
+			break;
+	}
+
+	/* Sanity check that this is indeed a power domain controller */
+	if (!of_find_property(pd, "#power-domain-cells", NULL)) {
+		log_err("Found power-controller but it doesn't have #power-domain-cells\n");
+		return;
+	}
+
+	/* Remove all references to the power domain controller */
+	for_each_of_allnodes(np) {
+		if (!(prop = of_find_property(np, "power-domains", NULL)))
+			continue;
+
+		val = prop->value;
+		if (val[0] == cpu_to_fdt32(pd->phandle))
+			of_remove_property(np, prop);
+	}
+}
+
 void qcom_of_fixup_nodes(void)
 {
 	fixup_usb_nodes();
+	fixup_power_domains();
 }

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (10 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 11/14] mach-snapdragon: fixup power-domains Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-19 13:55   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 13/14] qcom_defconfig: enable livetree Caleb Connolly
  2024-03-19 12:22 ` [PATCH v3 14/14] qcom_defconfig: enable USB Caleb Connolly
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

The USB VBUS supply for the type-A port is enabled via a GPIO regulator.
This is incorrectly modelled in Linux where only the PCIe dependency is
expressed. Add a U-Boot specific dtsi snippet so that this supply will
get enabled when initialising USB.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 arch/arm/dts/sdm845-db845c-u-boot.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/dts/sdm845-db845c-u-boot.dtsi b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
new file mode 100644
index 000000000000..3c83e21251c4
--- /dev/null
+++ b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* This GPIO must be turned on to enable the 5v VBUS
+ * supply on the USB port.
+ */
+&usb_2_dwc3 {
+	vbus-supply = <&pcie0_3p3v_dual>;
+};

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 13/14] qcom_defconfig: enable livetree
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (11 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-19 13:27   ` Sumit Garg
  2024-03-19 12:22 ` [PATCH v3 14/14] qcom_defconfig: enable USB Caleb Connolly
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

Qualcomm FDTs are on the larger size, and with the addition of DT
modifications during board_init() it makes sense to enable OF_LIVE
globally. The cost of building the tree should be offset by the
increased efficiency at which we can walk it.

Some rough measurements with CONFIG_BOOTSTAGE suggests that this might
add 0.1-0.2ms to the boot-to-console time. However the reset-to-reset
timer difference is in the range of 0.5ms so this could just be noise.

Suffice to say, no significant slow down.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 configs/qcom_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index cbc612b44bd9..eebd0d74bd51 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -25,8 +25,11 @@ CONFIG_CMD_UFS=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_CAT=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_LOG=y
+CONFIG_OF_LIVE=y
+# CONFIG_NET is not set
+# CONFIG_OFNODE_MULTI_TREE is not set
 CONFIG_BUTTON_QCOM_PMIC=y
 CONFIG_CLK=y
 CONFIG_CLK_QCOM_QCS404=y
 CONFIG_CLK_QCOM_SDM845=y

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v3 14/14] qcom_defconfig: enable USB
  2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
                   ` (12 preceding siblings ...)
  2024-03-19 12:22 ` [PATCH v3 13/14] qcom_defconfig: enable livetree Caleb Connolly
@ 2024-03-19 12:22 ` Caleb Connolly
  2024-03-20  5:40   ` Sumit Garg
  13 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 12:22 UTC (permalink / raw
  To: Tom Rini, Caleb Connolly, Neil Armstrong, Sumit Garg,
	Lukasz Majewski, Sean Anderson
  Cc: u-boot

Enable support for the DWC3 USB controller and required dependencies for
Qualcomm boards, specifically the DB845c:
* IOMMU / SMMU
* USB high-speed PHYs
* Mass storage and ACM gadgets

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 configs/qcom_defconfig | 49 ++++++++++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
index eebd0d74bd51..156c205284dd 100644
--- a/configs/qcom_defconfig
+++ b/configs/qcom_defconfig
@@ -12,42 +12,63 @@ CONFIG_BOOTSTD_FULL=y
 CONFIG_BOOTDELAY=1
 CONFIG_USE_PREBOOT=y
 CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
 CONFIG_SYS_CBSIZE=512
+# CONFIG_SYS_DEVICE_NULLDEV is not set
 CONFIG_LOG_MAX_LEVEL=9
 CONFIG_LOG_DEFAULT_LEVEL=4
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_EEPROM=y
+CONFIG_SYS_I2C_EEPROM_BUS=2
+CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
+CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
+# CONFIG_CMD_BIND is not set
 CONFIG_CMD_CLK=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_UFS=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_CAT=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_LOG=y
 CONFIG_OF_LIVE=y
 # CONFIG_NET is not set
+CONFIG_DM_WARN=y
 # CONFIG_OFNODE_MULTI_TREE is not set
 CONFIG_BUTTON_QCOM_PMIC=y
 CONFIG_CLK=y
 CONFIG_CLK_QCOM_QCS404=y
 CONFIG_CLK_QCOM_SDM845=y
 CONFIG_MSM_GPIO=y
 CONFIG_QCOM_PMIC_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_QUP=y
+CONFIG_I2C_MUX=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_BUTTON_KEYBOARD=y
+CONFIG_IOMMU=y
+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
+CONFIG_DM_ETH_PHY=y
 CONFIG_PHY=y
+CONFIG_PHY_QCOM_QUSB2=y
+CONFIG_PHY_QCOM_USB_HS_7NM=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_QCOM_QCS404=y
 CONFIG_PINCTRL_QCOM_SDM845=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_QCOM=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_SCSI=y
 CONFIG_MSM_SERIAL=y
 CONFIG_MSM_GENI_SERIAL=y
 CONFIG_SPMI_MSM=y
@@ -56,8 +77,13 @@ CONFIG_SYSINFO_SMBIOS=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_MASS_STORAGE=y
+CONFIG_USB_FUNCTION_ACM=y
 CONFIG_UFS=y
 CONFIG_VIDEO=y
 # CONFIG_VIDEO_FONT_8X16 is not set
 CONFIG_VIDEO_FONT_16X32=y
@@ -66,27 +92,4 @@ CONFIG_NO_FB_CLEAR=y
 CONFIG_VIDEO_SIMPLE=y
 CONFIG_HEXDUMP=y
 # CONFIG_GENERATE_SMBIOS_TABLE is not set
 CONFIG_LMB_MAX_REGIONS=64
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_EEPROM=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_PING=y
-CONFIG_DM_ETH=y
-CONFIG_DM_ETH_PHY=y
-CONFIG_DM_MDIO=y
-CONFIG_DWC_ETH_QOS=y
-CONFIG_DWC_ETH_QOS_QCOM=y
-CONFIG_RGMII=y
-CONFIG_PHY_MICREL=y
-CONFIG_PHY_MICREL_KSZ90X1=y
-CONFIG_MISC=y
-CONFIG_NVMEM=y
-CONFIG_DM_I2C=y
-CONFIG_I2C_SUPPORT=y
-CONFIG_I2C_MUX=y
-CONFIG_I2C_EEPROM=y
-CONFIG_SYS_I2C=y
-CONFIG_SYS_I2C_QUP=y
-CONFIG_SYS_I2C_EEPROM_BUS=2
-CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5

-- 
2.44.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 13/14] qcom_defconfig: enable livetree
  2024-03-19 12:22 ` [PATCH v3 13/14] qcom_defconfig: enable livetree Caleb Connolly
@ 2024-03-19 13:27   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-19 13:27 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Qualcomm FDTs are on the larger size, and with the addition of DT
> modifications during board_init() it makes sense to enable OF_LIVE
> globally. The cost of building the tree should be offset by the
> increased efficiency at which we can walk it.
>
> Some rough measurements with CONFIG_BOOTSTAGE suggests that this might
> add 0.1-0.2ms to the boot-to-console time. However the reset-to-reset
> timer difference is in the range of 0.5ms so this could just be noise.
>
> Suffice to say, no significant slow down.
>
> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  configs/qcom_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
> index cbc612b44bd9..eebd0d74bd51 100644
> --- a/configs/qcom_defconfig
> +++ b/configs/qcom_defconfig
> @@ -25,8 +25,11 @@ CONFIG_CMD_UFS=y
>  CONFIG_CMD_USB=y
>  CONFIG_CMD_CAT=y
>  CONFIG_CMD_BMP=y
>  CONFIG_CMD_LOG=y
> +CONFIG_OF_LIVE=y
> +# CONFIG_NET is not set

Is there any reason to disable CONFIG_NET here? We already support
networking on QCS404 based devices?

-Sumit

> +# CONFIG_OFNODE_MULTI_TREE is not set
>  CONFIG_BUTTON_QCOM_PMIC=y
>  CONFIG_CLK=y
>  CONFIG_CLK_QCOM_QCS404=y
>  CONFIG_CLK_QCOM_SDM845=y
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 10/14] mach-snapdragon: fixup USB nodes
  2024-03-19 12:22 ` [PATCH v3 10/14] mach-snapdragon: fixup USB nodes Caleb Connolly
@ 2024-03-19 13:49   ` Sumit Garg
  2024-03-19 14:45     ` Caleb Connolly
  0 siblings, 1 reply; 35+ messages in thread
From: Sumit Garg @ 2024-03-19 13:49 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

Hi Caleb,

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> We don't support USB super-speed in U-Boot yet, we lack the SS PHY
> drivers, however from my testing even with a PHY driver there seem to be
> other issues when talking to super-speed peripherals.
>
> In pursuit of maintaining upstream DT compatibility,

I can understand the reasoning behind this but since we enable these
fixups for every Qcom platform it may turn out to be counter
productive. There can be embedded use-cases where bootup times have
stringent requirements. Also, depending upon CPU speed/freq the add-on
times due to these can be significant.

I would suggest we rather solve these USB issues either via a common
Qcom *-u-boot.dtsi file which can be included for every board.

-Sumit

> and simplifying
> porting for new devices, let's implement the DT fixups necessary to
> configure USB in high-speed only mode at runtime. The pattern is
> identical for all Qualcomm boards that use the Synaptics DWC3
> controller:
>
> * Add an additional property on the Qualcomm wrapper node
> * Remove the super-speed phy phandle and phy-name entries.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  arch/arm/mach-snapdragon/Makefile    |   1 +
>  arch/arm/mach-snapdragon/board.c     |   3 +
>  arch/arm/mach-snapdragon/of_fixup.c  | 115 +++++++++++++++++++++++++++++++++++
>  arch/arm/mach-snapdragon/qcom-priv.h |  19 ++++++
>  4 files changed, 138 insertions(+)
>
> diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
> index 857171e593da..7a4495c8108f 100644
> --- a/arch/arm/mach-snapdragon/Makefile
> +++ b/arch/arm/mach-snapdragon/Makefile
> @@ -2,4 +2,5 @@
>  #
>  # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
>
>  obj-y += board.o
> +obj-$(CONFIG_OF_LIVE) += of_fixup.o
> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
> index 6f762fc948bf..65e4c61e866a 100644
> --- a/arch/arm/mach-snapdragon/board.c
> +++ b/arch/arm/mach-snapdragon/board.c
> @@ -27,8 +27,10 @@
>  #include <fdt_support.h>
>  #include <usb.h>
>  #include <sort.h>
>
> +#include "qcom-priv.h"
> +
>  DECLARE_GLOBAL_DATA_PTR;
>
>  static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
>
> @@ -159,8 +161,9 @@ void __weak qcom_board_init(void)
>
>  int board_init(void)
>  {
>         show_psci_version();
> +       qcom_of_fixup_nodes();
>         qcom_board_init();
>         return 0;
>  }
>
> diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
> new file mode 100644
> index 000000000000..6810c8617cc0
> --- /dev/null
> +++ b/arch/arm/mach-snapdragon/of_fixup.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * OF_LIVE devicetree fixup.
> + *
> + * This file implements runtime fixups for Qualcomm DT to improve
> + * compatibility with U-Boot. This includes adjusting the USB nodes
> + * to only use USB high-speed, as well as remapping volume buttons
> + * to behave as up/down for navigating U-Boot.
> + *
> + * We use OF_LIVE for this rather than early FDT fixup for a couple
> + * of reasons: it has a much nicer API, is most likely more efficient,
> + * and our changes are only applied to U-Boot. This allows us to use a
> + * DT designed for Linux, run U-Boot with a modified version, and then
> + * boot Linux with the original FDT.
> + *
> + * Copyright (c) 2024 Linaro Ltd.
> + *   Author: Caleb Connolly <caleb.connolly@linaro.org>
> + */
> +
> +#include <dt-bindings/input/linux-event-codes.h>
> +#include <dm/of_access.h>
> +#include <dm/of.h>
> +#include <fdt_support.h>
> +#include <linux/errno.h>
> +
> +/* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
> + * USB controllers. Rather than requiring source level DT changes, we fix up
> + * DT here. This improves compatibility with upstream DT and simplifies the
> + * porting process for new devices.
> + */
> +static int fixup_qcom_dwc3(struct device_node *glue_np)
> +{
> +       struct device_node *dwc3;
> +       int ret, len, hsphy_idx = 1;
> +       const __be32 *phandles;
> +       const char *second_phy_name;
> +
> +       debug("Fixing up %s\n", glue_np->name);
> +
> +       /* Tell the glue driver to configure the wrapper for high-speed only operation */
> +       ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
> +       if (ret) {
> +               log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* Find the DWC3 node itself */
> +       dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3");
> +       if (!dwc3) {
> +               log_err("Failed to find dwc3 node\n");
> +               return -ENOENT;
> +       }
> +
> +       phandles = of_get_property(dwc3, "phys", &len);
> +       len /= sizeof(*phandles);
> +       if (len == 1) {
> +               log_debug("Only one phy, not a superspeed controller\n");
> +               return 0;
> +       }
> +
> +       /* Figure out if the superspeed phy is present and if so then which phy is it? */
> +       ret = of_property_read_string_index(dwc3, "phy-names", 1, &second_phy_name);
> +       if (ret == -ENODATA) {
> +               log_debug("Only one phy, not a super-speed controller\n");
> +               return 0;
> +       } else if (ret) {
> +               log_err("Failed to read second phy name: %d\n", ret);
> +               return ret;
> +       }
> +
> +       if (!strncmp("usb3-phy", second_phy_name, strlen("usb3-phy"))) {
> +               log_debug("Second phy isn't superspeed (is '%s') assuming first phy is SS\n",
> +                         second_phy_name);
> +               hsphy_idx = 0;
> +       }
> +
> +       /* Overwrite the "phys" property to only contain the high-speed phy */
> +       ret = of_write_prop(dwc3, "phys", sizeof(*phandles), phandles + hsphy_idx);
> +       if (ret) {
> +               log_err("Failed to overwrite 'phys' property: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* Overwrite "phy-names" to only contain a single entry */
> +       ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "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");
> +       if (ret) {
> +               log_err("Failed to set 'maximum-speed' property: %d\n", ret);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static void fixup_usb_nodes(void)
> +{
> +       struct device_node *glue_np = NULL;
> +       int ret;
> +
> +       while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) {
> +               ret = fixup_qcom_dwc3(glue_np);
> +               if (ret)
> +                       log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
> +       }
> +}
> +
> +void qcom_of_fixup_nodes(void)
> +{
> +       fixup_usb_nodes();
> +}
> diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h
> new file mode 100644
> index 000000000000..d18fd1883b7f
> --- /dev/null
> +++ b/arch/arm/mach-snapdragon/qcom-priv.h
> @@ -0,0 +1,19 @@
> +
> +#ifndef __QCOM_PRIV_H__
> +#define __QCOM_PRIV_H__
> +
> +#if CONFIG_IS_ENABLED(OF_LIVE)
> +/**
> + * qcom_of_fixup_nodes() - Fixup Qualcomm DT nodes
> + *
> + * Adjusts nodes in the live tree to improve compatibility with U-Boot.
> + */
> +void qcom_of_fixup_nodes(void);
> +#else
> +static inline void qcom_of_fixup_nodes(void)
> +{
> +       log_debug("Unable to dynamically fixup USB nodes, please enable CONFIG_OF_LIVE\n");
> +}
> +#endif /* OF_LIVE */
> +
> +#endif /* __QCOM_PRIV_H__ */
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 11/14] mach-snapdragon: fixup power-domains
  2024-03-19 12:22 ` [PATCH v3 11/14] mach-snapdragon: fixup power-domains Caleb Connolly
@ 2024-03-19 13:51   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-19 13:51 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> We don't support the RPM(h)PD power domains in U-Boot, and we don't need
> to - the necessary resources are on, and we aren't going to enter any
> low power modes.
>
> We could try using a no-op device, but this requires adding a compatible
> for every platform, and just pollutes the driver model. So instead let's
> just remove every "power-domains" property that references the RPM(h)pd
> power controller. This takes <1ms as we're using OF_LIVE.

Similar reasoning here as on patch #10, it would be better if we can
handle it via a no-op device.

-Sumit

>
> Of note, this only applies to drivers which are loading post-relocation.
> Drivers loaded pre-reloc that reference the rpm(h)pd still need
> DM_FLAG_DEFAULT_PD_CTRL_OFF in their flags.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  arch/arm/mach-snapdragon/of_fixup.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
>
> diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
> index 6810c8617cc0..49f1fc1948f3 100644
> --- a/arch/arm/mach-snapdragon/of_fixup.c
> +++ b/arch/arm/mach-snapdragon/of_fixup.c
> @@ -21,8 +21,9 @@
>  #include <dm/of_access.h>
>  #include <dm/of.h>
>  #include <fdt_support.h>
>  #include <linux/errno.h>
> +#include <stdlib.h>
>
>  /* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
>   * USB controllers. Rather than requiring source level DT changes, we fix up
>   * DT here. This improves compatibility with upstream DT and simplifies the
> @@ -108,8 +109,39 @@ static void fixup_usb_nodes(void)
>                         log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
>         }
>  }
>
> +/* Remove all references to the rpmhpd device */
> +static void fixup_power_domains(void)
> +{
> +       struct device_node *pd = NULL, *np = NULL;
> +       struct property *prop;
> +       const __be32 *val;
> +
> +       /* All Qualcomm platforms name the rpm(h)pd "power-controller" */
> +       for_each_of_allnodes(pd) {
> +               if (pd->name && !strcmp("power-controller", pd->name))
> +                       break;
> +       }
> +
> +       /* Sanity check that this is indeed a power domain controller */
> +       if (!of_find_property(pd, "#power-domain-cells", NULL)) {
> +               log_err("Found power-controller but it doesn't have #power-domain-cells\n");
> +               return;
> +       }
> +
> +       /* Remove all references to the power domain controller */
> +       for_each_of_allnodes(np) {
> +               if (!(prop = of_find_property(np, "power-domains", NULL)))
> +                       continue;
> +
> +               val = prop->value;
> +               if (val[0] == cpu_to_fdt32(pd->phandle))
> +                       of_remove_property(np, prop);
> +       }
> +}
> +
>  void qcom_of_fixup_nodes(void)
>  {
>         fixup_usb_nodes();
> +       fixup_power_domains();
>  }
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups
  2024-03-19 12:22 ` [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups Caleb Connolly
@ 2024-03-19 13:55   ` Sumit Garg
  2024-03-20 12:33     ` Caleb Connolly
  0 siblings, 1 reply; 35+ messages in thread
From: Sumit Garg @ 2024-03-19 13:55 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> The USB VBUS supply for the type-A port is enabled via a GPIO regulator.
> This is incorrectly modelled in Linux where only the PCIe dependency is
> expressed.

Can we send a fix for the Linux kernel DTS to correctly model it? We
can then later get rid of this modification once that is accepted.

-Sumit

> Add a U-Boot specific dtsi snippet so that this supply will
> get enabled when initialising USB.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  arch/arm/dts/sdm845-db845c-u-boot.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm/dts/sdm845-db845c-u-boot.dtsi b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
> new file mode 100644
> index 000000000000..3c83e21251c4
> --- /dev/null
> +++ b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/* This GPIO must be turned on to enable the 5v VBUS
> + * supply on the USB port.
> + */
> +&usb_2_dwc3 {
> +       vbus-supply = <&pcie0_3p3v_dual>;
> +};
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 10/14] mach-snapdragon: fixup USB nodes
  2024-03-19 13:49   ` Sumit Garg
@ 2024-03-19 14:45     ` Caleb Connolly
  2024-03-20  4:37       ` Sumit Garg
  0 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-19 14:45 UTC (permalink / raw
  To: Sumit Garg
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

Hi Sumit,

On 19/03/2024 13:49, Sumit Garg wrote:
> Hi Caleb,
> 
> On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>> We don't support USB super-speed in U-Boot yet, we lack the SS PHY
>> drivers, however from my testing even with a PHY driver there seem to be
>> other issues when talking to super-speed peripherals.
>>
>> In pursuit of maintaining upstream DT compatibility,
> 
> I can understand the reasoning behind this but since we enable these
> fixups for every Qcom platform it may turn out to be counter
> productive. There can be embedded use-cases where bootup times have
> stringent requirements. Also, depending upon CPU speed/freq the add-on
> times due to these can be significant.

I have measured this on a few different boards:

On DB410c, the slowest board we currently support
* of_live_build took 7228us
* Fixing up USB nodes took 131us
* Fixing up power domains took 88us

On RB1 (the slowest new platform with a QCM2290 SoC)
* of_live_build took 2078us
* Fixing up USB nodes took 39us
* Fixing up power domains took 27us

The time taken initially to build the livetree is likely made back as it
is much much faster to query than the flat tree (as you can see, walking
every single node takes <100us on db410c). I took some rough
measurements of the boot-to-console time on sdm845 (see the "enable
livetree" patch) and basically concluded that the delta between live and
flat trees is within the margin of error.

If a specific board for whatever reason wants to avoid using OF_LIVE
then I'm fine with that, db410c isn't using it for example.
> 
> I would suggest we rather solve these USB issues either via a common
> Qcom *-u-boot.dtsi file which can be included for every board.
> 
> -Sumit
> 
>> and simplifying
>> porting for new devices, let's implement the DT fixups necessary to
>> configure USB in high-speed only mode at runtime. The pattern is
>> identical for all Qualcomm boards that use the Synaptics DWC3
>> controller:
>>
>> * Add an additional property on the Qualcomm wrapper node
>> * Remove the super-speed phy phandle and phy-name entries.
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
>> ---
>>  arch/arm/mach-snapdragon/Makefile    |   1 +
>>  arch/arm/mach-snapdragon/board.c     |   3 +
>>  arch/arm/mach-snapdragon/of_fixup.c  | 115 +++++++++++++++++++++++++++++++++++
>>  arch/arm/mach-snapdragon/qcom-priv.h |  19 ++++++
>>  4 files changed, 138 insertions(+)
>>
>> diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
>> index 857171e593da..7a4495c8108f 100644
>> --- a/arch/arm/mach-snapdragon/Makefile
>> +++ b/arch/arm/mach-snapdragon/Makefile
>> @@ -2,4 +2,5 @@
>>  #
>>  # (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
>>
>>  obj-y += board.o
>> +obj-$(CONFIG_OF_LIVE) += of_fixup.o
>> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
>> index 6f762fc948bf..65e4c61e866a 100644
>> --- a/arch/arm/mach-snapdragon/board.c
>> +++ b/arch/arm/mach-snapdragon/board.c
>> @@ -27,8 +27,10 @@
>>  #include <fdt_support.h>
>>  #include <usb.h>
>>  #include <sort.h>
>>
>> +#include "qcom-priv.h"
>> +
>>  DECLARE_GLOBAL_DATA_PTR;
>>
>>  static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } };
>>
>> @@ -159,8 +161,9 @@ void __weak qcom_board_init(void)
>>
>>  int board_init(void)
>>  {
>>         show_psci_version();
>> +       qcom_of_fixup_nodes();
>>         qcom_board_init();
>>         return 0;
>>  }
>>
>> diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
>> new file mode 100644
>> index 000000000000..6810c8617cc0
>> --- /dev/null
>> +++ b/arch/arm/mach-snapdragon/of_fixup.c
>> @@ -0,0 +1,115 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * OF_LIVE devicetree fixup.
>> + *
>> + * This file implements runtime fixups for Qualcomm DT to improve
>> + * compatibility with U-Boot. This includes adjusting the USB nodes
>> + * to only use USB high-speed, as well as remapping volume buttons
>> + * to behave as up/down for navigating U-Boot.
>> + *
>> + * We use OF_LIVE for this rather than early FDT fixup for a couple
>> + * of reasons: it has a much nicer API, is most likely more efficient,
>> + * and our changes are only applied to U-Boot. This allows us to use a
>> + * DT designed for Linux, run U-Boot with a modified version, and then
>> + * boot Linux with the original FDT.
>> + *
>> + * Copyright (c) 2024 Linaro Ltd.
>> + *   Author: Caleb Connolly <caleb.connolly@linaro.org>
>> + */
>> +
>> +#include <dt-bindings/input/linux-event-codes.h>
>> +#include <dm/of_access.h>
>> +#include <dm/of.h>
>> +#include <fdt_support.h>
>> +#include <linux/errno.h>
>> +
>> +/* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
>> + * USB controllers. Rather than requiring source level DT changes, we fix up
>> + * DT here. This improves compatibility with upstream DT and simplifies the
>> + * porting process for new devices.
>> + */
>> +static int fixup_qcom_dwc3(struct device_node *glue_np)
>> +{
>> +       struct device_node *dwc3;
>> +       int ret, len, hsphy_idx = 1;
>> +       const __be32 *phandles;
>> +       const char *second_phy_name;
>> +
>> +       debug("Fixing up %s\n", glue_np->name);
>> +
>> +       /* Tell the glue driver to configure the wrapper for high-speed only operation */
>> +       ret = of_write_prop(glue_np, "qcom,select-utmi-as-pipe-clk", 0, NULL);
>> +       if (ret) {
>> +               log_err("Failed to add property 'qcom,select-utmi-as-pipe-clk': %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /* Find the DWC3 node itself */
>> +       dwc3 = of_find_compatible_node(glue_np, NULL, "snps,dwc3");
>> +       if (!dwc3) {
>> +               log_err("Failed to find dwc3 node\n");
>> +               return -ENOENT;
>> +       }
>> +
>> +       phandles = of_get_property(dwc3, "phys", &len);
>> +       len /= sizeof(*phandles);
>> +       if (len == 1) {
>> +               log_debug("Only one phy, not a superspeed controller\n");
>> +               return 0;
>> +       }
>> +
>> +       /* Figure out if the superspeed phy is present and if so then which phy is it? */
>> +       ret = of_property_read_string_index(dwc3, "phy-names", 1, &second_phy_name);
>> +       if (ret == -ENODATA) {
>> +               log_debug("Only one phy, not a super-speed controller\n");
>> +               return 0;
>> +       } else if (ret) {
>> +               log_err("Failed to read second phy name: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       if (!strncmp("usb3-phy", second_phy_name, strlen("usb3-phy"))) {
>> +               log_debug("Second phy isn't superspeed (is '%s') assuming first phy is SS\n",
>> +                         second_phy_name);
>> +               hsphy_idx = 0;
>> +       }
>> +
>> +       /* Overwrite the "phys" property to only contain the high-speed phy */
>> +       ret = of_write_prop(dwc3, "phys", sizeof(*phandles), phandles + hsphy_idx);
>> +       if (ret) {
>> +               log_err("Failed to overwrite 'phys' property: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /* Overwrite "phy-names" to only contain a single entry */
>> +       ret = of_write_prop(dwc3, "phy-names", strlen("usb2-phy"), "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");
>> +       if (ret) {
>> +               log_err("Failed to set 'maximum-speed' property: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static void fixup_usb_nodes(void)
>> +{
>> +       struct device_node *glue_np = NULL;
>> +       int ret;
>> +
>> +       while ((glue_np = of_find_compatible_node(glue_np, NULL, "qcom,dwc3"))) {
>> +               ret = fixup_qcom_dwc3(glue_np);
>> +               if (ret)
>> +                       log_warning("Failed to fixup node %s: %d\n", glue_np->name, ret);
>> +       }
>> +}
>> +
>> +void qcom_of_fixup_nodes(void)
>> +{
>> +       fixup_usb_nodes();
>> +}
>> diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h
>> new file mode 100644
>> index 000000000000..d18fd1883b7f
>> --- /dev/null
>> +++ b/arch/arm/mach-snapdragon/qcom-priv.h
>> @@ -0,0 +1,19 @@
>> +
>> +#ifndef __QCOM_PRIV_H__
>> +#define __QCOM_PRIV_H__
>> +
>> +#if CONFIG_IS_ENABLED(OF_LIVE)
>> +/**
>> + * qcom_of_fixup_nodes() - Fixup Qualcomm DT nodes
>> + *
>> + * Adjusts nodes in the live tree to improve compatibility with U-Boot.
>> + */
>> +void qcom_of_fixup_nodes(void);
>> +#else
>> +static inline void qcom_of_fixup_nodes(void)
>> +{
>> +       log_debug("Unable to dynamically fixup USB nodes, please enable CONFIG_OF_LIVE\n");
>> +}
>> +#endif /* OF_LIVE */
>> +
>> +#endif /* __QCOM_PRIV_H__ */
>>
>> --
>> 2.44.0
>>

-- 
// Caleb (they/them)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 10/14] mach-snapdragon: fixup USB nodes
  2024-03-19 14:45     ` Caleb Connolly
@ 2024-03-20  4:37       ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  4:37 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 20:15, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Hi Sumit,
>
> On 19/03/2024 13:49, Sumit Garg wrote:
> > Hi Caleb,
> >
> > On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
> >>
> >> We don't support USB super-speed in U-Boot yet, we lack the SS PHY
> >> drivers, however from my testing even with a PHY driver there seem to be
> >> other issues when talking to super-speed peripherals.
> >>
> >> In pursuit of maintaining upstream DT compatibility,
> >
> > I can understand the reasoning behind this but since we enable these
> > fixups for every Qcom platform it may turn out to be counter
> > productive. There can be embedded use-cases where bootup times have
> > stringent requirements. Also, depending upon CPU speed/freq the add-on
> > times due to these can be significant.
>
> I have measured this on a few different boards:
>
> On DB410c, the slowest board we currently support
> * of_live_build took 7228us
> * Fixing up USB nodes took 131us
> * Fixing up power domains took 88us
>
> On RB1 (the slowest new platform with a QCM2290 SoC)
> * of_live_build took 2078us
> * Fixing up USB nodes took 39us
> * Fixing up power domains took 27us
>
> The time taken initially to build the livetree is likely made back as it
> is much much faster to query than the flat tree (as you can see, walking
> every single node takes <100us on db410c). I took some rough
> measurements of the boot-to-console time on sdm845 (see the "enable
> livetree" patch) and basically concluded that the delta between live and
> flat trees is within the margin of error.
>
> If a specific board for whatever reason wants to avoid using OF_LIVE
> then I'm fine with that, db410c isn't using it for example.

Okay that's fair. Let's try this approach and see if it pans out well.

-Sumit

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver
  2024-03-19 12:22 ` [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver Caleb Connolly
@ 2024-03-20  5:21   ` Sumit Garg
  2024-03-20 13:47     ` Caleb Connolly
  0 siblings, 1 reply; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:21 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot,
	Bhupesh Sharma

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> From: Bhupesh Sharma <bhupesh.linux@gmail.com>
>
> The Snapdragon 845 and several other Qualcomm SoCs feature this
> USB high-speed phy. Add a driver for it based on the Linux driver, with
> support for the SDM845, and the QCM2290 and SM6115 SoCs which will gain
> support in U-Boot in future patches.
>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
> [code cleanup, switch to clk_bulk]
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/phy/qcom/Kconfig          |   7 +
>  drivers/phy/qcom/Makefile         |   1 +
>  drivers/phy/qcom/phy-qcom-qusb2.c | 468 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 476 insertions(+)
>
> diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
> index f4ca174805a4..361dfb6e1126 100644
> --- a/drivers/phy/qcom/Kconfig
> +++ b/drivers/phy/qcom/Kconfig
> @@ -11,8 +11,15 @@ config PHY_QCOM_IPQ4019_USB
>         depends on PHY && ARCH_IPQ40XX
>         help
>           Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
>
> +config PHY_QCOM_QUSB2
> +       tristate "Qualcomm USB QUSB2 PHY driver"
> +       depends on PHY && ARCH_SNAPDRAGON
> +       help
> +         Enable this to support the Super-Speed USB transceiver on various
> +         Qualcomm chipsets.
> +
>  config PHY_QCOM_USB_HS_28NM
>         tristate "Qualcomm 28nm High-Speed PHY"
>         depends on PHY && ARCH_SNAPDRAGON
>         help
> diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
> index 2113f178c0c7..f6af985666a4 100644
> --- a/drivers/phy/qcom/Makefile
> +++ b/drivers/phy/qcom/Makefile
> @@ -1,4 +1,5 @@
>  obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
>  obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
> +obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
>  obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
> diff --git a/drivers/phy/qcom/phy-qcom-qusb2.c b/drivers/phy/qcom/phy-qcom-qusb2.c
> new file mode 100644
> index 000000000000..5b654403a181
> --- /dev/null
> +++ b/drivers/phy/qcom/phy-qcom-qusb2.c
> @@ -0,0 +1,468 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Bhupesh Sharma <bhupesh.sharma@linaro.org>
> + *
> + * Based on Linux driver
> + */
> +
> +#include <dm.h>
> +#include <generic-phy.h>
> +#include <linux/bitops.h>
> +#include <asm/io.h>
> +#include <reset.h>
> +#include <clk.h>
> +#include <linux/delay.h>
> +
> +#include <dt-bindings/phy/phy-qcom-qusb2.h>
> +
> +#define QUSB2PHY_PLL 0x0
> +#define QUSB2PHY_PLL_TEST 0x04
> +#define CLK_REF_SEL BIT(7)
> +
> +#define QUSB2PHY_PLL_TUNE 0x08
> +#define QUSB2PHY_PLL_USER_CTL1 0x0c
> +#define QUSB2PHY_PLL_USER_CTL2 0x10
> +#define QUSB2PHY_PLL_AUTOPGM_CTL1 0x1c
> +#define QUSB2PHY_PLL_PWR_CTRL 0x18
> +
> +/* QUSB2PHY_PLL_STATUS register bits */
> +#define PLL_LOCKED BIT(5)
> +
> +/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
> +#define CORE_READY_STATUS BIT(0)
> +
> +/* QUSB2PHY_PORT_POWERDOWN register bits */
> +#define CLAMP_N_EN BIT(5)
> +#define FREEZIO_N BIT(1)
> +#define POWER_DOWN BIT(0)
> +
> +/* QUSB2PHY_PWR_CTRL1 register bits */
> +#define PWR_CTRL1_VREF_SUPPLY_TRIM BIT(5)
> +#define PWR_CTRL1_CLAMP_N_EN BIT(1)
> +
> +#define QUSB2PHY_REFCLK_ENABLE BIT(0)
> +
> +#define PHY_CLK_SCHEME_SEL BIT(0)
> +
> +/* QUSB2PHY_INTR_CTRL register bits */
> +#define DMSE_INTR_HIGH_SEL BIT(4)
> +#define DPSE_INTR_HIGH_SEL BIT(3)
> +#define CHG_DET_INTR_EN BIT(2)
> +#define DMSE_INTR_EN BIT(1)
> +#define DPSE_INTR_EN BIT(0)
> +
> +/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register bits */
> +#define CORE_PLL_EN_FROM_RESET BIT(4)
> +#define CORE_RESET BIT(5)
> +#define CORE_RESET_MUX BIT(6)
> +
> +/* QUSB2PHY_IMP_CTRL1 register bits */
> +#define IMP_RES_OFFSET_MASK GENMASK(5, 0)
> +#define IMP_RES_OFFSET_SHIFT 0x0
> +
> +/* QUSB2PHY_PLL_BIAS_CONTROL_2 register bits */
> +#define BIAS_CTRL2_RES_OFFSET_MASK GENMASK(5, 0)
> +#define BIAS_CTRL2_RES_OFFSET_SHIFT 0x0
> +
> +/* QUSB2PHY_CHG_CONTROL_2 register bits */
> +#define CHG_CTRL2_OFFSET_MASK GENMASK(5, 4)
> +#define CHG_CTRL2_OFFSET_SHIFT 0x4
> +
> +/* QUSB2PHY_PORT_TUNE1 register bits */
> +#define HSTX_TRIM_MASK GENMASK(7, 4)
> +#define HSTX_TRIM_SHIFT 0x4
> +#define PREEMPH_WIDTH_HALF_BIT BIT(2)
> +#define PREEMPHASIS_EN_MASK GENMASK(1, 0)
> +#define PREEMPHASIS_EN_SHIFT 0x0
> +
> +/* QUSB2PHY_PORT_TUNE2 register bits */
> +#define HSDISC_TRIM_MASK GENMASK(1, 0)
> +#define HSDISC_TRIM_SHIFT 0x0
> +
> +#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x04
> +#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x18c
> +#define QUSB2PHY_PLL_CMODE 0x2c
> +#define QUSB2PHY_PLL_LOCK_DELAY 0x184
> +#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0xb4
> +#define QUSB2PHY_PLL_BIAS_CONTROL_1 0x194
> +#define QUSB2PHY_PLL_BIAS_CONTROL_2 0x198
> +#define QUSB2PHY_PWR_CTRL2 0x214
> +#define QUSB2PHY_IMP_CTRL1 0x220
> +#define QUSB2PHY_IMP_CTRL2 0x224
> +#define QUSB2PHY_CHG_CTRL2 0x23c
> +
> +struct qusb2_phy_init_tbl {
> +       unsigned int offset;
> +       unsigned int val;
> +       /*
> +        * register part of layout ?
> +        * if yes, then offset gives index in the reg-layout
> +        */
> +       int in_layout;
> +};
> +
> +struct qusb2_phy_cfg {
> +       const struct qusb2_phy_init_tbl *tbl;
> +       /* number of entries in the table */
> +       unsigned int tbl_num;
> +       /* offset to PHY_CLK_SCHEME register in TCSR map */
> +       unsigned int clk_scheme_offset;
> +
> +       /* array of registers with different offsets */
> +       const unsigned int *regs;
> +       unsigned int mask_core_ready;
> +       unsigned int disable_ctrl;
> +       unsigned int autoresume_en;
> +
> +       /* true if PHY has PLL_TEST register to select clk_scheme */
> +       bool has_pll_test;
> +
> +       /* true if TUNE1 register must be updated by fused value, else TUNE2 */
> +       bool update_tune1_with_efuse;
> +
> +       /* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
> +       bool has_pll_override;
> +};
> +
> +/* set of registers with offsets different per-PHY */
> +enum qusb2phy_reg_layout {
> +       QUSB2PHY_PLL_CORE_INPUT_OVERRIDE,
> +       QUSB2PHY_PLL_STATUS,
> +       QUSB2PHY_PORT_TUNE1,
> +       QUSB2PHY_PORT_TUNE2,
> +       QUSB2PHY_PORT_TUNE3,
> +       QUSB2PHY_PORT_TUNE4,
> +       QUSB2PHY_PORT_TUNE5,
> +       QUSB2PHY_PORT_TEST1,
> +       QUSB2PHY_PORT_TEST2,
> +       QUSB2PHY_PORT_POWERDOWN,
> +       QUSB2PHY_INTR_CTRL,
> +};
> +
> +#define QUSB2_PHY_INIT_CFG(o, v)       \
> +       {                              \
> +               .offset = o, .val = v, \
> +       }
> +
> +#define QUSB2_PHY_INIT_CFG_L(o, v)                     \
> +       {                                              \
> +               .offset = o, .val = v, .in_layout = 1, \
> +       }
> +
> +static const struct qusb2_phy_init_tbl sm6115_init_tbl[] = {
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x81),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x17),
> +
> +       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 unsigned int sm6115_regs_layout[] = {
> +       [QUSB2PHY_PLL_STATUS] = 0x38,     [QUSB2PHY_PORT_TUNE1] = 0x80,
> +       [QUSB2PHY_PORT_TUNE2] = 0x84,     [QUSB2PHY_PORT_TUNE3] = 0x88,
> +       [QUSB2PHY_PORT_TUNE4] = 0x8c,     [QUSB2PHY_PORT_TUNE5] = 0x90,
> +       [QUSB2PHY_PORT_TEST1] = 0xb8,     [QUSB2PHY_PORT_TEST2] = 0x9c,
> +       [QUSB2PHY_PORT_POWERDOWN] = 0xb4, [QUSB2PHY_INTR_CTRL] = 0xbc,
> +};
> +
> +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),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
> +
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
> +       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
> +
> +       QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
> +};
> +
> +static const unsigned int qusb2_v2_regs_layout[] = {
> +       [QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
> +       [QUSB2PHY_PLL_STATUS] = 0x1a0,
> +       [QUSB2PHY_PORT_TUNE1] = 0x240,
> +       [QUSB2PHY_PORT_TUNE2] = 0x244,
> +       [QUSB2PHY_PORT_TUNE3] = 0x248,
> +       [QUSB2PHY_PORT_TUNE4] = 0x24c,
> +       [QUSB2PHY_PORT_TUNE5] = 0x250,
> +       [QUSB2PHY_PORT_TEST1] = 0x254,
> +       [QUSB2PHY_PORT_TEST2] = 0x258,
> +       [QUSB2PHY_PORT_POWERDOWN] = 0x210,
> +       [QUSB2PHY_INTR_CTRL] = 0x230,
> +};
> +
> +static const struct qusb2_phy_cfg sm6115_phy_cfg = {
> +       .tbl = sm6115_init_tbl,
> +       .tbl_num = ARRAY_SIZE(sm6115_init_tbl),
> +       .regs = sm6115_regs_layout,
> +
> +       .has_pll_test = true,
> +       .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
> +       .mask_core_ready = PLL_LOCKED,
> +       .autoresume_en = BIT(3),
> +};
> +
> +static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
> +       .tbl = qusb2_v2_init_tbl,
> +       .tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl),
> +       .regs = qusb2_v2_regs_layout,
> +
> +       .disable_ctrl = (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
> +                        POWER_DOWN),
> +       .mask_core_ready = CORE_READY_STATUS,
> +       .has_pll_override = true,
> +       .autoresume_en = BIT(0),
> +       .update_tune1_with_efuse = true,
> +};
> +
> +/**
> + * struct qusb2_phy - structure holding qusb2 phy attributes
> + *
> + * @phy: generic phy
> + * @base: iomapped memory space for qubs2 phy
> + *
> + * @cfg_ahb_clk: AHB2PHY interface clock
> + * @phy_rst: phy reset control
> + *
> + * @cfg: phy config data
> + * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
> + */
> +struct qusb2_phy {
> +       struct phy *phy;
> +       void __iomem *base;
> +
> +       struct clk cfg_ahb_clk;
> +       struct reset_ctl phy_rst;
> +
> +       const struct qusb2_phy_cfg *cfg;
> +       bool has_se_clk_scheme;
> +};
> +
> +static inline void qusb2_write_mask(void __iomem *base, u32 offset, u32 val,
> +                                   u32 mask)
> +{
> +       u32 reg;
> +
> +       reg = readl(base + offset);
> +       reg &= ~mask;
> +       reg |= val & mask;
> +       writel(reg, base + offset);
> +
> +       /* Ensure above write is completed */
> +       readl(base + offset);
> +}

Function unused?

> +
> +static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
> +{
> +       u32 reg;
> +
> +       reg = readl(base + offset);
> +       reg |= val;
> +       writel(reg, base + offset);
> +
> +       /* Ensure above write is completed */
> +       readl(base + offset);
> +}
> +
> +static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
> +{
> +       u32 reg;
> +
> +       reg = readl(base + offset);
> +       reg &= ~val;
> +       writel(reg, base + offset);
> +
> +       /* Ensure above write is completed */
> +       readl(base + offset);
> +}

Any specific reason to not use setbits_le32() and clrbits_le32() her instead?

> +
> +static inline void qusb2_phy_configure(void __iomem *base,
> +                                      const unsigned int *regs,
> +                                      const struct qusb2_phy_init_tbl tbl[],
> +                                      int num)
> +{
> +       int i;
> +
> +       for (i = 0; i < num; i++) {
> +               if (tbl[i].in_layout)
> +                       writel(tbl[i].val, base + regs[tbl[i].offset]);
> +               else
> +                       writel(tbl[i].val, base + tbl[i].offset);
> +       }
> +}
> +
> +static int qusb2phy_do_reset(struct qusb2_phy *qphy)
> +{
> +       int ret;
> +
> +       ret = reset_assert(&qphy->phy_rst);
> +       if (ret)
> +               return ret;
> +
> +       udelay(10);
> +
> +       ret = reset_deassert(&qphy->phy_rst);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static int qusb2phy_power_on(struct phy *phy)
> +{
> +       struct qusb2_phy *qphy = dev_get_priv(phy->dev);
> +       const struct qusb2_phy_cfg *cfg = qphy->cfg;
> +       int ret;
> +       u32 val;
> +
> +       ret = qusb2phy_do_reset(qphy);
> +       if (ret)
> +               return ret;

Do we really need to reset here? Wouldn't just
reset_deassert(&qphy->phy_rst) be sufficient here instead?

-Sumit

> +
> +       /* Disable the PHY */
> +       qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> +                     qphy->cfg->disable_ctrl);
> +
> +       if (cfg->has_pll_test) {
> +               /* save reset value to override reference clock scheme later */
> +               val = readl(qphy->base + QUSB2PHY_PLL_TEST);
> +       }
> +
> +       qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl, cfg->tbl_num);
> +
> +       /* Enable the PHY */
> +       qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> +                     POWER_DOWN);
> +
> +       /* Required to get phy pll lock successfully */
> +       udelay(150);
> +
> +       if (cfg->has_pll_test) {
> +               val |= CLK_REF_SEL;
> +
> +               writel(val, qphy->base + QUSB2PHY_PLL_TEST);
> +
> +               /* ensure above write is through */
> +               readl(qphy->base + QUSB2PHY_PLL_TEST);
> +       }
> +
> +       /* Required to get phy pll lock successfully */
> +       udelay(100);
> +
> +       val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
> +       if (!(val & cfg->mask_core_ready)) {
> +               pr_err("QUSB2PHY pll lock failed: status reg = %x\n", val);
> +               ret = -EBUSY;
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int qusb2phy_power_off(struct phy *phy)
> +{
> +       struct qusb2_phy *qphy = dev_get_priv(phy->dev);
> +
> +       /* Disable the PHY */
> +       qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
> +                     qphy->cfg->disable_ctrl);
> +
> +       reset_assert(&qphy->phy_rst);
> +
> +       clk_disable(&qphy->cfg_ahb_clk);
> +
> +       return 0;
> +}
> +
> +static int qusb2phy_clk_init(struct udevice *dev, struct qusb2_phy *qphy)
> +{
> +       int ret;
> +
> +       /* We ignore the ref clock as we currently lack a driver for rpmcc/rpmhcc where
> +        * it usually comes from - we assume it's always on.
> +        */
> +       ret = clk_get_by_name(dev, "cfg_ahb", &qphy->cfg_ahb_clk);
> +       if (ret == -ENOSYS || ret == -ENOENT)
> +               return 0;
> +       if (ret)
> +               return ret;
> +
> +       ret = clk_enable(&qphy->cfg_ahb_clk);
> +       if (ret) {
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int qusb2phy_probe(struct udevice *dev)
> +{
> +       struct qusb2_phy *qphy = dev_get_priv(dev);
> +       int ret;
> +
> +       qphy->base = (void __iomem *)dev_read_addr(dev);
> +       if (IS_ERR(qphy->base))
> +               return PTR_ERR(qphy->base);
> +
> +       ret = qusb2phy_clk_init(dev, qphy);
> +       if (ret) {
> +               printf("%s: Couldn't get clocks: %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       ret = reset_get_by_index(dev, 0, &qphy->phy_rst);
> +       if (ret) {
> +               printf("%s: Couldn't get resets: %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       qphy->cfg = (const struct qusb2_phy_cfg *)dev_get_driver_data(dev);
> +       if (!qphy->cfg) {
> +               printf("%s: Couldn't get driver data\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       debug("%s success qusb phy cfg %p\n", __func__, qphy->cfg);
> +       return 0;
> +}
> +
> +static struct phy_ops qusb2phy_ops = {
> +       .power_on = qusb2phy_power_on,
> +       .power_off = qusb2phy_power_off,
> +};
> +
> +static const struct udevice_id qusb2phy_ids[] = {
> +       { .compatible = "qcom,qusb2-phy" },
> +       { .compatible = "qcom,qcm2290-qusb2-phy",
> +         .data = (ulong)&sm6115_phy_cfg },
> +       { .compatible = "qcom,sm6115-qusb2-phy",
> +         .data = (ulong)&sm6115_phy_cfg },
> +       { .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
> +       {}
> +};
> +
> +U_BOOT_DRIVER(qcom_qusb2_phy) = {
> +       .name = "qcom-qusb2-phy",
> +       .id = UCLASS_PHY,
> +       .of_match = qusb2phy_ids,
> +       .ops = &qusb2phy_ops,
> +       .probe = qusb2phy_probe,
> +       .priv_auto = sizeof(struct qusb2_phy),
> +};
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers
  2024-03-19 12:22 ` [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers Caleb Connolly
@ 2024-03-20  5:21   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:21 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Some devices like the UART and clock controller reference an RPM(h)
> power domain. We don't support this device in U-Boot, so add
> DM_FLAG_DEFAULT_PD_CTRL_OFF to tell DM core not to try and enable the
> power domain.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/clk/qcom/clock-qcom.c    | 2 ++
>  drivers/clk/qcom/clock-sdm845.c  | 2 +-
>  drivers/serial/serial_msm_geni.c | 2 +-
>  3 files changed, 4 insertions(+), 2 deletions(-)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>


-Sumit

> diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
> index 7a5938a06a34..6303dcbf8461 100644
> --- a/drivers/clk/qcom/clock-qcom.c
> +++ b/drivers/clk/qcom/clock-qcom.c
> @@ -226,8 +226,9 @@ U_BOOT_DRIVER(qcom_clk) = {
>         .id             = UCLASS_CLK,
>         .ops            = &msm_clk_ops,
>         .priv_auto      = sizeof(struct msm_clk_priv),
>         .probe          = msm_clk_probe,
> +       .flags          = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
>  };
>
>  int qcom_cc_bind(struct udevice *parent)
>  {
> @@ -410,5 +411,6 @@ U_BOOT_DRIVER(qcom_power) = {
>         .name = "qcom_power",
>         .id = UCLASS_POWER_DOMAIN,
>         .ops = &qcom_power_ops,
>         .probe = qcom_power_probe,
> +       .flags = DM_FLAG_PRE_RELOC,
>  };
> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
> index 36ffee79d966..babd83119e2c 100644
> --- a/drivers/clk/qcom/clock-sdm845.c
> +++ b/drivers/clk/qcom/clock-sdm845.c
> @@ -182,6 +182,6 @@ U_BOOT_DRIVER(gcc_sdm845) = {
>         .name           = "gcc_sdm845",
>         .id             = UCLASS_NOP,
>         .of_match       = gcc_sdm845_of_match,
>         .bind           = qcom_cc_bind,
> -       .flags          = DM_FLAG_PRE_RELOC,
> +       .flags          = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
>  };
> diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
> index e5c3dcffc1c6..4aa0bc8c72bc 100644
> --- a/drivers/serial/serial_msm_geni.c
> +++ b/drivers/serial/serial_msm_geni.c
> @@ -602,9 +602,9 @@ U_BOOT_DRIVER(serial_msm_geni) = {
>         .of_to_plat = msm_serial_ofdata_to_platdata,
>         .priv_auto = sizeof(struct msm_serial_data),
>         .probe = msm_serial_probe,
>         .ops = &msm_serial_ops,
> -       .flags = DM_FLAG_PRE_RELOC,
> +       .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
>  };
>
>  #ifdef CONFIG_DEBUG_UART_MSM_GENI
>
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 03/14] phy: qcom: Add USB HS 7nm PHY driver
  2024-03-19 12:22 ` [PATCH v3 03/14] phy: qcom: Add USB HS 7nm " Caleb Connolly
@ 2024-03-20  5:37   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:37 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot,
	Bhupesh Sharma

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> From: Bhupesh Sharma <bhupesh.linux@gmail.com>
>
> Some Qualcomm SoCs newer than SDM845 feature a so-called "7nm phy"
> driver, notable the SM8250 SoC which will gain U-Boot support in
> upcoming patches.
>
> Introduce a driver based on the Linux driver.
>
> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
> [code cleanup, switch to clk/reset_bulk APIs]
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/phy/qcom/Kconfig               |   8 +
>  drivers/phy/qcom/Makefile              |   1 +
>  drivers/phy/qcom/phy-qcom-usb-hs-7nm.c | 295 +++++++++++++++++++++++++++++++++
>  3 files changed, 304 insertions(+)
>
> diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
> index 361dfb6e1126..3fc59dc65650 100644
> --- a/drivers/phy/qcom/Kconfig
> +++ b/drivers/phy/qcom/Kconfig
> @@ -18,8 +18,16 @@ config PHY_QCOM_QUSB2
>         help
>           Enable this to support the Super-Speed USB transceiver on various
>           Qualcomm chipsets.
>
> +config PHY_QCOM_USB_HS_7NM
> +       tristate "Qualcomm 7nm High-Speed PHY"
> +       depends on PHY && ARCH_SNAPDRAGON
> +       help
> +         Enable this to support the Qualcomm Synopsys DesignWare Core 7nm
> +         High-Speed PHY driver. This driver supports the Hi-Speed PHY which
> +         is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
> +
>  config PHY_QCOM_USB_HS_28NM
>         tristate "Qualcomm 28nm High-Speed PHY"
>         depends on PHY && ARCH_SNAPDRAGON
>         help
> diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile
> index f6af985666a4..39219ecd24aa 100644
> --- a/drivers/phy/qcom/Makefile
> +++ b/drivers/phy/qcom/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
>  obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
>  obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
> +obj-$(CONFIG_PHY_QCOM_USB_HS_7NM) += phy-qcom-usb-hs-7nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o
> diff --git a/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c b/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c
> new file mode 100644
> index 000000000000..65128b45937b
> --- /dev/null
> +++ b/drivers/phy/qcom/phy-qcom-usb-hs-7nm.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2023 Bhupesh Sharma <bhupesh.sharma@linaro.org>
> + *
> + * Based on Linux driver
> + */
> +
> +#include <clk.h>
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <dm/devres.h>
> +#include <generic-phy.h>
> +#include <malloc.h>
> +#include <reset.h>
> +
> +#include <asm/io.h>
> +#include <linux/bitops.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/iopoll.h>
> +
> +#define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c)
> +#define SLEEPM BIT(0)
> +#define OPMODE_MASK GENMASK(4, 3)
> +#define OPMODE_NORMAL (0x00)
> +#define OPMODE_NONDRIVING BIT(3)
> +#define TERMSEL BIT(5)
> +
> +#define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40)

Drop unused macros. Check other macros too below if all of them are being used.

> +#define XCVRSEL BIT(0)
> +
> +#define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50)
> +#define POR BIT(1)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
> +#define SIDDQ BIT(2)
> +#define RETENABLEN BIT(3)
> +#define FSEL_MASK GENMASK(6, 4)
> +#define FSEL_DEFAULT (0x3 << 4)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58)
> +#define VBUSVLDEXTSEL0 BIT(4)
> +#define PLLBTUNE BIT(5)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2 (0x5c)
> +#define VREGBYPASS BIT(0)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_CTRL1 (0x60)
> +#define VBUSVLDEXT0 BIT(0)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_CTRL2 (0x64)
> +#define USB2_AUTO_RESUME BIT(0)
> +#define USB2_SUSPEND_N BIT(2)
> +#define USB2_SUSPEND_N_SEL BIT(3)
> +
> +#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X0 (0x6c)
> +#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1 (0x70)
> +#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X2 (0x74)
> +#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X3 (0x78)
> +#define PARAM_OVRD_MASK 0xFF
> +
> +#define USB2_PHY_USB_PHY_CFG0 (0x94)
> +#define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0)
> +#define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1)
> +
> +#define USB2_PHY_USB_PHY_REFCLK_CTRL (0xa0)
> +#define REFCLK_SEL_MASK GENMASK(1, 0)
> +#define REFCLK_SEL_DEFAULT (0x2 << 0)
> +
> +#define HS_DISCONNECT_MASK GENMASK(2, 0)
> +#define SQUELCH_DETECTOR_MASK GENMASK(7, 5)
> +
> +#define HS_AMPLITUDE_MASK GENMASK(3, 0)
> +#define PREEMPHASIS_DURATION_MASK BIT(5)
> +#define PREEMPHASIS_AMPLITUDE_MASK GENMASK(7, 6)
> +
> +#define HS_RISE_FALL_MASK GENMASK(1, 0)
> +#define HS_CROSSOVER_VOLTAGE_MASK GENMASK(3, 2)
> +#define HS_OUTPUT_IMPEDANCE_MASK GENMASK(5, 4)
> +
> +#define LS_FS_OUTPUT_IMPEDANCE_MASK GENMASK(3, 0)
> +
> +#define SNPS_HS_NUM_VREGS ARRAY_SIZE(hs_7nm_vreg_names)
> +
> +struct override_param {
> +       s32 value;
> +       u8 reg_val;
> +};
> +
> +struct override_param_map {
> +       const char *prop_name;
> +       const struct override_param *param_table;
> +       u8 table_size;
> +       u8 reg_offset;
> +       u8 param_mask;
> +};
> +
> +struct phy_override_seq {
> +       bool need_update;
> +       u8 offset;
> +       u8 value;
> +       u8 mask;
> +};
> +
> +#define NUM_HSPHY_TUNING_PARAMS (9)
> +
> +/* struct hs_7nm_phy_cfg - per-PHY initialization config */
> +struct hs_7nm_phy_cfg {
> +       /* resets to be requested */

If you want to put these comments then a better format is to use
kernel doc style comments.

> +       struct reset_ctl *resets;
> +       int num_resets;
> +

redundant newline?

> +       struct override_param_map *map_cfg;
> +       struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS];
> +};
> +
> +/**
> + * struct hs_7nm_phy_priv - snps hs phy attributes
> + */
> +struct hs_7nm_phy_priv {
> +       void __iomem *base;
> +

redundant newline, here and below?

> +       /* clocks to be requested */

Ditto.

> +       struct clk_bulk clks;
> +
> +       /* resets to be requested */
> +       struct reset_ctl_bulk resets;
> +
> +       struct hs_7nm_phy_cfg *cfg;
> +};
> +
> +static inline void hs_7nm_write_mask(void __iomem *base, u32 offset, u32 mask,
> +                                    u32 val)
> +{
> +       u32 reg;
> +
> +       reg = readl_relaxed(base + offset);
> +
> +       reg &= ~mask;
> +       reg |= val & mask;
> +       writel_relaxed(reg, base + offset);
> +
> +       /* Ensure above write is completed */
> +       readl_relaxed(base + offset);
> +}

I think it's better to reuse setbits_le32() and clrbits_le32() here too.

> +
> +static int hs_7nm_usb_init(struct phy *phy)
> +{
> +       struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_CFG0,
> +                         UTMI_PHY_CMN_CTRL_OVERRIDE_EN,
> +                         UTMI_PHY_CMN_CTRL_OVERRIDE_EN);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
> +                         FSEL_MASK, 0);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
> +                         PLLBTUNE, PLLBTUNE);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_REFCLK_CTRL,
> +                         REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
> +                         VBUSVLDEXTSEL0, VBUSVLDEXTSEL0);
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1,
> +                         VBUSVLDEXT0, VBUSVLDEXT0);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
> +                         VREGBYPASS, VREGBYPASS);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
> +                         USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
> +                         USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL0, SLEEPM,
> +                         SLEEPM);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
> +                         SIDDQ, 0);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_UTMI_CTRL5, POR, 0);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
> +                         USB2_SUSPEND_N_SEL, 0);
> +
> +       hs_7nm_write_mask(hs_7nm->base, USB2_PHY_USB_PHY_CFG0,
> +                         UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0);
> +
> +       return 0;
> +}
> +
> +static int hs_7nm_phy_power_on(struct phy *phy)
> +{
> +       struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
> +       int ret;
> +
> +       clk_enable_bulk(&hs_7nm->clks);
> +
> +       ret = reset_deassert_bulk(&hs_7nm->resets);
> +       if (ret)
> +               return ret;
> +
> +       ret = hs_7nm_usb_init(phy);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static int hs_7nm_phy_power_off(struct phy *phy)
> +{
> +       struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(phy->dev);
> +
> +       reset_assert_bulk(&hs_7nm->resets);
> +       clk_disable_bulk(&hs_7nm->clks);
> +
> +       return 0;
> +}
> +
> +static int hs_7nm_phy_clk_init(struct udevice *dev,
> +                              struct hs_7nm_phy_priv *hs_7nm)
> +{
> +       int ret;
> +
> +       ret = clk_get_bulk(dev, &hs_7nm->clks);
> +       /* We may have no clocks */

redundant comment?

> +       if (ret == -ENOENT) {
> +               debug("%s: no clocks\n", __func__);
> +               return 0;
> +       }
> +       if (ret < 0) {
> +               printf("%s: Failed to get clocks %d\n", __func__, ret);
> +               return ret;
> +       }

redundant error checking?

> +
> +       return 0;
> +}
> +
> +static int hs_7nm_phy_probe(struct udevice *dev)
> +{
> +       struct hs_7nm_phy_priv *hs_7nm = dev_get_priv(dev);
> +       int ret;
> +
> +       hs_7nm->base = (void __iomem *)dev_read_addr(dev);

Use dev_read_addr_ptr() instead.

> +       if (IS_ERR(hs_7nm->base))
> +               return PTR_ERR(hs_7nm->base);
> +
> +       hs_7nm->cfg = (struct hs_7nm_phy_cfg *)dev_get_driver_data(dev);
> +
> +       ret = hs_7nm_phy_clk_init(dev, hs_7nm);

I would rather make it inline to directly invoke clk_get_bulk() here.

> +       if (ret) {
> +               printf("%s: hs_7nm_phy_clk_init %d\n", __func__, ret);
> +               return ret;
> +       }
> +
> +       ret = reset_get_bulk(dev, &hs_7nm->resets);
> +       if (ret < 0) {
> +               printf("failed to get resets, ret = %d\n", ret);
> +               return ret;
> +       }
> +
> +       clk_enable_bulk(&hs_7nm->clks);
> +       reset_deassert_bulk(&hs_7nm->resets);
> +
> +       return 0;
> +}
> +
> +static struct phy_ops hs_7nm_phy_ops = {
> +       .power_on = hs_7nm_phy_power_on,
> +       .power_off = hs_7nm_phy_power_off,
> +};
> +
> +static const struct udevice_id hs_7nm_phy_ids[] = {
> +       {
> +               .compatible = "qcom,sm8150-usb-hs-phy",
> +       },
> +       {
> +               .compatible = "qcom,usb-snps-hs-5nm-phy",
> +       },
> +       {
> +               .compatible = "qcom,usb-snps-hs-7nm-phy",
> +       },
> +       {
> +               .compatible = "qcom,usb-snps-femto-v2-phy",
> +       },
> +       {}
> +};

I would rather write above as:

    static const struct udevice_id hs_7nm_phy_ids[] = {
        { .compatible = "qcom,sm8150-usb-hs-phy" },
        { .compatible = "qcom,usb-snps-hs-5nm-phy" },
        { .compatible = "qcom,usb-snps-hs-7nm-phy" },
        { .compatible = "qcom,usb-snps-femto-v2-phy" },
        { }
    };

-Sumit

> +
> +U_BOOT_DRIVER(qcom_usb_hs_7nm) = {
> +       .name = "qcom-usb-hs-7nm",
> +       .id = UCLASS_PHY,
> +       .of_match = hs_7nm_phy_ids,
> +       .ops = &hs_7nm_phy_ops,
> +       .probe = hs_7nm_phy_probe,
> +       .priv_auto = sizeof(struct hs_7nm_phy_priv),
> +};
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 14/14] qcom_defconfig: enable USB
  2024-03-19 12:22 ` [PATCH v3 14/14] qcom_defconfig: enable USB Caleb Connolly
@ 2024-03-20  5:40   ` Sumit Garg
  2024-03-20 13:16     ` Caleb Connolly
  0 siblings, 1 reply; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:40 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Enable support for the DWC3 USB controller and required dependencies for
> Qualcomm boards, specifically the DB845c:
> * IOMMU / SMMU
> * USB high-speed PHYs
> * Mass storage and ACM gadgets
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  configs/qcom_defconfig | 49 ++++++++++++++++++++++++++-----------------------
>  1 file changed, 26 insertions(+), 23 deletions(-)
>
> diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
> index eebd0d74bd51..156c205284dd 100644
> --- a/configs/qcom_defconfig
> +++ b/configs/qcom_defconfig
> @@ -12,42 +12,63 @@ CONFIG_BOOTSTD_FULL=y
>  CONFIG_BOOTDELAY=1
>  CONFIG_USE_PREBOOT=y
>  CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
>  CONFIG_SYS_CBSIZE=512
> +# CONFIG_SYS_DEVICE_NULLDEV is not set
>  CONFIG_LOG_MAX_LEVEL=9
>  CONFIG_LOG_DEFAULT_LEVEL=4
>  # CONFIG_DISPLAY_CPUINFO is not set
>  CONFIG_DISPLAY_BOARDINFO_LATE=y
>  CONFIG_CMD_BOOTMENU=y
> +CONFIG_CMD_EEPROM=y
> +CONFIG_SYS_I2C_EEPROM_BUS=2
> +CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
> +CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
> +# CONFIG_CMD_BIND is not set
>  CONFIG_CMD_CLK=y
>  CONFIG_CMD_GPIO=y
> +CONFIG_CMD_I2C=y
>  CONFIG_CMD_MMC=y
>  CONFIG_CMD_UFS=y
>  CONFIG_CMD_USB=y
>  CONFIG_CMD_CAT=y
>  CONFIG_CMD_BMP=y
>  CONFIG_CMD_LOG=y
>  CONFIG_OF_LIVE=y
>  # CONFIG_NET is not set
> +CONFIG_DM_WARN=y
>  # CONFIG_OFNODE_MULTI_TREE is not set
>  CONFIG_BUTTON_QCOM_PMIC=y
>  CONFIG_CLK=y
>  CONFIG_CLK_QCOM_QCS404=y
>  CONFIG_CLK_QCOM_SDM845=y
>  CONFIG_MSM_GPIO=y
>  CONFIG_QCOM_PMIC_GPIO=y
> +CONFIG_DM_I2C=y
> +CONFIG_SYS_I2C_QUP=y
> +CONFIG_I2C_MUX=y
>  CONFIG_DM_KEYBOARD=y
>  CONFIG_BUTTON_KEYBOARD=y
> +CONFIG_IOMMU=y
> +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
> +CONFIG_DM_ETH_PHY=y
>  CONFIG_PHY=y
> +CONFIG_PHY_QCOM_QUSB2=y
> +CONFIG_PHY_QCOM_USB_HS_7NM=y
>  CONFIG_PINCTRL=y
>  CONFIG_PINCTRL_QCOM_QCS404=y
>  CONFIG_PINCTRL_QCOM_SDM845=y
>  CONFIG_DM_PMIC=y
>  CONFIG_PMIC_QCOM=y
> +CONFIG_DM_REGULATOR=y
> +CONFIG_DM_REGULATOR_FIXED=y
>  CONFIG_SCSI=y
>  CONFIG_MSM_SERIAL=y
>  CONFIG_MSM_GENI_SERIAL=y
>  CONFIG_SPMI_MSM=y
> @@ -56,8 +77,13 @@ CONFIG_SYSINFO_SMBIOS=y
>  CONFIG_USB=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_DWC3=y
>  CONFIG_USB_DWC3=y
> +CONFIG_USB_DWC3_GENERIC=y
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_GADGET_DOWNLOAD=y
> +CONFIG_USB_FUNCTION_MASS_STORAGE=y
> +CONFIG_USB_FUNCTION_ACM=y
>  CONFIG_UFS=y
>  CONFIG_VIDEO=y
>  # CONFIG_VIDEO_FONT_8X16 is not set
>  CONFIG_VIDEO_FONT_16X32=y
> @@ -66,27 +92,4 @@ CONFIG_NO_FB_CLEAR=y
>  CONFIG_VIDEO_SIMPLE=y
>  CONFIG_HEXDUMP=y
>  # CONFIG_GENERATE_SMBIOS_TABLE is not set
>  CONFIG_LMB_MAX_REGIONS=64
> -CONFIG_CMD_DHCP=y
> -CONFIG_CMD_EEPROM=y
> -CONFIG_CMD_I2C=y
> -CONFIG_CMD_PING=y
> -CONFIG_DM_ETH=y
> -CONFIG_DM_ETH_PHY=y
> -CONFIG_DM_MDIO=y
> -CONFIG_DWC_ETH_QOS=y
> -CONFIG_DWC_ETH_QOS_QCOM=y

Any particular reason to drop these?

-Sumit

> -CONFIG_RGMII=y
> -CONFIG_PHY_MICREL=y
> -CONFIG_PHY_MICREL_KSZ90X1=y
> -CONFIG_MISC=y
> -CONFIG_NVMEM=y
> -CONFIG_DM_I2C=y
> -CONFIG_I2C_SUPPORT=y
> -CONFIG_I2C_MUX=y
> -CONFIG_I2C_EEPROM=y
> -CONFIG_SYS_I2C=y
> -CONFIG_SYS_I2C_QUP=y
> -CONFIG_SYS_I2C_EEPROM_BUS=2
> -CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
> -CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 05/14] clk/qcom: use offsets for RCG registers
  2024-03-19 12:22 ` [PATCH v3 05/14] clk/qcom: use offsets for RCG registers Caleb Connolly
@ 2024-03-20  5:42   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:42 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> The RCG registers always have the same offsets, so only store the base
> CMD register address and calculate the others relative to that.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/clk/qcom/clock-apq8016.c |  39 +------------
>  drivers/clk/qcom/clock-apq8096.c |  28 +--------
>  drivers/clk/qcom/clock-qcom.c    |  22 +++----
>  drivers/clk/qcom/clock-qcom.h    |  16 +++---
>  drivers/clk/qcom/clock-qcs404.c  | 121 +++++----------------------------------
>  drivers/clk/qcom/clock-sdm845.c  |  16 +-----
>  6 files changed, 39 insertions(+), 203 deletions(-)
>
> diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c
> index e6647f7c41dd..5a5868169c89 100644
> --- a/drivers/clk/qcom/clock-apq8016.c
> +++ b/drivers/clk/qcom/clock-apq8016.c
> @@ -22,13 +22,9 @@
>  #define APCS_GPLL_ENA_VOTE             (0x45000)
>  #define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
>
>  #define SDCC_BCR(n)                    ((n * 0x1000) + 0x41000)
> -#define SDCC_CMD_RCGR(n)               ((n * 0x1000) + 0x41004)
> -#define SDCC_CFG_RCGR(n)               ((n * 0x1000) + 0x41008)
> -#define SDCC_M(n)                      ((n * 0x1000) + 0x4100C)
> -#define SDCC_N(n)                      ((n * 0x1000) + 0x41010)
> -#define SDCC_D(n)                      ((n * 0x1000) + 0x41014)
> +#define SDCC_CMD_RCGR(n)               (((n + 1) * 0x1000) + 0x41004)
>  #define SDCC_APPS_CBCR(n)              ((n * 0x1000) + 0x41018)
>  #define SDCC_AHB_CBCR(n)               ((n * 0x1000) + 0x4101C)
>
>  /* BLSP1 AHB clock (root clock for BLSP) */
> @@ -37,33 +33,12 @@
>  /* Uart clock control registers */
>  #define BLSP1_UART2_BCR                        (0x3028)
>  #define BLSP1_UART2_APPS_CBCR          (0x302C)
>  #define BLSP1_UART2_APPS_CMD_RCGR      (0x3034)
> -#define BLSP1_UART2_APPS_CFG_RCGR      (0x3038)
> -#define BLSP1_UART2_APPS_M             (0x303C)
> -#define BLSP1_UART2_APPS_N             (0x3040)
> -#define BLSP1_UART2_APPS_D             (0x3044)
>
>  /* GPLL0 clock control registers */
>  #define GPLL0_STATUS_ACTIVE BIT(17)
>
> -static const struct bcr_regs sdc_regs[] = {
> -       {
> -       .cfg_rcgr = SDCC_CFG_RCGR(1),
> -       .cmd_rcgr = SDCC_CMD_RCGR(1),
> -       .M = SDCC_M(1),
> -       .N = SDCC_N(1),
> -       .D = SDCC_D(1),
> -       },
> -       {
> -       .cfg_rcgr = SDCC_CFG_RCGR(2),
> -       .cmd_rcgr = SDCC_CMD_RCGR(2),
> -       .M = SDCC_M(2),
> -       .N = SDCC_N(2),
> -       .D = SDCC_D(2),
> -       }
> -};
> -
>  static struct pll_vote_clk gpll0_vote_clk = {
>         .status = GPLL0_STATUS,
>         .status_bit = GPLL0_STATUS_ACTIVE,
>         .ena_vote = APCS_GPLL_ENA_VOTE,
> @@ -85,32 +60,24 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
>                 div = 4;
>
>         clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
>         /* 800Mhz/div, gpll0 */
> -       clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
> +       clk_rcg_set_rate_mnd(priv->base, SDCC_CMD_RCGR(slot), div, 0, 0,
>                              CFG_CLK_SRC_GPLL0, 8);
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>         clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
>
>         return rate;
>  }
>
> -static const struct bcr_regs uart2_regs = {
> -       .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
> -       .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
> -       .M = BLSP1_UART2_APPS_M,
> -       .N = BLSP1_UART2_APPS_N,
> -       .D = BLSP1_UART2_APPS_D,
> -};
> -
>  /* UART: 115200 */
>  int apq8016_clk_init_uart(phys_addr_t base)
>  {
>         /* Enable AHB clock */
>         clk_enable_vote_clk(base, &gcc_blsp1_ahb_clk);
>
>         /* 7372800 uart block clock @ GPLL0 */
> -       clk_rcg_set_rate_mnd(base, &uart2_regs, 1, 144, 15625,
> +       clk_rcg_set_rate_mnd(base, BLSP1_UART2_APPS_CMD_RCGR, 1, 144, 15625,
>                              CFG_CLK_SRC_GPLL0, 16);
>
>         /* Vote for gpll0 clock */
>         clk_enable_gpll0(base, &gpll0_vote_clk);
> diff --git a/drivers/clk/qcom/clock-apq8096.c b/drivers/clk/qcom/clock-apq8096.c
> index a4731613c5e0..479f9771a464 100644
> --- a/drivers/clk/qcom/clock-apq8096.c
> +++ b/drivers/clk/qcom/clock-apq8096.c
> @@ -25,33 +25,17 @@
>  #define SDCC2_BCR                      (0x14000) /* block reset */
>  #define SDCC2_APPS_CBCR                        (0x14004) /* branch control */
>  #define SDCC2_AHB_CBCR                 (0x14008)
>  #define SDCC2_CMD_RCGR                 (0x14010)
> -#define SDCC2_CFG_RCGR                 (0x14014)
> -#define SDCC2_M                                (0x14018)
> -#define SDCC2_N                                (0x1401C)
> -#define SDCC2_D                                (0x14020)
>
>  #define BLSP2_AHB_CBCR                 (0x25004)
>  #define BLSP2_UART2_APPS_CBCR          (0x29004)
>  #define BLSP2_UART2_APPS_CMD_RCGR      (0x2900C)
> -#define BLSP2_UART2_APPS_CFG_RCGR      (0x29010)
> -#define BLSP2_UART2_APPS_M             (0x29014)
> -#define BLSP2_UART2_APPS_N             (0x29018)
> -#define BLSP2_UART2_APPS_D             (0x2901C)
>
>  /* GPLL0 clock control registers */
>  #define GPLL0_STATUS_ACTIVE            BIT(30)
>  #define APCS_GPLL_ENA_VOTE_GPLL0       BIT(0)
>
> -static const struct bcr_regs sdc_regs = {
> -       .cfg_rcgr = SDCC2_CFG_RCGR,
> -       .cmd_rcgr = SDCC2_CMD_RCGR,
> -       .M = SDCC2_M,
> -       .N = SDCC2_N,
> -       .D = SDCC2_D,
> -};
> -
>  static const struct pll_vote_clk gpll0_vote_clk = {
>         .status = GPLL0_STATUS,
>         .status_bit = GPLL0_STATUS_ACTIVE,
>         .ena_vote = APCS_GPLL_ENA_VOTE,
> @@ -68,31 +52,23 @@ static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
>  {
>         int div = 5;
>
>         clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
> -       clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
> +       clk_rcg_set_rate_mnd(priv->base, SDCC2_CMD_RCGR, div, 0, 0,
>                              CFG_CLK_SRC_GPLL0, 8);
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>         clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
>
>         return rate;
>  }
>
> -static const struct bcr_regs uart2_regs = {
> -       .cfg_rcgr = BLSP2_UART2_APPS_CFG_RCGR,
> -       .cmd_rcgr = BLSP2_UART2_APPS_CMD_RCGR,
> -       .M = BLSP2_UART2_APPS_M,
> -       .N = BLSP2_UART2_APPS_N,
> -       .D = BLSP2_UART2_APPS_D,
> -};
> -
>  static int clk_init_uart(struct msm_clk_priv *priv)
>  {
>         /* Enable AHB clock */
>         clk_enable_vote_clk(priv->base, &gcc_blsp2_ahb_clk);
>
>         /* 7372800 uart block clock @ GPLL0 */
> -       clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 192, 15625,
> +       clk_rcg_set_rate_mnd(priv->base, BLSP2_UART2_APPS_CMD_RCGR, 1, 192, 15625,
>                              CFG_CLK_SRC_GPLL0, 16);
>
>         /* Vote for gpll0 clock */
>         clk_enable_gpll0(priv->base, &gpll0_vote_clk);
> diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
> index 6303dcbf8461..05e5ab7d094b 100644
> --- a/drivers/clk/qcom/clock-qcom.c
> +++ b/drivers/clk/qcom/clock-qcom.c
> @@ -103,9 +103,9 @@ void clk_bcr_update(phys_addr_t apps_cmd_rcgr)
>  /*
>   * root set rate for clocks with half integer and MND divider
>   * div should be pre-calculated ((div * 2) - 1)
>   */
> -void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
> +void clk_rcg_set_rate_mnd(phys_addr_t base, uint32_t cmd_rcgr,
>                           int div, int m, int n, int source, u8 mnd_width)
>  {
>         u32 cfg;
>         /* M value for MND divider. */
> @@ -119,14 +119,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>
>         debug("m %#x n %#x d %#x div %#x mask %#x\n", m_val, n_val, d_val, div, mask);
>
>         /* Program MND values */
> -       writel(m_val & mask, base + regs->M);
> -       writel(n_val & mask, base + regs->N);
> -       writel(d_val & mask, base + regs->D);
> +       writel(m_val & mask, base + cmd_rcgr + RCG_M_REG);
> +       writel(n_val & mask, base + cmd_rcgr + RCG_N_REG);
> +       writel(d_val & mask, base + cmd_rcgr + RCG_D_REG);
>
>         /* setup src select and divider */
> -       cfg  = readl(base + regs->cfg_rcgr);
> +       cfg  = readl(base + cmd_rcgr + RCG_CFG_REG);
>         cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK |
>                  CFG_SRC_DIV_MASK);
>         cfg |= source & CFG_SRC_SEL_MASK; /* Select clock source */
>
> @@ -135,22 +135,22 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
>
>         if (n && n != m)
>                 cfg |= CFG_MODE_DUAL_EDGE;
>
> -       writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
> +       writel(cfg, base + cmd_rcgr + RCG_CFG_REG); /* Write new clock configuration */
>
>         /* Inform h/w to start using the new config. */
> -       clk_bcr_update(base + regs->cmd_rcgr);
> +       clk_bcr_update(base + cmd_rcgr);
>  }
>
>  /* root set rate for clocks with half integer and mnd_width=0 */
> -void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
> +void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
>                       int source)
>  {
>         u32 cfg;
>
>         /* setup src select and divider */
> -       cfg  = readl(base + regs->cfg_rcgr);
> +       cfg  = readl(base + cmd_rcgr + RCG_CFG_REG);
>         cfg &= ~(CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK);
>         cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
>
>         /*
> @@ -159,12 +159,12 @@ void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
>          */
>         if (div)
>                 cfg |= (2 * div - 1) & CFG_SRC_DIV_MASK;
>
> -       writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
> +       writel(cfg, base + cmd_rcgr + RCG_CFG_REG); /* Write new clock configuration */
>
>         /* Inform h/w to start using the new config. */
> -       clk_bcr_update(base + regs->cmd_rcgr);
> +       clk_bcr_update(base + cmd_rcgr);
>  }
>
>  const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
>  {
> diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h
> index 12a1eaec2b2e..a7f833a4b6dd 100644
> --- a/drivers/clk/qcom/clock-qcom.h
> +++ b/drivers/clk/qcom/clock-qcom.h
> @@ -11,8 +11,13 @@
>  #define CFG_CLK_SRC_GPLL0 (1 << 8)
>  #define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
>  #define CFG_CLK_SRC_MASK  (7 << 8)
>
> +#define RCG_CFG_REG            0x4
> +#define RCG_M_REG              0x8
> +#define RCG_N_REG              0xc
> +#define RCG_D_REG              0x10
> +
>  struct pll_vote_clk {
>         uintptr_t status;
>         int status_bit;
>         uintptr_t ena_vote;
> @@ -23,15 +28,8 @@ struct vote_clk {
>         uintptr_t cbcr_reg;
>         uintptr_t ena_vote;
>         int vote_bit;
>  };
> -struct bcr_regs {
> -       uintptr_t cfg_rcgr;
> -       uintptr_t cmd_rcgr;
> -       uintptr_t M;
> -       uintptr_t N;
> -       uintptr_t D;
> -};
>
>  struct freq_tbl {
>         uint freq;
>         uint src;
> @@ -87,11 +85,11 @@ void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
>  void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
>  void clk_enable_cbc(phys_addr_t cbcr);
>  void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
>  const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate);
> -void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
> +void clk_rcg_set_rate_mnd(phys_addr_t base, uint32_t cmd_rcgr,
>                           int div, int m, int n, int source, u8 mnd_width);
> -void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,
> +void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div,
>                       int source);
>
>  static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
>  {
> diff --git a/drivers/clk/qcom/clock-qcs404.c b/drivers/clk/qcom/clock-qcs404.c
> index 958312b88842..64a0a2d36754 100644
> --- a/drivers/clk/qcom/clock-qcs404.c
> +++ b/drivers/clk/qcom/clock-qcs404.c
> @@ -27,37 +27,24 @@
>  /* Uart clock control registers */
>  #define BLSP1_UART2_BCR                        (0x3028)
>  #define BLSP1_UART2_APPS_CBCR          (0x302C)
>  #define BLSP1_UART2_APPS_CMD_RCGR      (0x3034)
> -#define BLSP1_UART2_APPS_CFG_RCGR      (0x3038)
> -#define BLSP1_UART2_APPS_M             (0x303C)
> -#define BLSP1_UART2_APPS_N             (0x3040)
> -#define BLSP1_UART2_APPS_D             (0x3044)
>
>  /* I2C controller clock control registerss */
>  #define BLSP1_QUP0_I2C_APPS_CBCR       (0x6028)
>  #define BLSP1_QUP0_I2C_APPS_CMD_RCGR   (0x602C)
> -#define BLSP1_QUP0_I2C_APPS_CFG_RCGR   (0x6030)
>  #define BLSP1_QUP1_I2C_APPS_CBCR       (0x2008)
>  #define BLSP1_QUP1_I2C_APPS_CMD_RCGR   (0x200C)
> -#define BLSP1_QUP1_I2C_APPS_CFG_RCGR   (0x2010)
>  #define BLSP1_QUP2_I2C_APPS_CBCR       (0x3010)
>  #define BLSP1_QUP2_I2C_APPS_CMD_RCGR   (0x3000)
> -#define BLSP1_QUP2_I2C_APPS_CFG_RCGR   (0x3004)
>  #define BLSP1_QUP3_I2C_APPS_CBCR       (0x4020)
>  #define BLSP1_QUP3_I2C_APPS_CMD_RCGR   (0x4000)
> -#define BLSP1_QUP3_I2C_APPS_CFG_RCGR   (0x4004)
>  #define BLSP1_QUP4_I2C_APPS_CBCR       (0x5020)
>  #define BLSP1_QUP4_I2C_APPS_CMD_RCGR   (0x5000)
> -#define BLSP1_QUP4_I2C_APPS_CFG_RCGR   (0x5004)
>
>  /* SD controller clock control registers */
>  #define SDCC_BCR(n)                    (((n) * 0x1000) + 0x41000)
> -#define SDCC_CMD_RCGR(n)               (((n) * 0x1000) + 0x41004)
> -#define SDCC_CFG_RCGR(n)               (((n) * 0x1000) + 0x41008)
> -#define SDCC_M(n)                      (((n) * 0x1000) + 0x4100C)
> -#define SDCC_N(n)                      (((n) * 0x1000) + 0x41010)
> -#define SDCC_D(n)                      (((n) * 0x1000) + 0x41014)
> +#define SDCC_CMD_RCGR(n)               (((n + 1) * 0x1000) + 0x41004)
>  #define SDCC_APPS_CBCR(n)              (((n) * 0x1000) + 0x41018)
>  #define SDCC_AHB_CBCR(n)               (((n) * 0x1000) + 0x4101C)
>
>  /* USB-3.0 controller clock control registers */
> @@ -69,12 +56,8 @@
>  #define USB30_MOCK_UTMI_CBCR           (0x39014)
>  #define USB30_MOCK_UTMI_CMD_RCGR       (0x3901C)
>  #define USB30_MOCK_UTMI_CFG_RCGR       (0x39020)
>  #define USB30_MASTER_CMD_RCGR          (0x39028)
> -#define USB30_MASTER_CFG_RCGR          (0x3902C)
> -#define USB30_MASTER_M                 (0x39030)
> -#define USB30_MASTER_N                 (0x39034)
> -#define USB30_MASTER_D                 (0x39038)
>  #define USB2A_PHY_SLEEP_CBCR           (0x4102C)
>  #define USB_HS_PHY_CFG_AHB_CBCR                (0x41030)
>
>  /* ETH controller clock control registers */
> @@ -84,12 +67,8 @@
>  #define ETH_AXI_CBCR                   (0x4e010)
>  #define EMAC_PTP_CMD_RCGR              (0x4e014)
>  #define EMAC_PTP_CFG_RCGR              (0x4e018)

You forgot to remove this. With that fixed:

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

-Sumit

>  #define EMAC_CMD_RCGR                  (0x4e01c)
> -#define EMAC_CFG_RCGR                  (0x4e020)
> -#define EMAC_M                         (0x4e024)
> -#define EMAC_N                         (0x4e028)
> -#define EMAC_D                         (0x4e02c)
>
>
>  /* GPLL0 clock control registers */
>  #define GPLL0_STATUS_ACTIVE BIT(31)
> @@ -102,24 +81,8 @@ static struct vote_clk gcc_blsp1_ahb_clk = {
>         .ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
>         .vote_bit = BIT(10) | BIT(5) | BIT(4),
>  };
>
> -static const struct bcr_regs uart2_regs = {
> -       .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
> -       .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
> -       .M = BLSP1_UART2_APPS_M,
> -       .N = BLSP1_UART2_APPS_N,
> -       .D = BLSP1_UART2_APPS_D,
> -};
> -
> -static const struct bcr_regs sdc_regs = {
> -       .cfg_rcgr = SDCC_CFG_RCGR(1),
> -       .cmd_rcgr = SDCC_CMD_RCGR(1),
> -       .M = SDCC_M(1),
> -       .N = SDCC_N(1),
> -       .D = SDCC_D(1),
> -};
> -
>  static struct pll_vote_clk gpll0_vote_clk = {
>         .status = GPLL0_STATUS,
>         .status_bit = GPLL0_STATUS_ACTIVE,
>         .ena_vote = APCS_GPLL_ENA_VOTE,
> @@ -132,92 +95,38 @@ static struct pll_vote_clk gpll1_vote_clk = {
>         .ena_vote = APCS_GPLL_ENA_VOTE,
>         .vote_bit = BIT(1),
>  };
>
> -static const struct bcr_regs usb30_master_regs = {
> -       .cfg_rcgr = USB30_MASTER_CFG_RCGR,
> -       .cmd_rcgr = USB30_MASTER_CMD_RCGR,
> -       .M = USB30_MASTER_M,
> -       .N = USB30_MASTER_N,
> -       .D = USB30_MASTER_D,
> -};
> -
> -static const struct bcr_regs emac_regs = {
> -       .cfg_rcgr = EMAC_CFG_RCGR,
> -       .cmd_rcgr = EMAC_CMD_RCGR,
> -       .M = EMAC_M,
> -       .N = EMAC_N,
> -       .D = EMAC_D,
> -};
> -
> -static const struct bcr_regs emac_ptp_regs = {
> -       .cfg_rcgr = EMAC_PTP_CFG_RCGR,
> -       .cmd_rcgr = EMAC_PTP_CMD_RCGR,
> -       .M = EMAC_M,
> -       .N = EMAC_N,
> -       .D = EMAC_D,
> -};
> -
> -static const struct bcr_regs blsp1_qup0_i2c_apps_regs = {
> -       .cmd_rcgr = BLSP1_QUP0_I2C_APPS_CMD_RCGR,
> -       .cfg_rcgr = BLSP1_QUP0_I2C_APPS_CFG_RCGR,
> -       /* mnd_width = 0 */
> -};
> -
> -static const struct bcr_regs blsp1_qup1_i2c_apps_regs = {
> -       .cmd_rcgr = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
> -       .cfg_rcgr = BLSP1_QUP1_I2C_APPS_CFG_RCGR,
> -       /* mnd_width = 0 */
> -};
> -
> -static const struct bcr_regs blsp1_qup2_i2c_apps_regs = {
> -       .cmd_rcgr = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
> -       .cfg_rcgr = BLSP1_QUP2_I2C_APPS_CFG_RCGR,
> -       /* mnd_width = 0 */
> -};
> -
> -static const struct bcr_regs blsp1_qup3_i2c_apps_regs = {
> -       .cmd_rcgr = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
> -       .cfg_rcgr = BLSP1_QUP3_I2C_APPS_CFG_RCGR,
> -       /* mnd_width = 0 */
> -};
> -
> -static const struct bcr_regs blsp1_qup4_i2c_apps_regs = {
> -       .cmd_rcgr = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
> -       .cfg_rcgr = BLSP1_QUP4_I2C_APPS_CFG_RCGR,
> -       /* mnd_width = 0 */
> -};
> -
>  static ulong qcs404_clk_set_rate(struct clk *clk, ulong rate)
>  {
>         struct msm_clk_priv *priv = dev_get_priv(clk->dev);
>
>         switch (clk->id) {
>         case GCC_BLSP1_UART2_APPS_CLK:
>                 /* UART: 1843200Hz for a fixed 115200 baudrate (19200000 * (12/125)) */
> -               clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
> +               clk_rcg_set_rate_mnd(priv->base, BLSP1_UART2_APPS_CMD_RCGR, 0, 12, 125,
>                                      CFG_CLK_SRC_CXO, 16);
>                 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
>                 return 1843200;
>         case GCC_SDCC1_APPS_CLK:
>                 /* SDCC1: 200MHz */
> -               clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 7, 0, 0,
> +               clk_rcg_set_rate_mnd(priv->base, SDCC_CMD_RCGR(0), 7, 0, 0,
>                                      CFG_CLK_SRC_GPLL0, 8);
>                 clk_enable_gpll0(priv->base, &gpll0_vote_clk);
>                 clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
>                 return rate;
>         case GCC_ETH_RGMII_CLK:
>                 if (rate == 250000000)
> -                       clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
> +                       clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 0, 0,
>                                              CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 125000000)
> -                       clk_rcg_set_rate_mnd(priv->base, &emac_regs, 7, 0, 0,
> +                       clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 7, 0, 0,
>                                              CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 50000000)
> -                       clk_rcg_set_rate_mnd(priv->base, &emac_regs, 19, 0, 0,
> +                       clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 19, 0, 0,
>                                              CFG_CLK_SRC_GPLL1, 8);
>                 else if (rate == 5000000)
> -                       clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 1, 50,
> +                       clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 1, 50,
>                                              CFG_CLK_SRC_GPLL1, 8);
>                 return rate;
>         }
>
> @@ -236,9 +145,9 @@ static int qcs404_clk_enable(struct clk *clk)
>
>         switch (clk->id) {
>         case GCC_USB30_MASTER_CLK:
>                 clk_enable_cbc(priv->base + USB30_MASTER_CBCR);
> -               clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 7, 0, 0,
> +               clk_rcg_set_rate_mnd(priv->base, USB30_MASTER_CMD_RCGR, 7, 0, 0,
>                                      CFG_CLK_SRC_GPLL0, 8);
>                 break;
>         case GCC_SYS_NOC_USB3_CLK:
>                 clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR);
> @@ -258,16 +167,16 @@ static int qcs404_clk_enable(struct clk *clk)
>         case GCC_ETH_PTP_CLK:
>                 /* SPEED_1000: freq -> 250MHz */
>                 clk_enable_cbc(priv->base + ETH_PTP_CBCR);
>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
> -               clk_rcg_set_rate_mnd(priv->base, &emac_ptp_regs, 3, 0, 0,
> +               clk_rcg_set_rate_mnd(priv->base, EMAC_PTP_CMD_RCGR, 3, 0, 0,
>                                      CFG_CLK_SRC_GPLL1, 8);
>                 break;
>         case GCC_ETH_RGMII_CLK:
>                 /* SPEED_1000: freq -> 250MHz */
>                 clk_enable_cbc(priv->base + ETH_RGMII_CBCR);
>                 clk_enable_gpll0(priv->base, &gpll1_vote_clk);
> -               clk_rcg_set_rate_mnd(priv->base, &emac_regs, 3, 0, 0,
> +               clk_rcg_set_rate_mnd(priv->base, EMAC_CMD_RCGR, 3, 0, 0,
>                                      CFG_CLK_SRC_GPLL1, 8);
>                 break;
>         case GCC_ETH_SLAVE_AHB_CLK:
>                 clk_enable_cbc(priv->base + ETH_SLAVE_AHB_CBCR);
> @@ -279,29 +188,29 @@ static int qcs404_clk_enable(struct clk *clk)
>                 clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
>                 break;
>         case GCC_BLSP1_QUP0_I2C_APPS_CLK:
>                 clk_enable_cbc(priv->base + BLSP1_QUP0_I2C_APPS_CBCR);
> -               clk_rcg_set_rate(priv->base, &blsp1_qup0_i2c_apps_regs, 0,
> +               clk_rcg_set_rate(priv->base, BLSP1_QUP0_I2C_APPS_CMD_RCGR, 0,
>                                  CFG_CLK_SRC_CXO);
>                 break;
>         case GCC_BLSP1_QUP1_I2C_APPS_CLK:
>                 clk_enable_cbc(priv->base + BLSP1_QUP1_I2C_APPS_CBCR);
> -               clk_rcg_set_rate(priv->base, &blsp1_qup1_i2c_apps_regs, 0,
> +               clk_rcg_set_rate(priv->base, BLSP1_QUP1_I2C_APPS_CMD_RCGR, 0,
>                                  CFG_CLK_SRC_CXO);
>                 break;
>         case GCC_BLSP1_QUP2_I2C_APPS_CLK:
>                 clk_enable_cbc(priv->base + BLSP1_QUP2_I2C_APPS_CBCR);
> -               clk_rcg_set_rate(priv->base, &blsp1_qup2_i2c_apps_regs, 0,
> +               clk_rcg_set_rate(priv->base, BLSP1_QUP2_I2C_APPS_CMD_RCGR, 0,
>                                  CFG_CLK_SRC_CXO);
>                 break;
>         case GCC_BLSP1_QUP3_I2C_APPS_CLK:
>                 clk_enable_cbc(priv->base + BLSP1_QUP3_I2C_APPS_CBCR);
> -               clk_rcg_set_rate(priv->base, &blsp1_qup3_i2c_apps_regs, 0,
> +               clk_rcg_set_rate(priv->base, BLSP1_QUP3_I2C_APPS_CMD_RCGR, 0,
>                                  CFG_CLK_SRC_CXO);
>                 break;
>         case GCC_BLSP1_QUP4_I2C_APPS_CLK:
>                 clk_enable_cbc(priv->base + BLSP1_QUP4_I2C_APPS_CBCR);
> -               clk_rcg_set_rate(priv->base, &blsp1_qup4_i2c_apps_regs, 0,
> +               clk_rcg_set_rate(priv->base, BLSP1_QUP4_I2C_APPS_CMD_RCGR, 0,
>                                  CFG_CLK_SRC_CXO);
>                 break;
>         case GCC_SDCC1_AHB_CLK:
>                 clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
> index babd83119e2c..ccb0cf245d33 100644
> --- a/drivers/clk/qcom/clock-sdm845.c
> +++ b/drivers/clk/qcom/clock-sdm845.c
> @@ -18,15 +18,9 @@
>  #include <dt-bindings/clock/qcom,gcc-sdm845.h>
>
>  #include "clock-qcom.h"
>
> -#define SE9_AHB_CBCR           0x25004
> -#define SE9_UART_APPS_CBCR     0x29004
>  #define SE9_UART_APPS_CMD_RCGR 0x18148
> -#define SE9_UART_APPS_CFG_RCGR 0x1814C
> -#define SE9_UART_APPS_M                0x18150
> -#define SE9_UART_APPS_N                0x18154
> -#define SE9_UART_APPS_D                0x18158
>
>  static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
>         F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
>         F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
> @@ -45,25 +39,17 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
>         F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
>         { }
>  };
>
> -static const struct bcr_regs uart2_regs = {
> -       .cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
> -       .cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
> -       .M = SE9_UART_APPS_M,
> -       .N = SE9_UART_APPS_N,
> -       .D = SE9_UART_APPS_D,
> -};
> -
>  static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
>  {
>         struct msm_clk_priv *priv = dev_get_priv(clk->dev);
>         const struct freq_tbl *freq;
>
>         switch (clk->id) {
>         case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */
>                 freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
> -               clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
> +               clk_rcg_set_rate_mnd(priv->base, SE9_UART_APPS_CMD_RCGR,
>                                      freq->pre_div, freq->m, freq->n, freq->src, 16);
>                 return freq->freq;
>         default:
>                 return 0;
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 06/14] clk/qcom: sdm845: add gdscs
  2024-03-19 12:22 ` [PATCH v3 06/14] clk/qcom: sdm845: add gdscs Caleb Connolly
@ 2024-03-20  5:42   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:42 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Define the GDSC power domains for SDM845.
>
> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/clk/qcom/clock-sdm845.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

-Sumit

> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
> index ccb0cf245d33..b7154360894a 100644
> --- a/drivers/clk/qcom/clock-sdm845.c
> +++ b/drivers/clk/qcom/clock-sdm845.c
> @@ -145,13 +145,31 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = {
>         [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
>         [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
>  };
>
> +static const struct qcom_power_map sdm845_gdscs[] = {
> +       [PCIE_0_GDSC] = { 0x6b004 },
> +       [PCIE_1_GDSC] = { 0x8d004 },
> +       [UFS_CARD_GDSC] = { 0x75004 },
> +       [UFS_PHY_GDSC] = { 0x77004 },
> +       [USB30_PRIM_GDSC] = { 0xf004 },
> +       [USB30_SEC_GDSC] = { 0x10004 },
> +       [HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC] = { 0x7d030 },
> +       [HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC] = { 0x7d03c },
> +       [HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC] = { 0x7d034 },
> +       [HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC] = { 0x7d038 },
> +       [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = { 0x7d040 },
> +       [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = { 0x7d048 },
> +       [HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = { 0x7d044 },
> +};
> +
>  static struct msm_clk_data sdm845_clk_data = {
>         .resets = sdm845_gcc_resets,
>         .num_resets = ARRAY_SIZE(sdm845_gcc_resets),
>         .clks = sdm845_clks,
>         .num_clks = ARRAY_SIZE(sdm845_clks),
> +       .power_domains = sdm845_gdscs,
> +       .num_power_domains = ARRAY_SIZE(sdm845_gdscs),
>
>         .enable = sdm845_clk_enable,
>         .set_rate = sdm845_clk_set_rate,
>  };
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks
  2024-03-19 12:22 ` [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks Caleb Connolly
@ 2024-03-20  5:43   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:43 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> Most devices only initialise the USB clocks for us if we boot via
> "fastboot boot", add the missing clock configuration to get both USB
> ports working regardless of the bootloader state.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/clk/qcom/clock-sdm845.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

-Sumit

> diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c
> index b7154360894a..e9c61eb480de 100644
> --- a/drivers/clk/qcom/clock-sdm845.c
> +++ b/drivers/clk/qcom/clock-sdm845.c
> @@ -20,8 +20,12 @@
>  #include "clock-qcom.h"
>
>  #define SE9_UART_APPS_CMD_RCGR 0x18148
>
> +#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf018
> +#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf030
> +#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf05c
> +
>  static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
>         F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
>         F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
>         F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
> @@ -56,8 +60,10 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
>         }
>  }
>
>  static const struct gate_clk sdm845_clks[] = {
> +       GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK,            0x82020, 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),
>         GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK,                0x5200c, 0x00001000),
>         GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK,                0x5200c, 0x00002000),
> @@ -120,8 +126,27 @@ static int sdm845_clk_enable(struct clk *clk)
>         struct msm_clk_priv *priv = dev_get_priv(clk->dev);
>
>         debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name);
>
> +       switch (clk->id) {
> +       case GCC_USB30_PRIM_MASTER_CLK:
> +               qcom_gate_clk_en(priv, GCC_USB_PHY_CFG_AHB2PHY_CLK);
> +               /* These numbers are just pulled from the frequency tables in the Linux driver */
> +               clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR,
> +                                    (4.5 * 2) - 1, 0, 0, 1 << 8, 8);
> +               clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR,
> +                                    1, 0, 0, 0, 8);
> +               clk_rcg_set_rate_mnd(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR,
> +                                    1, 0, 0, 0, 8);
> +               break;
> +       case GCC_USB30_SEC_MASTER_CLK:
> +               qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
> +
> +               qcom_gate_clk_en(priv, GCC_USB3_SEC_CLKREF_CLK);
> +               qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
> +               break;
> +       }
> +
>         qcom_gate_clk_en(priv, clk->id);
>
>         return 0;
>  }
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op
  2024-03-19 12:22 ` [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op Caleb Connolly
@ 2024-03-20  5:44   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:44 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> The .direction_input and .direction_output ops are deprecated, and don't
> seem to behave properly for us. Implement our own .set_flags op to
> handle this correctly.
>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/gpio/msm_gpio.c | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

-Sumit

> diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
> index 5e57b0cbde75..f5d9ab54e817 100644
> --- a/drivers/gpio/msm_gpio.c
> +++ b/drivers/gpio/msm_gpio.c
> @@ -34,21 +34,21 @@ struct msm_gpio_bank {
>
>  #define GPIO_IN_OUT_REG(dev, x) \
>         (GPIO_CONFIG_REG(dev, x) + 0x4)
>
> -static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
> +static void msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
>  {
>         struct msm_gpio_bank *priv = dev_get_priv(dev);
>
>         /* Always NOP for special pins, assume they're in the correct state */
>         if (qcom_is_special_pin(priv->pin_data, gpio))
> -               return 0;
> +               return;
>
>         /* Disable OE bit */
>         clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
>                         GPIO_OE_MASK, GPIO_OE_DISABLE);
>
> -       return 0;
> +       return;
>  }
>
>  static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
>  {
> @@ -83,8 +83,25 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
>
>         return 0;
>  }
>
> +static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags)
> +{
> +       if (flags & GPIOD_IS_OUT_ACTIVE) {
> +               return msm_gpio_direction_output(dev, gpio, 1);
> +       } else if (flags & GPIOD_IS_OUT) {
> +               return msm_gpio_direction_output(dev, gpio, 0);
> +       } else if (flags & GPIOD_IS_IN) {
> +               msm_gpio_direction_input(dev, gpio);
> +               if (flags & GPIOD_PULL_UP)
> +                       return msm_gpio_set_value(dev, gpio, 1);
> +               else if (flags & GPIOD_PULL_DOWN)
> +                       return msm_gpio_set_value(dev, gpio, 0);
> +       }
> +
> +       return 0;
> +}
> +
>  static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
>  {
>         struct msm_gpio_bank *priv = dev_get_priv(dev);
>
> @@ -109,12 +126,10 @@ static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
>         return GPIOF_INPUT;
>  }
>
>  static const struct dm_gpio_ops gpio_msm_ops = {
> -       .direction_input        = msm_gpio_direction_input,
> -       .direction_output       = msm_gpio_direction_output,
> +       .set_flags              = msm_gpio_set_flags,
>         .get_value              = msm_gpio_get_value,
> -       .set_value              = msm_gpio_set_value,
>         .get_function           = msm_gpio_get_function,
>  };
>
>  static int msm_gpio_probe(struct udevice *dev)
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 09/14] serial: msm-geni: support livetree
  2024-03-19 12:22 ` [PATCH v3 09/14] serial: msm-geni: support livetree Caleb Connolly
@ 2024-03-20  5:44   ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-20  5:44 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
> When using OF_LIVE, the debug UART driver won't be probed if it's a
> subnode of the geni-se-qup controller. Add a NOP driver for the
> controller to correctly discover its child nodes.
>
> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
> ---
>  drivers/serial/serial_msm_geni.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>

-Sumit

> diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
> index 4aa0bc8c72bc..5260474fb9a4 100644
> --- a/drivers/serial/serial_msm_geni.c
> +++ b/drivers/serial/serial_msm_geni.c
> @@ -605,8 +605,21 @@ U_BOOT_DRIVER(serial_msm_geni) = {
>         .ops = &msm_serial_ops,
>         .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
>  };
>
> +static const struct udevice_id geniqup_ids[] = {
> +       { .compatible = "qcom,geni-se-qup" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(geni_se_qup) = {
> +       .name = "geni-se-qup",
> +       .id = UCLASS_NOP,
> +       .of_match = geniqup_ids,
> +       .bind = dm_scan_fdt_dev,
> +       .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
> +};
> +
>  #ifdef CONFIG_DEBUG_UART_MSM_GENI
>
>  static struct msm_serial_data init_serial_data = {
>         .base = CONFIG_VAL(DEBUG_UART_BASE)
>
> --
> 2.44.0
>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups
  2024-03-19 13:55   ` Sumit Garg
@ 2024-03-20 12:33     ` Caleb Connolly
  2024-03-20 12:34       ` Caleb Connolly
  0 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-20 12:33 UTC (permalink / raw
  To: Sumit Garg
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot



On 19/03/2024 13:55, Sumit Garg wrote:
> On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>> The USB VBUS supply for the type-A port is enabled via a GPIO regulator.
>> This is incorrectly modelled in Linux where only the PCIe dependency is
>> expressed.
> 
> Can we send a fix for the Linux kernel DTS to correctly model it? We
> can then later get rid of this modification once that is accepted.

I spoke to Bjorn about this and apparently the correct way to model this
will be to have a usb-connector node with a vbus-supply property. There
is some work underway in Linux to support this kind of thing already.

In the mean time he suggested to just make the regulator always-on, so I
sent a patch to do that [1]. I actually hit this issue when booting from
USB as the PCIe drivers aren't available in the initramfs, so USB never
turns on, and the always-on hack fixes that.

In the mean time, we'll still need this vbus-supply reference as U-Boot
doesn't automatically probe regulators.
> 
> -Sumit
> 
>> Add a U-Boot specific dtsi snippet so that this supply will
>> get enabled when initialising USB.
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
>> ---
>>  arch/arm/dts/sdm845-db845c-u-boot.dtsi | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm/dts/sdm845-db845c-u-boot.dtsi b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
>> new file mode 100644
>> index 000000000000..3c83e21251c4
>> --- /dev/null
>> +++ b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
>> @@ -0,0 +1,8 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +/* This GPIO must be turned on to enable the 5v VBUS
>> + * supply on the USB port.
>> + */
>> +&usb_2_dwc3 {
>> +       vbus-supply = <&pcie0_3p3v_dual>;
>> +};
>>
>> --
>> 2.44.0
>>

-- 
// Caleb (they/them)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups
  2024-03-20 12:33     ` Caleb Connolly
@ 2024-03-20 12:34       ` Caleb Connolly
  2024-03-21  4:53         ` Sumit Garg
  0 siblings, 1 reply; 35+ messages in thread
From: Caleb Connolly @ 2024-03-20 12:34 UTC (permalink / raw
  To: Sumit Garg
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot



On 20/03/2024 12:33, Caleb Connolly wrote:
> 
> 
> On 19/03/2024 13:55, Sumit Garg wrote:
>> On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>>
>>> The USB VBUS supply for the type-A port is enabled via a GPIO regulator.
>>> This is incorrectly modelled in Linux where only the PCIe dependency is
>>> expressed.
>>
>> Can we send a fix for the Linux kernel DTS to correctly model it? We
>> can then later get rid of this modification once that is accepted.
> 
> I spoke to Bjorn about this and apparently the correct way to model this
> will be to have a usb-connector node with a vbus-supply property. There
> is some work underway in Linux to support this kind of thing already.
> 
> In the mean time he suggested to just make the regulator always-on, so I
> sent a patch to do that [1]. I actually hit this issue when booting from
> USB as the PCIe drivers aren't available in the initramfs, so USB never
> turns on, and the always-on hack fixes that.
> 
> In the mean time, we'll still need this vbus-supply reference as U-Boot
> doesn't automatically probe regulators.

oh, forgot the link!

[1]:
https://lore.kernel.org/linux-arm-msm/20240320122515.3243711-1-caleb.connolly@linaro.org/
>>
>> -Sumit
>>
>>> Add a U-Boot specific dtsi snippet so that this supply will
>>> get enabled when initialising USB.
>>>
>>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
>>> ---
>>>  arch/arm/dts/sdm845-db845c-u-boot.dtsi | 8 ++++++++
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/arch/arm/dts/sdm845-db845c-u-boot.dtsi b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
>>> new file mode 100644
>>> index 000000000000..3c83e21251c4
>>> --- /dev/null
>>> +++ b/arch/arm/dts/sdm845-db845c-u-boot.dtsi
>>> @@ -0,0 +1,8 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +
>>> +/* This GPIO must be turned on to enable the 5v VBUS
>>> + * supply on the USB port.
>>> + */
>>> +&usb_2_dwc3 {
>>> +       vbus-supply = <&pcie0_3p3v_dual>;
>>> +};
>>>
>>> --
>>> 2.44.0
>>>
> 

-- 
// Caleb (they/them)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 14/14] qcom_defconfig: enable USB
  2024-03-20  5:40   ` Sumit Garg
@ 2024-03-20 13:16     ` Caleb Connolly
  0 siblings, 0 replies; 35+ messages in thread
From: Caleb Connolly @ 2024-03-20 13:16 UTC (permalink / raw
  To: Sumit Garg
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot



On 20/03/2024 05:40, Sumit Garg wrote:
> On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>>
>> Enable support for the DWC3 USB controller and required dependencies for
>> Qualcomm boards, specifically the DB845c:
>> * IOMMU / SMMU
>> * USB high-speed PHYs
>> * Mass storage and ACM gadgets
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
>> ---
>>  configs/qcom_defconfig | 49 ++++++++++++++++++++++++++-----------------------
>>  1 file changed, 26 insertions(+), 23 deletions(-)
>>
>> diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig
>> index eebd0d74bd51..156c205284dd 100644
>> --- a/configs/qcom_defconfig
>> +++ b/configs/qcom_defconfig
>> @@ -12,42 +12,63 @@ CONFIG_BOOTSTD_FULL=y
>>  CONFIG_BOOTDELAY=1
>>  CONFIG_USE_PREBOOT=y
>>  CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
>>  CONFIG_SYS_CBSIZE=512
>> +# CONFIG_SYS_DEVICE_NULLDEV is not set
>>  CONFIG_LOG_MAX_LEVEL=9
>>  CONFIG_LOG_DEFAULT_LEVEL=4
>>  # CONFIG_DISPLAY_CPUINFO is not set
>>  CONFIG_DISPLAY_BOARDINFO_LATE=y
>>  CONFIG_CMD_BOOTMENU=y
>> +CONFIG_CMD_EEPROM=y
>> +CONFIG_SYS_I2C_EEPROM_BUS=2
>> +CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
>> +CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
>> +# CONFIG_CMD_BIND is not set
>>  CONFIG_CMD_CLK=y
>>  CONFIG_CMD_GPIO=y
>> +CONFIG_CMD_I2C=y
>>  CONFIG_CMD_MMC=y
>>  CONFIG_CMD_UFS=y
>>  CONFIG_CMD_USB=y
>>  CONFIG_CMD_CAT=y
>>  CONFIG_CMD_BMP=y
>>  CONFIG_CMD_LOG=y
>>  CONFIG_OF_LIVE=y
>>  # CONFIG_NET is not set
>> +CONFIG_DM_WARN=y
>>  # CONFIG_OFNODE_MULTI_TREE is not set
>>  CONFIG_BUTTON_QCOM_PMIC=y
>>  CONFIG_CLK=y
>>  CONFIG_CLK_QCOM_QCS404=y
>>  CONFIG_CLK_QCOM_SDM845=y
>>  CONFIG_MSM_GPIO=y
>>  CONFIG_QCOM_PMIC_GPIO=y
>> +CONFIG_DM_I2C=y
>> +CONFIG_SYS_I2C_QUP=y
>> +CONFIG_I2C_MUX=y
>>  CONFIG_DM_KEYBOARD=y
>>  CONFIG_BUTTON_KEYBOARD=y
>> +CONFIG_IOMMU=y
>> +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
>> +CONFIG_DM_ETH_PHY=y
>>  CONFIG_PHY=y
>> +CONFIG_PHY_QCOM_QUSB2=y
>> +CONFIG_PHY_QCOM_USB_HS_7NM=y
>>  CONFIG_PINCTRL=y
>>  CONFIG_PINCTRL_QCOM_QCS404=y
>>  CONFIG_PINCTRL_QCOM_SDM845=y
>>  CONFIG_DM_PMIC=y
>>  CONFIG_PMIC_QCOM=y
>> +CONFIG_DM_REGULATOR=y
>> +CONFIG_DM_REGULATOR_FIXED=y
>>  CONFIG_SCSI=y
>>  CONFIG_MSM_SERIAL=y
>>  CONFIG_MSM_GENI_SERIAL=y
>>  CONFIG_SPMI_MSM=y
>> @@ -56,8 +77,13 @@ CONFIG_SYSINFO_SMBIOS=y
>>  CONFIG_USB=y
>>  CONFIG_USB_XHCI_HCD=y
>>  CONFIG_USB_XHCI_DWC3=y
>>  CONFIG_USB_DWC3=y
>> +CONFIG_USB_DWC3_GENERIC=y
>> +CONFIG_USB_GADGET=y
>> +CONFIG_USB_GADGET_DOWNLOAD=y
>> +CONFIG_USB_FUNCTION_MASS_STORAGE=y
>> +CONFIG_USB_FUNCTION_ACM=y
>>  CONFIG_UFS=y
>>  CONFIG_VIDEO=y
>>  # CONFIG_VIDEO_FONT_8X16 is not set
>>  CONFIG_VIDEO_FONT_16X32=y
>> @@ -66,27 +92,4 @@ CONFIG_NO_FB_CLEAR=y
>>  CONFIG_VIDEO_SIMPLE=y
>>  CONFIG_HEXDUMP=y
>>  # CONFIG_GENERATE_SMBIOS_TABLE is not set
>>  CONFIG_LMB_MAX_REGIONS=64
>> -CONFIG_CMD_DHCP=y
>> -CONFIG_CMD_EEPROM=y
>> -CONFIG_CMD_I2C=y
>> -CONFIG_CMD_PING=y
>> -CONFIG_DM_ETH=y
>> -CONFIG_DM_ETH_PHY=y
>> -CONFIG_DM_MDIO=y
>> -CONFIG_DWC_ETH_QOS=y
>> -CONFIG_DWC_ETH_QOS_QCOM=y
> 
> Any particular reason to drop these?

No, this is weird, I must have screwed something up while regenerating
the defconfig. Thanks for catching this, I'll fix it for the next revision.
> 
> -Sumit
> 
>> -CONFIG_RGMII=y
>> -CONFIG_PHY_MICREL=y
>> -CONFIG_PHY_MICREL_KSZ90X1=y
>> -CONFIG_MISC=y
>> -CONFIG_NVMEM=y
>> -CONFIG_DM_I2C=y
>> -CONFIG_I2C_SUPPORT=y
>> -CONFIG_I2C_MUX=y
>> -CONFIG_I2C_EEPROM=y
>> -CONFIG_SYS_I2C=y
>> -CONFIG_SYS_I2C_QUP=y
>> -CONFIG_SYS_I2C_EEPROM_BUS=2
>> -CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
>> -CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
>>
>> --
>> 2.44.0
>>

-- 
// Caleb (they/them)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver
  2024-03-20  5:21   ` Sumit Garg
@ 2024-03-20 13:47     ` Caleb Connolly
  0 siblings, 0 replies; 35+ messages in thread
From: Caleb Connolly @ 2024-03-20 13:47 UTC (permalink / raw
  To: Sumit Garg
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot,
	Bhupesh Sharma

Hi Sumit,

>> +static inline void qusb2_write_mask(void __iomem *base, u32 offset, u32 val,
>> +                                   u32 mask)
>> +{
>> +       u32 reg;
>> +
>> +       reg = readl(base + offset);
>> +       reg &= ~mask;
>> +       reg |= val & mask;
>> +       writel(reg, base + offset);
>> +
>> +       /* Ensure above write is completed */
>> +       readl(base + offset);
>> +}
> 
> Function unused?

Will drop
> 
>> +
>> +static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
>> +{
>> +       u32 reg;
>> +
>> +       reg = readl(base + offset);
>> +       reg |= val;
>> +       writel(reg, base + offset);
>> +
>> +       /* Ensure above write is completed */
>> +       readl(base + offset);
>> +}
>> +
>> +static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
>> +{
>> +       u32 reg;
>> +
>> +       reg = readl(base + offset);
>> +       reg &= ~val;
>> +       writel(reg, base + offset);
>> +
>> +       /* Ensure above write is completed */
>> +       readl(base + offset);
>> +}
> 
> Any specific reason to not use setbits_le32() and clrbits_le32() her instead?

This is just copied from Linux. I tested with set/clrbits and it seems
to work ok... I'm a little worried this is a workaround for some obscure
bug but eh, I guess we'll just go without and see what happens.
> 
>> +
>> +static inline void qusb2_phy_configure(void __iomem *base,
>> +                                      const unsigned int *regs,
>> +                                      const struct qusb2_phy_init_tbl tbl[],
>> +                                      int num)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < num; i++) {
>> +               if (tbl[i].in_layout)
>> +                       writel(tbl[i].val, base + regs[tbl[i].offset]);
>> +               else
>> +                       writel(tbl[i].val, base + tbl[i].offset);
>> +       }
>> +}
>> +
>> +static int qusb2phy_do_reset(struct qusb2_phy *qphy)
>> +{
>> +       int ret;
>> +
>> +       ret = reset_assert(&qphy->phy_rst);
>> +       if (ret)
>> +               return ret;
>> +
>> +       udelay(10);
>> +
>> +       ret = reset_deassert(&qphy->phy_rst);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return 0;
>> +}
>> +
>> +static int qusb2phy_power_on(struct phy *phy)
>> +{
>> +       struct qusb2_phy *qphy = dev_get_priv(phy->dev);
>> +       const struct qusb2_phy_cfg *cfg = qphy->cfg;
>> +       int ret;
>> +       u32 val;
>> +
>> +       ret = qusb2phy_do_reset(qphy);
>> +       if (ret)
>> +               return ret;
> 
> Do we really need to reset here? Wouldn't just
> reset_deassert(&qphy->phy_rst) be sufficient here instead?

The reset is not asserted by default, so de-asserting it would do
nothing. Yes we need to reset because we have no idea what state the
hardware is in, depending on what board and what bootloader you've come
from this phy could have already been powered up and configured before
we get to U-Boot.


> 
> -Sumit
> 
>> +
>> +       /* Disable the PHY */
>> +       qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
>> +                     qphy->cfg->disable_ctrl);
>> +
>> +       if (cfg->has_pll_test) {
>> +               /* save reset value to override reference clock scheme later */
>> +               val = readl(qphy->base + QUSB2PHY_PLL_TEST);
>> +       }
>> +
>> +       qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl, cfg->tbl_num);
>> +
>> +       /* Enable the PHY */
>> +       qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
>> +                     POWER_DOWN);
>> +
>> +       /* Required to get phy pll lock successfully */
>> +       udelay(150);
>> +
>> +       if (cfg->has_pll_test) {
>> +               val |= CLK_REF_SEL;
>> +
>> +               writel(val, qphy->base + QUSB2PHY_PLL_TEST);
>> +
>> +               /* ensure above write is through */
>> +               readl(qphy->base + QUSB2PHY_PLL_TEST);
>> +       }
>> +
>> +       /* Required to get phy pll lock successfully */
>> +       udelay(100);
>> +
>> +       val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
>> +       if (!(val & cfg->mask_core_ready)) {
>> +               pr_err("QUSB2PHY pll lock failed: status reg = %x\n", val);
>> +               ret = -EBUSY;
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int qusb2phy_power_off(struct phy *phy)
>> +{
>> +       struct qusb2_phy *qphy = dev_get_priv(phy->dev);
>> +
>> +       /* Disable the PHY */
>> +       qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
>> +                     qphy->cfg->disable_ctrl);
>> +
>> +       reset_assert(&qphy->phy_rst);
>> +
>> +       clk_disable(&qphy->cfg_ahb_clk);
>> +
>> +       return 0;
>> +}
>> +
>> +static int qusb2phy_clk_init(struct udevice *dev, struct qusb2_phy *qphy)
>> +{
>> +       int ret;
>> +
>> +       /* We ignore the ref clock as we currently lack a driver for rpmcc/rpmhcc where
>> +        * it usually comes from - we assume it's always on.
>> +        */
>> +       ret = clk_get_by_name(dev, "cfg_ahb", &qphy->cfg_ahb_clk);
>> +       if (ret == -ENOSYS || ret == -ENOENT)
>> +               return 0;
>> +       if (ret)
>> +               return ret;
>> +
>> +       ret = clk_enable(&qphy->cfg_ahb_clk);
>> +       if (ret) {
>> +               return ret;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int qusb2phy_probe(struct udevice *dev)
>> +{
>> +       struct qusb2_phy *qphy = dev_get_priv(dev);
>> +       int ret;
>> +
>> +       qphy->base = (void __iomem *)dev_read_addr(dev);
>> +       if (IS_ERR(qphy->base))
>> +               return PTR_ERR(qphy->base);
>> +
>> +       ret = qusb2phy_clk_init(dev, qphy);
>> +       if (ret) {
>> +               printf("%s: Couldn't get clocks: %d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       ret = reset_get_by_index(dev, 0, &qphy->phy_rst);
>> +       if (ret) {
>> +               printf("%s: Couldn't get resets: %d\n", __func__, ret);
>> +               return ret;
>> +       }
>> +
>> +       qphy->cfg = (const struct qusb2_phy_cfg *)dev_get_driver_data(dev);
>> +       if (!qphy->cfg) {
>> +               printf("%s: Couldn't get driver data\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>> +       debug("%s success qusb phy cfg %p\n", __func__, qphy->cfg);
>> +       return 0;
>> +}
>> +
>> +static struct phy_ops qusb2phy_ops = {
>> +       .power_on = qusb2phy_power_on,
>> +       .power_off = qusb2phy_power_off,
>> +};
>> +
>> +static const struct udevice_id qusb2phy_ids[] = {
>> +       { .compatible = "qcom,qusb2-phy" },
>> +       { .compatible = "qcom,qcm2290-qusb2-phy",
>> +         .data = (ulong)&sm6115_phy_cfg },
>> +       { .compatible = "qcom,sm6115-qusb2-phy",
>> +         .data = (ulong)&sm6115_phy_cfg },
>> +       { .compatible = "qcom,qusb2-v2-phy", .data = (ulong)&qusb2_v2_phy_cfg },
>> +       {}
>> +};
>> +
>> +U_BOOT_DRIVER(qcom_qusb2_phy) = {
>> +       .name = "qcom-qusb2-phy",
>> +       .id = UCLASS_PHY,
>> +       .of_match = qusb2phy_ids,
>> +       .ops = &qusb2phy_ops,
>> +       .probe = qusb2phy_probe,
>> +       .priv_auto = sizeof(struct qusb2_phy),
>> +};
>>
>> --
>> 2.44.0
>>

-- 
// Caleb (they/them)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups
  2024-03-20 12:34       ` Caleb Connolly
@ 2024-03-21  4:53         ` Sumit Garg
  0 siblings, 0 replies; 35+ messages in thread
From: Sumit Garg @ 2024-03-21  4:53 UTC (permalink / raw
  To: Caleb Connolly
  Cc: Tom Rini, Neil Armstrong, Lukasz Majewski, Sean Anderson, u-boot

On Wed, 20 Mar 2024 at 18:04, Caleb Connolly <caleb.connolly@linaro.org> wrote:
>
>
>
> On 20/03/2024 12:33, Caleb Connolly wrote:
> >
> >
> > On 19/03/2024 13:55, Sumit Garg wrote:
> >> On Tue, 19 Mar 2024 at 17:52, Caleb Connolly <caleb.connolly@linaro.org> wrote:
> >>>
> >>> The USB VBUS supply for the type-A port is enabled via a GPIO regulator.
> >>> This is incorrectly modelled in Linux where only the PCIe dependency is
> >>> expressed.
> >>
> >> Can we send a fix for the Linux kernel DTS to correctly model it? We
> >> can then later get rid of this modification once that is accepted.
> >
> > I spoke to Bjorn about this and apparently the correct way to model this
> > will be to have a usb-connector node with a vbus-supply property. There
> > is some work underway in Linux to support this kind of thing already.
> >
> > In the mean time he suggested to just make the regulator always-on, so I
> > sent a patch to do that [1]. I actually hit this issue when booting from
> > USB as the PCIe drivers aren't available in the initramfs, so USB never
> > turns on, and the always-on hack fixes that.
> >
> > In the mean time, we'll still need this vbus-supply reference as U-Boot
> > doesn't automatically probe regulators.
>

Try adding regulators_enable_boot_on() to the common board code. With
that there shouldn't be any need for this vbus-supply reference.

> oh, forgot the link!
>
> [1]:
> https://lore.kernel.org/linux-arm-msm/20240320122515.3243711-1-caleb.connolly@linaro.org/

-Sumit

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2024-03-21  4:54 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-19 12:21 [PATCH v3 00/14] Qualcomm platform USB support Caleb Connolly
2024-03-19 12:22 ` [PATCH v3 01/14] mailmap: update Bhupesh's email address Caleb Connolly
2024-03-19 12:22 ` [PATCH v3 02/14] phy: qcom: add Qualcomm QUSB2 USB PHY driver Caleb Connolly
2024-03-20  5:21   ` Sumit Garg
2024-03-20 13:47     ` Caleb Connolly
2024-03-19 12:22 ` [PATCH v3 03/14] phy: qcom: Add USB HS 7nm " Caleb Connolly
2024-03-20  5:37   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 04/14] mach-snapdragon: disable power-domains for pre-reloc drivers Caleb Connolly
2024-03-20  5:21   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 05/14] clk/qcom: use offsets for RCG registers Caleb Connolly
2024-03-20  5:42   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 06/14] clk/qcom: sdm845: add gdscs Caleb Connolly
2024-03-20  5:42   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 07/14] clk/qcom: sdm845: add USB clocks Caleb Connolly
2024-03-20  5:43   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 08/14] gpio: msm_gpio: add .set_flags op Caleb Connolly
2024-03-20  5:44   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 09/14] serial: msm-geni: support livetree Caleb Connolly
2024-03-20  5:44   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 10/14] mach-snapdragon: fixup USB nodes Caleb Connolly
2024-03-19 13:49   ` Sumit Garg
2024-03-19 14:45     ` Caleb Connolly
2024-03-20  4:37       ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 11/14] mach-snapdragon: fixup power-domains Caleb Connolly
2024-03-19 13:51   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 12/14] dts: sdm845-db845c: add u-boot fixups Caleb Connolly
2024-03-19 13:55   ` Sumit Garg
2024-03-20 12:33     ` Caleb Connolly
2024-03-20 12:34       ` Caleb Connolly
2024-03-21  4:53         ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 13/14] qcom_defconfig: enable livetree Caleb Connolly
2024-03-19 13:27   ` Sumit Garg
2024-03-19 12:22 ` [PATCH v3 14/14] qcom_defconfig: enable USB Caleb Connolly
2024-03-20  5:40   ` Sumit Garg
2024-03-20 13:16     ` Caleb Connolly

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.