From ca39a022ad324a5f3f821236b22fa0cd5fdd880b Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:41:01 -0800 Subject: [PATCH 001/128] FROMLIST: dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: Add Glymur compatible Define a Glymur compatible string for the QMP combo PHY, along with resource requirements. Acked-by: Rob Herring (Arm) Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-1-42133596bda0@oss.qualcomm.com/ From 289a0f96a33fb9e6c96e94a5921fe14e6c52e6e1 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 11 Dec 2025 11:47:27 -0800 Subject: [PATCH 002/128] FROMLIST: dt-bindings: phy: qcom-m31-eusb2: Add Glymur compatible Add the Glymur compatible to the M31 eUSB2 PHY, and use the SM8750 as the fallback. Signed-off-by: Wesley Cheng Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/all/20251209-linux-next-12825-v8-3-42133596bda0@oss.qualcomm.com/ From 1b57f5e88f24f9f21b709bc25a6be7c1f19bfd7c Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:35 +0530 Subject: [PATCH 003/128] usb: misc: onboard_usb_hub: Add Genesys Logic GL3590 hub support Add support for the GL3590 4 ports USB3.2 hub. This allows to control its reset pins with a gpio. Signed-off-by: Swati Agarwal --- drivers/usb/misc/onboard_usb_dev.c | 1 + drivers/usb/misc/onboard_usb_dev.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index ba37eb99efbaf..b52dafeefcda9 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -661,6 +661,7 @@ static const struct usb_device_id onboard_dev_id_table[] = { { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 HUB */ + { USB_DEVICE(VENDOR_ID_GENESYS, 0x0625) }, /* Genesys Logic GL3590 USB 3.2 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 HUB */ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 HUB */ diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h index 1a1e86e60e042..978acc662ce41 100644 --- a/drivers/usb/misc/onboard_usb_dev.h +++ b/drivers/usb/misc/onboard_usb_dev.h @@ -147,6 +147,7 @@ static const struct of_device_id onboard_dev_match[] = { { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, { .compatible = "usb5e3,610", .data = &genesys_gl852g_data, }, { .compatible = "usb5e3,620", .data = &genesys_gl852g_data, }, + { .compatible = "usb5e3,625", .data = &genesys_gl852g_data, }, { .compatible = "usb5e3,626", .data = &genesys_gl852g_data, }, { .compatible = "usbbda,179", .data = &realtek_rtl8188etv_data, }, { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, From 8bdbb58d234df243a9ca57054dbf5096607e9c6c Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Sat, 20 Dec 2025 12:05:34 +0530 Subject: [PATCH 004/128] dt-bindings: usb: Add binding for Genesys Logic GL3590 hub Add the binding for the USB3.2 Genesys Logic GL3590 hub. Signed-off-by: Swati Agarwal --- .../devicetree/bindings/usb/genesys,gl850g.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml index 9a94b2a74a1eb..a184e1074c7c4 100644 --- a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml @@ -15,6 +15,7 @@ properties: - usb5e3,608 - usb5e3,610 - usb5e3,620 + - usb5e3,625 - usb5e3,626 reg: true @@ -69,6 +70,17 @@ allOf: peer-hub: true vdd-supply: true + - if: + properties: + compatible: + contains: + enum: + - usb5e3,625 + then: + properties: + peer-hub: true + vdd-supply: false + unevaluatedProperties: false examples: From cfe135bf3401dee9bbb5c726594894cc453d28ea Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:22 -0800 Subject: [PATCH 005/128] FROMLIST: dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Qualcomm Embedded USB Debugger (EUD) can intercept one or two independent High-Speed UTMI paths, depending on the SoC. Each path is distinct with its own HS-PHY interface, connector/controller wiring, and UTMI routing behavior. The EUD hardware sits between the USB2 PHY and the USB controller on each path. The existing binding models only a single UTMI path and does not provide a way to associate the required High-Speed USB PHY. EUD relies on the HS-PHY on the selected UTMI path for link signalling and correct operation of the hardware. Historically, EUD has worked on platforms that use a single UTMI path because the USB controller maintains ownership of the PHY during enumeration and normal operation. This implicit relationship allowed EUD to function even though the dependency on the PHY was not described in the binding. However, this behavior is not guaranteed by hardware. The current binding description is not sufficient for SoCs that expose two independent UTMI paths, where the PHY association and port wiring must be explicitly described. Introduce per-path eud-path child nodes so each UTMI path can describe its HS-PHY, port connections, and the role‑switching capability of its associated USB port. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-2-elson.serrao@oss.qualcomm.com/ --- .../bindings/soc/qcom/qcom,eud.yaml | 100 +++++++++++++----- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml index 84218636c0d8d..0507252dbf27e 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml @@ -10,8 +10,11 @@ maintainers: - Souradeep Chowdhury description: - This binding is used to describe the Qualcomm Embedded USB Debugger, which is - mini USB-hub implemented on chip to support USB-based debug capabilities. + This binding describes the Qualcomm Embedded USB Debugger (EUD), an on-chip + mini USB hub that enables USB-based debug capabilities. The EUD block is + positioned between the High-Speed USB PHY and the USB controller, where it + intercepts the UTMI interface to support debug and bypass modes. EUD can be + supported on up to two High-Speed USB ports. properties: compatible: @@ -29,26 +32,62 @@ properties: description: EUD interrupt maxItems: 1 - ports: - $ref: /schemas/graph.yaml#/properties/ports + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^eud-path@[0-1]$": + type: object description: - These ports is to be attached to the endpoint of the DWC3 controller node - and type C connector node. The controller has the "usb-role-switch" - property. + Represents one High-Speed UTMI path that EUD intercepts. This node models + the physical data path intercepted by EUD and provides graph endpoints to + link the USB controller and the external connector associated with this path. properties: - port@0: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the DWC3 controller. + reg: + maxItems: 1 + description: Path number + + phys: + maxItems: 1 + description: High-Speed USB PHY associated with this data path. + + usb-role-switch: + type: boolean + description: + Set this property if the USB port on this path is role switch capable. + In device role, debug mode inserts the EUD hub into the UTMI path. In + host role, the EUD hub is bypassed and UTMI traffic flows directly + between the PHY and the USB controller. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + These ports are to be attached to the endpoint of the USB controller node + and USB connector node. + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the USB controller. - port@1: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the type C connector. + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the USB connector. + + required: + - reg + - phys + - ports + + additionalProperties: false required: - compatible - reg - - ports additionalProperties: false @@ -58,21 +97,30 @@ examples: compatible = "qcom,sc7280-eud", "qcom,eud"; reg = <0x88e0000 0x2000>, <0x88e2000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + eud-path@0 { + reg = <0>; + phys = <&usb_1_hsphy>; + usb-role-switch; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; + }; }; - }; - port@1 { - reg = <1>; - eud_con: endpoint { - remote-endpoint = <&con_eud>; + port@1 { + reg = <1>; + eud_con: endpoint { + remote-endpoint = <&con_eud>; + }; }; }; }; From c042ed7b42aff071249d6a1b91cedb7170e2d2d4 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:23 -0800 Subject: [PATCH 006/128] FROMLIST: usb: misc: qcom_eud: add sysfs attribute for port selection EUD can be mapped to either the primary USB port or the secondary USB port depending on the value of the EUD_PORT_SEL register. Add a 'port' sysfs attribute to allow userspace to select which port EUD should operate on and update the ABI documentation. This is needed for systems with dual USB ports where EUD needs to be accessible on either port depending on the system configuration and use case. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-3-elson.serrao@oss.qualcomm.com/ --- Documentation/ABI/testing/sysfs-driver-eud | 16 ++++++++ drivers/usb/misc/qcom_eud.c | 43 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud index 2bab0db2d2f0f..67223f73ee606 100644 --- a/Documentation/ABI/testing/sysfs-driver-eud +++ b/Documentation/ABI/testing/sysfs-driver-eud @@ -7,3 +7,19 @@ Description: EUD based on a 1 or a 0 value. By enabling EUD, the user is able to activate the mini-usb hub of EUD for debug and trace capabilities. + +What: /sys/bus/platform/drivers/qcom_eud/.../port +Date: January 2026 +Contact: Elson Serrao +Description: + Selects which USB port the Embedded USB Debugger (EUD) + is mapped to on platforms providing multiple High-Speed + USB ports. + + Valid values: + 0 - Primary USB port + 1 - Secondary USB port + + The attribute is writable only while EUD is disabled. + Reading the attribute returns the currently selected + USB port number. diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 926419ca560fc..1a136f8f1ae52 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -23,8 +23,11 @@ #define EUD_REG_VBUS_INT_CLR 0x0080 #define EUD_REG_CSR_EUD_EN 0x1014 #define EUD_REG_SW_ATTACH_DET 0x1018 +#define EUD_REG_PORT_SEL 0x1028 #define EUD_REG_EUD_EN2 0x0000 +#define EUD_MAX_PORTS 2 + #define EUD_ENABLE BIT(0) #define EUD_INT_PET_EUD BIT(0) #define EUD_INT_VBUS BIT(2) @@ -40,6 +43,7 @@ struct eud_chip { int irq; bool enabled; bool usb_attached; + u8 port_idx; }; static int enable_eud(struct eud_chip *priv) @@ -104,8 +108,47 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR_RW(enable); +static ssize_t port_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", chip->port_idx); +} + +static ssize_t port_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + u8 port; + int ret; + + ret = kstrtou8(buf, 0, &port); + if (ret) + return ret; + + /* Only port 0 and port 1 are valid */ + if (port >= EUD_MAX_PORTS) + return -EINVAL; + + /* Port selection must be done before enabling EUD */ + if (chip->enabled) { + dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); + return -EBUSY; + } + + writel(port, chip->base + EUD_REG_PORT_SEL); + chip->port_idx = port; + + return count; +} + +static DEVICE_ATTR_RW(port); + static struct attribute *eud_attrs[] = { &dev_attr_enable.attr, + &dev_attr_port.attr, NULL, }; ATTRIBUTE_GROUPS(eud); From e2541a8409a99af58825af0a54178d0b26677f5b Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:24 -0800 Subject: [PATCH 007/128] FROMLIST: usb: misc: qcom_eud: add per-path High-Speed PHY control EUD hardware can support multiple High-Speed USB paths, each routed through its own PHY. The active path is selected in hardware via the EUD_PORT_SEL register. As a High-Speed hub, EUD requires access to the High-Speed PHY associated with the active UTMI path. To support this multi-path capability, the driver must manage PHY resources on a per-path basis, ensuring that the PHY for the currently selected path is properly initialized and powered. This patch restructures the driver to implement per-path PHY management. The driver now powers the appropriate PHY based on the selected and enabled UTMI path, ensuring correct operation when EUD is enabled. Supporting this requires describing the available UTMI paths and their corresponding PHYs in Device Tree. This updates DT requirements and is not backward compatible with older DTs that lacked this description. Historically, EUD appeared to work on single-path systems because the USB controller kept the PHY initialized. However, EUD is designed to operate independently of the USB controller and therefore requires explicit PHY control. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-4-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 130 +++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 1a136f8f1ae52..5cebb64f4a672 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -34,26 +35,96 @@ #define EUD_INT_SAFE_MODE BIT(4) #define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE) +struct eud_path { + struct eud_chip *chip; + struct phy *phy; + u8 num; +}; + struct eud_chip { struct device *dev; struct usb_role_switch *role_sw; void __iomem *base; + struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; + bool phy_enabled; u8 port_idx; }; +static int eud_phy_enable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + int ret; + + if (chip->phy_enabled) + return 0; + + path = chip->paths[chip->port_idx]; + if (!path || !path->phy) { + dev_err(chip->dev, "No PHY configured for port %u\n", chip->port_idx); + return -ENODEV; + } + + phy = path->phy; + + ret = phy_init(phy); + if (ret) { + dev_err(chip->dev, "Failed to initialize USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + return ret; + } + + ret = phy_power_on(phy); + if (ret) { + dev_err(chip->dev, "Failed to power on USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + phy_exit(phy); + return ret; + } + + chip->phy_enabled = true; + + return 0; +} + +static void eud_phy_disable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + + if (!chip->phy_enabled) + return; + + path = chip->paths[chip->port_idx]; + if (!path || !path->phy) + return; + + phy = path->phy; + + phy_power_off(phy); + phy_exit(phy); + chip->phy_enabled = false; +} + static int enable_eud(struct eud_chip *priv) { int ret; - ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + ret = eud_phy_enable(priv); if (ret) return ret; + ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + if (ret) { + eud_phy_disable(priv); + return ret; + } + writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); @@ -70,6 +141,8 @@ static int disable_eud(struct eud_chip *priv) return ret; writel(0, priv->base + EUD_REG_CSR_EUD_EN); + eud_phy_disable(priv); + return 0; } @@ -132,6 +205,12 @@ static ssize_t port_store(struct device *dev, if (port >= EUD_MAX_PORTS) return -EINVAL; + /* Check if the corresponding path is available */ + if (!chip->paths[port]) { + dev_err(chip->dev, "EUD not supported on selected port\n"); + return -EOPNOTSUPP; + } + /* Port selection must be done before enabling EUD */ if (chip->enabled) { dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); @@ -231,8 +310,45 @@ static void eud_role_switch_release(void *data) usb_role_switch_put(chip->role_sw); } +static int eud_init_path(struct eud_chip *chip, struct device_node *np) +{ + struct eud_path *path; + u32 path_num; + int ret; + + ret = of_property_read_u32(np, "reg", &path_num); + if (ret) { + dev_err(chip->dev, "Missing 'reg' property in path node\n"); + return ret; + } + + if (path_num >= EUD_MAX_PORTS) { + dev_err(chip->dev, "Invalid path number: %u (max %d)\n", + path_num, EUD_MAX_PORTS - 1); + return -EINVAL; + } + + path = devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL); + if (!path) + return -ENOMEM; + + path->chip = chip; + path->num = path_num; + + path->phy = devm_of_phy_get(chip->dev, np, NULL); + if (IS_ERR(path->phy)) + return dev_err_probe(chip->dev, PTR_ERR(path->phy), + "Failed to get PHY for path %d\n", path_num); + + chip->paths[path_num] = path; + + return 0; +} + static int eud_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + struct device_node *child; struct eud_chip *chip; struct resource *res; int ret; @@ -252,6 +368,18 @@ static int eud_probe(struct platform_device *pdev) if (ret) return ret; + for_each_child_of_node(np, child) { + ret = eud_init_path(chip, child); + if (ret) { + of_node_put(child); + return ret; + } + } + + /* Primary path is mandatory. Secondary is optional */ + if (!chip->paths[0]) + return -ENODEV; + chip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->base)) return PTR_ERR(chip->base); From e7e656c813d8d651e26704a10f9c56a34a2f7e13 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:25 -0800 Subject: [PATCH 008/128] FROMLIST: usb: misc: qcom_eud: add per-path role switch support The EUD hardware can support multiple High-Speed USB paths, each connected to different USB controllers. The current implementation uses a single chip-level role switch, which cannot properly handle multi-path configurations where each path needs independent role management. Since EUD is physically present between the USB connector and the controller, it should also relay the role change requests from the connector. Restructure the driver to support per-path role switches and remove the chip-level role switch. Additionally, as EUD need not modify the USB role upon enabling, remove the unnecessary role switch call from enable_eud(). Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-5-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 80 ++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 5cebb64f4a672..a58022f50484f 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -38,12 +38,15 @@ struct eud_path { struct eud_chip *chip; struct phy *phy; + struct usb_role_switch *controller_sw; + struct usb_role_switch *eud_sw; + enum usb_role curr_role; + char name[16]; u8 num; }; struct eud_chip { struct device *dev; - struct usb_role_switch *role_sw; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; @@ -129,7 +132,7 @@ static int enable_eud(struct eud_chip *priv) writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); - return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); + return 0; } static int disable_eud(struct eud_chip *priv) @@ -287,15 +290,21 @@ static irqreturn_t handle_eud_irq(int irq, void *data) static irqreturn_t handle_eud_irq_thread(int irq, void *data) { struct eud_chip *chip = data; + struct eud_path *path; int ret; + path = chip->paths[chip->port_idx]; + if (!path || !path->controller_sw) + goto clear_irq; + if (chip->usb_attached) - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); +clear_irq: /* set and clear vbus_int_clr[0] to clear interrupt */ writel(BIT(0), chip->base + EUD_REG_VBUS_INT_CLR); writel(0, chip->base + EUD_REG_VBUS_INT_CLR); @@ -303,15 +312,45 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) return IRQ_HANDLED; } +static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) +{ + struct eud_path *path = usb_role_switch_get_drvdata(sw); + int ret; + + /* Forward the role request to the USB controller */ + ret = usb_role_switch_set_role(path->controller_sw, role); + if (ret) { + dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", + usb_role_string(role), path->num, ret); + return ret; + } + + path->curr_role = role; + + return 0; +} + static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; + int i; - usb_role_switch_put(chip->role_sw); + for (i = 0; i < EUD_MAX_PORTS; i++) { + struct eud_path *path = chip->paths[i]; + + if (!path) + continue; + + if (path->eud_sw) + usb_role_switch_unregister(path->eud_sw); + if (path->controller_sw) + usb_role_switch_put(path->controller_sw); + } } static int eud_init_path(struct eud_chip *chip, struct device_node *np) { + struct usb_role_switch_desc role_sw_desc = {}; struct eud_path *path; u32 path_num; int ret; @@ -342,6 +381,32 @@ static int eud_init_path(struct eud_chip *chip, struct device_node *np) chip->paths[path_num] = path; + path->curr_role = USB_ROLE_NONE; + + if (!of_property_read_bool(np, "usb-role-switch")) + return 0; + + /* Fetch the USB controller's role switch */ + path->controller_sw = fwnode_usb_role_switch_get(of_fwnode_handle(np)); + if (IS_ERR(path->controller_sw)) + return dev_err_probe(chip->dev, PTR_ERR(path->controller_sw), + "Failed to get controller role switch for path %d\n", + path_num); + + /* Create a role switch */ + role_sw_desc.fwnode = of_fwnode_handle(np); + role_sw_desc.set = eud_role_switch_set; + role_sw_desc.driver_data = path; + snprintf(path->name, sizeof(path->name), "eud-path%u", path_num); + role_sw_desc.name = path->name; + + path->eud_sw = usb_role_switch_register(chip->dev, &role_sw_desc); + if (IS_ERR(path->eud_sw)) { + dev_err(chip->dev, "Failed to register EUD role switch for path %d: %ld\n", + path_num, PTR_ERR(path->eud_sw)); + return PTR_ERR(path->eud_sw); + } + return 0; } @@ -359,11 +424,6 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; - chip->role_sw = usb_role_switch_get(&pdev->dev); - if (IS_ERR(chip->role_sw)) - return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), - "failed to get role switch\n"); - ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From eb5da51b8cba5fc4ed3bd699d2cce066020e3415 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:26 -0800 Subject: [PATCH 009/128] FROMLIST: usb: misc: qcom_eud: improve enable_store API Currently enable_store() allows operations irrespective of the EUD state, which can result in redundant operations. Avoid this by adding duplicate state checks to skip requests when EUD is already in the desired state. Additionally, improve error handling with explicit logging to provide better feedback. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-6-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index a58022f50484f..0ea6491f963ce 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -168,18 +168,27 @@ static ssize_t enable_store(struct device *dev, if (kstrtobool(buf, &enable)) return -EINVAL; + /* Skip operation if already in desired state */ + if (chip->enabled == enable) + return count; + if (enable) { ret = enable_eud(chip); - if (!ret) - chip->enabled = enable; - else - disable_eud(chip); - + if (ret) { + dev_err(chip->dev, "failed to enable eud\n"); + return ret; + } } else { ret = disable_eud(chip); + if (ret) { + dev_err(chip->dev, "failed to disable eud\n"); + return ret; + } } - return ret < 0 ? ret : count; + chip->enabled = enable; + + return count; } static DEVICE_ATTR_RW(enable); From 583d6fc0f35f15b14ebed9dd244a7ba4bf845496 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:27 -0800 Subject: [PATCH 010/128] FROMLIST: usb: misc: qcom_eud: add host mode coordination EUD functions by presenting itself as a USB device to the host PC for debugging, making it incompatible in USB host mode configurations. Enabling EUD, when in host mode can also cause the USB controller to misbehave as the EUD hub can only have one upstream facing port. Handle below two scenarios to prevent these conflicts: 1. Prevent user from enabling EUD via sysfs when the USB port is in host mode. 2. Automatically disable EUD when USB port switches to host mode and re-enable it when exiting host mode. This ensures consistent state management without creating conflicts between the EUD debug hub and the USB controller. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-7-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 79 ++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 0ea6491f963ce..3f1cc7ea2a6ae 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -49,12 +49,15 @@ struct eud_chip { struct device *dev; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; + /* serializes EUD control operations */ + struct mutex state_lock; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; bool phy_enabled; + bool eud_disabled_for_host; u8 port_idx; }; @@ -162,32 +165,66 @@ static ssize_t enable_store(struct device *dev, const char *buf, size_t count) { struct eud_chip *chip = dev_get_drvdata(dev); + struct eud_path *path; bool enable; int ret; if (kstrtobool(buf, &enable)) return -EINVAL; + mutex_lock(&chip->state_lock); + /* Skip operation if already in desired state */ - if (chip->enabled == enable) + if (chip->enabled == enable) { + mutex_unlock(&chip->state_lock); return count; + } + + /* + * Handle double-disable scenario: User is disabling EUD that was already + * disabled due to host mode. Since the hardware is already disabled, we + * only need to clear the host-disabled flag to prevent unwanted re-enabling + * when exiting host mode. This respects the user's explicit disable request. + */ + if (!enable && chip->eud_disabled_for_host) { + chip->eud_disabled_for_host = false; + chip->enabled = false; + mutex_unlock(&chip->state_lock); + return count; + } if (enable) { + /* + * EUD functions by presenting itself as a USB device to the host PC for + * debugging, making it incompatible in USB host mode configuration. + * Prevent enabling EUD in this configuration to avoid hardware conflicts. + */ + path = chip->paths[chip->port_idx]; + if (path && path->curr_role == USB_ROLE_HOST) { + dev_err(chip->dev, "EUD not usable in host mode configuration\n"); + mutex_unlock(&chip->state_lock); + return -EBUSY; + } + ret = enable_eud(chip); if (ret) { dev_err(chip->dev, "failed to enable eud\n"); + mutex_unlock(&chip->state_lock); return ret; } } else { ret = disable_eud(chip); if (ret) { dev_err(chip->dev, "failed to disable eud\n"); + mutex_unlock(&chip->state_lock); return ret; } } chip->enabled = enable; + mutex_unlock(&chip->state_lock); + return count; } @@ -324,18 +361,56 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) { struct eud_path *path = usb_role_switch_get_drvdata(sw); + struct eud_chip *chip = path->chip; int ret; + mutex_lock(&chip->state_lock); + + /* + * EUD must be disabled when USB operates in host mode. EUD functions by + * presenting itself as a USB device to the host PC for debugging, making + * it incompatible in host mode configuration. + * + * chip->enabled preserves user's sysfs configuration and is not modified + * during host mode transitions to maintain user intent. + */ + + /* Only act if EUD is enabled and this is the active path */ + if (chip->enabled && path->num == chip->port_idx) { + if (role == USB_ROLE_HOST && !chip->eud_disabled_for_host) { + ret = disable_eud(chip); + if (ret) { + dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n", + ret); + mutex_unlock(&chip->state_lock); + return ret; + } + chip->eud_disabled_for_host = true; + } else if (role != USB_ROLE_HOST && chip->eud_disabled_for_host) { + ret = enable_eud(chip); + if (ret) { + dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n", + ret); + mutex_unlock(&chip->state_lock); + return ret; + } + chip->eud_disabled_for_host = false; + } + } + /* Forward the role request to the USB controller */ ret = usb_role_switch_set_role(path->controller_sw, role); if (ret) { dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", usb_role_string(role), path->num, ret); + mutex_unlock(&chip->state_lock); return ret; } path->curr_role = role; + mutex_unlock(&chip->state_lock); + return 0; } @@ -433,6 +508,8 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; + mutex_init(&chip->state_lock); + ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From 7104631aca14a5f01ee8f33ebbfda4c2e4047d28 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:28 -0800 Subject: [PATCH 011/128] FROMLIST: usb: misc: qcom_eud: fix virtual attach/detach event handling EUD provides virtual USB attach/detach events to simulate cable plug/unplug while maintaining the physical debug connection. However, the current implementation incorrectly sets the USB role to HOST on virtual detach, which doesn't represent the disconnected state. Fix the virtual detach handling by setting the USB role to NONE instead of HOST, correctly representing the disconnected state. Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio https://lore.kernel.org/linux-usb/20260126233830.2193816-8-elson.serrao@oss.qualcomm.com/ --- drivers/usb/misc/qcom_eud.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 3f1cc7ea2a6ae..60f566427abe2 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -343,10 +343,26 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) if (!path || !path->controller_sw) goto clear_irq; + /* + * EUD virtual attach/detach event handling for low power debugging: + * + * When EUD is enabled in debug mode, the device remains physically + * connected to the PC throughout the debug session, keeping the USB + * controller active. This prevents testing of low power scenarios that + * require USB disconnection. + * + * EUD solves this by providing virtual USB attach/detach events while + * maintaining the physical connection. These events are triggered from + * the Host PC via the enumerated EUD control interface and delivered + * to the EUD driver as interrupts. + * + * These notifications are forwarded to the USB controller through role + * switch framework. + */ if (chip->usb_attached) ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_NONE); if (ret) dev_err(chip->dev, "failed to set role switch\n"); From 6260765ea4de159fe357a6006cb323d6d831f808 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:29 -0800 Subject: [PATCH 012/128] FROMLIST: arm64: dts: qcom: kodiak: Align EUD node with binding The EUD node does not match the current binding and maps USB endpoints to the secondary controller. This SoC supports EUD only on the primary High-Speed USB path. The binding also requires a per-path PHY reference. Model the primary UTMI path as a child node with the required PHY and an empty ports graph. Leave endpoint mapping to board DTS files, and remove the secondary mapping and associated ports so the description conforms to the binding. Signed-off-by: Elson Serrao iLink: https://lore.kernel.org/linux-usb/20260126233830.2193816-9-elson.serrao@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 33 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 6079e67ea829b..5d40ffb06e4b7 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4294,12 +4294,6 @@ phy-names = "usb2-phy"; maximum-speed = "high-speed"; usb-role-switch; - - port { - usb2_role_switch: endpoint { - remote-endpoint = <&eud_ep>; - }; - }; }; qspi: spi@88dc000 { @@ -4623,16 +4617,29 @@ <0 0x88e2000 0 0x1000>; interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; - ports { - #address-cells = <1>; - #size-cells = <0>; + eud0: eud-path@0 { + reg = <0>; + phys = <&usb_1_hsphy>; - port@0 { - reg = <0>; - eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + eud_usb0: endpoint { + }; + }; + + port@1 { + reg = <1>; + eud_con0: endpoint { + }; }; }; }; From 2a45fc0d2177da2930062afb734ffc8b3928f993 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Mon, 26 Jan 2026 15:38:30 -0800 Subject: [PATCH 013/128] FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality On this board, EUD resides on the primary High-Speed USB data path between the connector and the DWC3 controller. Update the device tree connections to correctly map the connector and controller endpoints, and describe role-switch capability on the EUD primary path. Signed-off-by: Elson Serrao Link: https://lore.kernel.org/linux-usb/20260126233830.2193816-10-elson.serrao@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index e3d2f01881ae0..293c390094051 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -194,7 +194,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con0>; }; }; @@ -1304,13 +1304,29 @@ }; &usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; + remote-endpoint = <&eud_usb0>; }; &usb_1_dwc3_ss { remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; }; +&eud_con0 { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&eud_usb0 { + remote-endpoint = <&usb_1_dwc3_hs>; +}; + +&eud { + status = "okay"; +}; + +&eud0 { + usb-role-switch; +}; + &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; From f1167ebe1be1a91e0e06d2de0625184149fe928c Mon Sep 17 00:00:00 2001 From: Jan Remmet Date: Fri, 23 Jan 2026 15:52:37 +0100 Subject: [PATCH 014/128] FROMLIST: usb: typec: hd3ss3220: Enable VBUS based on role state For systems where the ID pin isn't available as gpio use the ATTACHED_STATE register instead to control vbus. >From the datasheet: "This is an additional method to communicate attach other than the ID pin. These bits can be read by the application to determine what was attached." Use this method if id-gpios property is not set, but the connector node has vbus-supply defined. Check regulator state as peripheral and detach can disable vbus. Signed-off-by: Jan Remmet From a84e6baf590a78e6465888285500987bb6752e01 Mon Sep 17 00:00:00 2001 From: Swati Agarwal Date: Mon, 16 Feb 2026 01:35:33 +0530 Subject: [PATCH 015/128] FROMLIST: usb: typec: hd3ss3220: Add wakeup support from system suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HD3SS3220's interrupt is disabled during system suspend, so a USB‑C cable connect/attach event cannot wake the system. This prevents resume from low‑power modes when the port controller is expected to act as a wakeup source. Add wakeup support by: - Initialize the device as wakeup‑capable. - Enable the HD3SS3220 IRQ as a wakeup interrupt. - Add suspend/resume callbacks to enable or disable the IRQ for wakeup depending on the device's wakeup configuration. With this, USB‑C cable insertion correctly wakes the system from suspend. Link: https://lore.kernel.org/all/20260215183325.3836178-2-swati.agarwal@oss.qualcomm.com/ Signed-off-by: Swati Agarwal --- drivers/usb/typec/hd3ss3220.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index 3e39b800e6b5f..b56df9349f89b 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -501,6 +501,11 @@ static int hd3ss3220_probe(struct i2c_client *client) if (hd3ss3220->poll) schedule_delayed_work(&hd3ss3220->output_poll_work, HZ); + if (client->irq && device_property_read_bool(hd3ss3220->dev, "wakeup-source")) { + device_init_wakeup(&client->dev, true); + enable_irq_wake(client->irq); + } + dev_info(&client->dev, "probed revision=0x%x\n", ret); return 0; @@ -525,6 +530,35 @@ static void hd3ss3220_remove(struct i2c_client *client) usb_role_switch_put(hd3ss3220->role_sw); } +static int __maybe_unused hd3ss3220_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(client->irq); + else + disable_irq(client->irq); + + return 0; +} + +static int __maybe_unused hd3ss3220_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(client->irq); + else + enable_irq(client->irq); + + return 0; +} + +static const struct dev_pm_ops hd3ss3220_pm_ops = { + .suspend = hd3ss3220_suspend, + .resume = hd3ss3220_resume, +}; + static const struct of_device_id dev_ids[] = { { .compatible = "ti,hd3ss3220"}, {} @@ -535,6 +569,7 @@ static struct i2c_driver hd3ss3220_driver = { .driver = { .name = "hd3ss3220", .of_match_table = dev_ids, + .pm = &hd3ss3220_pm_ops, }, .probe = hd3ss3220_probe, .remove = hd3ss3220_remove, From 7beb7c17e03d159344721a7c65488d1f3eb36113 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Fri, 20 Feb 2026 16:01:25 +0530 Subject: [PATCH 016/128] Revert "FROMLIST: arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality" This reverts commit e65028c6aae9f531066bdfc487454ed45e0834a9. Issue is observed with this commit e65028c6aae9f531066bdfc487454ed45e0834a9 leading to crash, with following call stack [ 19.706310][ T73] Call trace: [ 19.706312][ T73] usb_role_switch_unregister+0x28/0x70 (P) [ 19.706319][ T73] eud_role_switch_release+0x30/0x78 [qcom_eud] [ 19.884972][ T73] devm_action_release+0x1c/0x30 [ 19.884981][ T73] release_nodes+0x70/0x120 [ 19.884987][ T73] devres_release_all+0x98/0xf0 [ 19.884995][ T73] device_unbind_cleanup+0x20/0x98 [ 19.885000][ T73] really_probe+0x184/0x3f0 [ 19.885005][ T73] __driver_probe_device+0x88/0x190 [ 19.885010][ T73] driver_probe_device+0x44/0x120 [ 19.885015][ T73] __device_attach_driver+0xc4/0x178 [ 19.885020][ T73] bus_for_each_drv+0x90/0xf8 [ 19.885027][ T73] __device_attach+0xa8/0x1d8 [ 19.885032][ T73] device_initial_probe+0x58/0x68 [ 19.885037][ T73] bus_probe_device+0x40/0xb8 [ 19.885041][ T73] deferred_probe_work_func+0xbc/0x128 [ 19.885046][ T73] process_one_work+0x180/0x450 [ 19.885055][ T73] worker_thread+0x26c/0x388 [ 19.885062][ T73] kthread+0x120/0x140 [ 19.885068][ T73] ret_from_fork+0x10/0x20 [ 19.885079][ T73] Code: f9000bf3 aa0003f3 b140041f 54000168 (390c901f) [ 19.885083][ T73] ---[ end trace 0000000000000000 ]--- [ 19.885088][ T73] Kernel panic - not syncing: Oops: Fatal exception [ 19.885091][ T73] SMP: stopping secondary CPUs Revert commit for now. Signed-off-by: Salendarsingh Gaud --- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index 293c390094051..e3d2f01881ae0 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -194,7 +194,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&eud_con0>; + remote-endpoint = <&usb_1_dwc3_hs>; }; }; @@ -1304,29 +1304,13 @@ }; &usb_1_dwc3_hs { - remote-endpoint = <&eud_usb0>; + remote-endpoint = <&pmic_glink_hs_in>; }; &usb_1_dwc3_ss { remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; }; -&eud_con0 { - remote-endpoint = <&pmic_glink_hs_in>; -}; - -&eud_usb0 { - remote-endpoint = <&usb_1_dwc3_hs>; -}; - -&eud { - status = "okay"; -}; - -&eud0 { - usb-role-switch; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; From 4b0295a95fb1d7b7e2c6052883e8eb0a4620f7b5 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Fri, 20 Feb 2026 16:02:45 +0530 Subject: [PATCH 017/128] Revert "FROMLIST: arm64: dts: qcom: kodiak: Align EUD node with binding" This reverts commit 09ed0b6ddc99b87f0fb3141a9c4d55f015329c5c. Issue is observed with this commit 09ed0b6ddc99b87f0fb3141a9c4d55f015329c5c leading to crash, with following call stack [ 19.706310][ T73] Call trace: [ 19.706312][ T73] usb_role_switch_unregister+0x28/0x70 (P) [ 19.706319][ T73] eud_role_switch_release+0x30/0x78 [qcom_eud] [ 19.884972][ T73] devm_action_release+0x1c/0x30 [ 19.884981][ T73] release_nodes+0x70/0x120 [ 19.884987][ T73] devres_release_all+0x98/0xf0 [ 19.884995][ T73] device_unbind_cleanup+0x20/0x98 [ 19.885000][ T73] really_probe+0x184/0x3f0 [ 19.885005][ T73] __driver_probe_device+0x88/0x190 [ 19.885010][ T73] driver_probe_device+0x44/0x120 [ 19.885015][ T73] __device_attach_driver+0xc4/0x178 [ 19.885020][ T73] bus_for_each_drv+0x90/0xf8 [ 19.885027][ T73] __device_attach+0xa8/0x1d8 [ 19.885032][ T73] device_initial_probe+0x58/0x68 [ 19.885037][ T73] bus_probe_device+0x40/0xb8 [ 19.885041][ T73] deferred_probe_work_func+0xbc/0x128 [ 19.885046][ T73] process_one_work+0x180/0x450 [ 19.885055][ T73] worker_thread+0x26c/0x388 [ 19.885062][ T73] kthread+0x120/0x140 [ 19.885068][ T73] ret_from_fork+0x10/0x20 [ 19.885079][ T73] Code: f9000bf3 aa0003f3 b140041f 54000168 (390c901f) [ 19.885083][ T73] ---[ end trace 0000000000000000 ]--- [ 19.885088][ T73] Kernel panic - not syncing: Oops: Fatal exception [ 19.885091][ T73] SMP: stopping secondary CPUs Revert commit for now. Signed-off-by: Salendarsingh Gaud --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 33 +++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 5d40ffb06e4b7..6079e67ea829b 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4294,6 +4294,12 @@ phy-names = "usb2-phy"; maximum-speed = "high-speed"; usb-role-switch; + + port { + usb2_role_switch: endpoint { + remote-endpoint = <&eud_ep>; + }; + }; }; qspi: spi@88dc000 { @@ -4617,29 +4623,16 @@ <0 0x88e2000 0 0x1000>; interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - eud0: eud-path@0 { - reg = <0>; - phys = <&usb_1_hsphy>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - eud_usb0: endpoint { - }; - }; + ports { + #address-cells = <1>; + #size-cells = <0>; - port@1 { - reg = <1>; - eud_con0: endpoint { - }; + port@0 { + reg = <0>; + eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; }; }; }; From 8ff3106a1681c29e724960cb68010ec5e2d27d28 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:19:50 -0700 Subject: [PATCH 018/128] Revert "FROMLIST: usb: misc: qcom_eud: fix virtual attach/detach event handling" This reverts commit 7104631aca14a5f01ee8f33ebbfda4c2e4047d28. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 60f566427abe2..3f1cc7ea2a6ae 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -343,26 +343,10 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) if (!path || !path->controller_sw) goto clear_irq; - /* - * EUD virtual attach/detach event handling for low power debugging: - * - * When EUD is enabled in debug mode, the device remains physically - * connected to the PC throughout the debug session, keeping the USB - * controller active. This prevents testing of low power scenarios that - * require USB disconnection. - * - * EUD solves this by providing virtual USB attach/detach events while - * maintaining the physical connection. These events are triggered from - * the Host PC via the enumerated EUD control interface and delivered - * to the EUD driver as interrupts. - * - * These notifications are forwarded to the USB controller through role - * switch framework. - */ if (chip->usb_attached) ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_NONE); + ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); From babfcf55f3137b7ccfeace477c906ed290abf60f Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:20:22 -0700 Subject: [PATCH 019/128] Revert "FROMLIST: usb: misc: qcom_eud: add host mode coordination" This reverts commit 583d6fc0f35f15b14ebed9dd244a7ba4bf845496. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 79 +------------------------------------ 1 file changed, 1 insertion(+), 78 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 3f1cc7ea2a6ae..0ea6491f963ce 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -49,15 +49,12 @@ struct eud_chip { struct device *dev; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; - /* serializes EUD control operations */ - struct mutex state_lock; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; bool phy_enabled; - bool eud_disabled_for_host; u8 port_idx; }; @@ -165,66 +162,32 @@ static ssize_t enable_store(struct device *dev, const char *buf, size_t count) { struct eud_chip *chip = dev_get_drvdata(dev); - struct eud_path *path; bool enable; int ret; if (kstrtobool(buf, &enable)) return -EINVAL; - mutex_lock(&chip->state_lock); - /* Skip operation if already in desired state */ - if (chip->enabled == enable) { - mutex_unlock(&chip->state_lock); + if (chip->enabled == enable) return count; - } - - /* - * Handle double-disable scenario: User is disabling EUD that was already - * disabled due to host mode. Since the hardware is already disabled, we - * only need to clear the host-disabled flag to prevent unwanted re-enabling - * when exiting host mode. This respects the user's explicit disable request. - */ - if (!enable && chip->eud_disabled_for_host) { - chip->eud_disabled_for_host = false; - chip->enabled = false; - mutex_unlock(&chip->state_lock); - return count; - } if (enable) { - /* - * EUD functions by presenting itself as a USB device to the host PC for - * debugging, making it incompatible in USB host mode configuration. - * Prevent enabling EUD in this configuration to avoid hardware conflicts. - */ - path = chip->paths[chip->port_idx]; - if (path && path->curr_role == USB_ROLE_HOST) { - dev_err(chip->dev, "EUD not usable in host mode configuration\n"); - mutex_unlock(&chip->state_lock); - return -EBUSY; - } - ret = enable_eud(chip); if (ret) { dev_err(chip->dev, "failed to enable eud\n"); - mutex_unlock(&chip->state_lock); return ret; } } else { ret = disable_eud(chip); if (ret) { dev_err(chip->dev, "failed to disable eud\n"); - mutex_unlock(&chip->state_lock); return ret; } } chip->enabled = enable; - mutex_unlock(&chip->state_lock); - return count; } @@ -361,56 +324,18 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) { struct eud_path *path = usb_role_switch_get_drvdata(sw); - struct eud_chip *chip = path->chip; int ret; - mutex_lock(&chip->state_lock); - - /* - * EUD must be disabled when USB operates in host mode. EUD functions by - * presenting itself as a USB device to the host PC for debugging, making - * it incompatible in host mode configuration. - * - * chip->enabled preserves user's sysfs configuration and is not modified - * during host mode transitions to maintain user intent. - */ - - /* Only act if EUD is enabled and this is the active path */ - if (chip->enabled && path->num == chip->port_idx) { - if (role == USB_ROLE_HOST && !chip->eud_disabled_for_host) { - ret = disable_eud(chip); - if (ret) { - dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n", - ret); - mutex_unlock(&chip->state_lock); - return ret; - } - chip->eud_disabled_for_host = true; - } else if (role != USB_ROLE_HOST && chip->eud_disabled_for_host) { - ret = enable_eud(chip); - if (ret) { - dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n", - ret); - mutex_unlock(&chip->state_lock); - return ret; - } - chip->eud_disabled_for_host = false; - } - } - /* Forward the role request to the USB controller */ ret = usb_role_switch_set_role(path->controller_sw, role); if (ret) { dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", usb_role_string(role), path->num, ret); - mutex_unlock(&chip->state_lock); return ret; } path->curr_role = role; - mutex_unlock(&chip->state_lock); - return 0; } @@ -508,8 +433,6 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; - mutex_init(&chip->state_lock); - ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From f3d669d81f43dc68c5d245a8d9a159916f883d3b Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:20:39 -0700 Subject: [PATCH 020/128] Revert "FROMLIST: usb: misc: qcom_eud: improve enable_store API" This reverts commit eb5da51b8cba5fc4ed3bd699d2cce066020e3415. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 0ea6491f963ce..a58022f50484f 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -168,27 +168,18 @@ static ssize_t enable_store(struct device *dev, if (kstrtobool(buf, &enable)) return -EINVAL; - /* Skip operation if already in desired state */ - if (chip->enabled == enable) - return count; - if (enable) { ret = enable_eud(chip); - if (ret) { - dev_err(chip->dev, "failed to enable eud\n"); - return ret; - } + if (!ret) + chip->enabled = enable; + else + disable_eud(chip); + } else { ret = disable_eud(chip); - if (ret) { - dev_err(chip->dev, "failed to disable eud\n"); - return ret; - } } - chip->enabled = enable; - - return count; + return ret < 0 ? ret : count; } static DEVICE_ATTR_RW(enable); From 5c037c925f08962ad5bcea6947087e1bc0bca234 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:21:03 -0700 Subject: [PATCH 021/128] Revert "FROMLIST: usb: misc: qcom_eud: add per-path role switch support" This reverts commit e7e656c813d8d651e26704a10f9c56a34a2f7e13. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 80 +++++-------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index a58022f50484f..5cebb64f4a672 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -38,15 +38,12 @@ struct eud_path { struct eud_chip *chip; struct phy *phy; - struct usb_role_switch *controller_sw; - struct usb_role_switch *eud_sw; - enum usb_role curr_role; - char name[16]; u8 num; }; struct eud_chip { struct device *dev; + struct usb_role_switch *role_sw; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; @@ -132,7 +129,7 @@ static int enable_eud(struct eud_chip *priv) writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); - return 0; + return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); } static int disable_eud(struct eud_chip *priv) @@ -290,21 +287,15 @@ static irqreturn_t handle_eud_irq(int irq, void *data) static irqreturn_t handle_eud_irq_thread(int irq, void *data) { struct eud_chip *chip = data; - struct eud_path *path; int ret; - path = chip->paths[chip->port_idx]; - if (!path || !path->controller_sw) - goto clear_irq; - if (chip->usb_attached) - ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); + ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); -clear_irq: /* set and clear vbus_int_clr[0] to clear interrupt */ writel(BIT(0), chip->base + EUD_REG_VBUS_INT_CLR); writel(0, chip->base + EUD_REG_VBUS_INT_CLR); @@ -312,45 +303,15 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) return IRQ_HANDLED; } -static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role) -{ - struct eud_path *path = usb_role_switch_get_drvdata(sw); - int ret; - - /* Forward the role request to the USB controller */ - ret = usb_role_switch_set_role(path->controller_sw, role); - if (ret) { - dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n", - usb_role_string(role), path->num, ret); - return ret; - } - - path->curr_role = role; - - return 0; -} - static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; - int i; - for (i = 0; i < EUD_MAX_PORTS; i++) { - struct eud_path *path = chip->paths[i]; - - if (!path) - continue; - - if (path->eud_sw) - usb_role_switch_unregister(path->eud_sw); - if (path->controller_sw) - usb_role_switch_put(path->controller_sw); - } + usb_role_switch_put(chip->role_sw); } static int eud_init_path(struct eud_chip *chip, struct device_node *np) { - struct usb_role_switch_desc role_sw_desc = {}; struct eud_path *path; u32 path_num; int ret; @@ -381,32 +342,6 @@ static int eud_init_path(struct eud_chip *chip, struct device_node *np) chip->paths[path_num] = path; - path->curr_role = USB_ROLE_NONE; - - if (!of_property_read_bool(np, "usb-role-switch")) - return 0; - - /* Fetch the USB controller's role switch */ - path->controller_sw = fwnode_usb_role_switch_get(of_fwnode_handle(np)); - if (IS_ERR(path->controller_sw)) - return dev_err_probe(chip->dev, PTR_ERR(path->controller_sw), - "Failed to get controller role switch for path %d\n", - path_num); - - /* Create a role switch */ - role_sw_desc.fwnode = of_fwnode_handle(np); - role_sw_desc.set = eud_role_switch_set; - role_sw_desc.driver_data = path; - snprintf(path->name, sizeof(path->name), "eud-path%u", path_num); - role_sw_desc.name = path->name; - - path->eud_sw = usb_role_switch_register(chip->dev, &role_sw_desc); - if (IS_ERR(path->eud_sw)) { - dev_err(chip->dev, "Failed to register EUD role switch for path %d: %ld\n", - path_num, PTR_ERR(path->eud_sw)); - return PTR_ERR(path->eud_sw); - } - return 0; } @@ -424,6 +359,11 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; + chip->role_sw = usb_role_switch_get(&pdev->dev); + if (IS_ERR(chip->role_sw)) + return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), + "failed to get role switch\n"); + ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From df9ad41e7c8c4b5c291a31c6f3b8d57f8796cd60 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:21:33 -0700 Subject: [PATCH 022/128] Revert "FROMLIST: usb: misc: qcom_eud: add per-path High-Speed PHY control" This reverts commit e2541a8409a99af58825af0a54178d0b26677f5b. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 130 +----------------------------------- 1 file changed, 1 insertion(+), 129 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 5cebb64f4a672..1a136f8f1ae52 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -35,95 +34,25 @@ #define EUD_INT_SAFE_MODE BIT(4) #define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE) -struct eud_path { - struct eud_chip *chip; - struct phy *phy; - u8 num; -}; - struct eud_chip { struct device *dev; struct usb_role_switch *role_sw; void __iomem *base; - struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; - bool phy_enabled; u8 port_idx; }; -static int eud_phy_enable(struct eud_chip *chip) -{ - struct eud_path *path; - struct phy *phy; - int ret; - - if (chip->phy_enabled) - return 0; - - path = chip->paths[chip->port_idx]; - if (!path || !path->phy) { - dev_err(chip->dev, "No PHY configured for port %u\n", chip->port_idx); - return -ENODEV; - } - - phy = path->phy; - - ret = phy_init(phy); - if (ret) { - dev_err(chip->dev, "Failed to initialize USB2 PHY for port %u: %d\n", - chip->port_idx, ret); - return ret; - } - - ret = phy_power_on(phy); - if (ret) { - dev_err(chip->dev, "Failed to power on USB2 PHY for port %u: %d\n", - chip->port_idx, ret); - phy_exit(phy); - return ret; - } - - chip->phy_enabled = true; - - return 0; -} - -static void eud_phy_disable(struct eud_chip *chip) -{ - struct eud_path *path; - struct phy *phy; - - if (!chip->phy_enabled) - return; - - path = chip->paths[chip->port_idx]; - if (!path || !path->phy) - return; - - phy = path->phy; - - phy_power_off(phy); - phy_exit(phy); - chip->phy_enabled = false; -} - static int enable_eud(struct eud_chip *priv) { int ret; - ret = eud_phy_enable(priv); - if (ret) - return ret; - ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); - if (ret) { - eud_phy_disable(priv); + if (ret) return ret; - } writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, @@ -141,8 +70,6 @@ static int disable_eud(struct eud_chip *priv) return ret; writel(0, priv->base + EUD_REG_CSR_EUD_EN); - eud_phy_disable(priv); - return 0; } @@ -205,12 +132,6 @@ static ssize_t port_store(struct device *dev, if (port >= EUD_MAX_PORTS) return -EINVAL; - /* Check if the corresponding path is available */ - if (!chip->paths[port]) { - dev_err(chip->dev, "EUD not supported on selected port\n"); - return -EOPNOTSUPP; - } - /* Port selection must be done before enabling EUD */ if (chip->enabled) { dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); @@ -310,45 +231,8 @@ static void eud_role_switch_release(void *data) usb_role_switch_put(chip->role_sw); } -static int eud_init_path(struct eud_chip *chip, struct device_node *np) -{ - struct eud_path *path; - u32 path_num; - int ret; - - ret = of_property_read_u32(np, "reg", &path_num); - if (ret) { - dev_err(chip->dev, "Missing 'reg' property in path node\n"); - return ret; - } - - if (path_num >= EUD_MAX_PORTS) { - dev_err(chip->dev, "Invalid path number: %u (max %d)\n", - path_num, EUD_MAX_PORTS - 1); - return -EINVAL; - } - - path = devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL); - if (!path) - return -ENOMEM; - - path->chip = chip; - path->num = path_num; - - path->phy = devm_of_phy_get(chip->dev, np, NULL); - if (IS_ERR(path->phy)) - return dev_err_probe(chip->dev, PTR_ERR(path->phy), - "Failed to get PHY for path %d\n", path_num); - - chip->paths[path_num] = path; - - return 0; -} - static int eud_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; - struct device_node *child; struct eud_chip *chip; struct resource *res; int ret; @@ -368,18 +252,6 @@ static int eud_probe(struct platform_device *pdev) if (ret) return ret; - for_each_child_of_node(np, child) { - ret = eud_init_path(chip, child); - if (ret) { - of_node_put(child); - return ret; - } - } - - /* Primary path is mandatory. Secondary is optional */ - if (!chip->paths[0]) - return -ENODEV; - chip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->base)) return PTR_ERR(chip->base); From f9edf40bf40a76327ed3ed0d77de822a9a55db76 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:21:52 -0700 Subject: [PATCH 023/128] Revert "FROMLIST: usb: misc: qcom_eud: add sysfs attribute for port selection" This reverts commit c042ed7b42aff071249d6a1b91cedb7170e2d2d4. Signed-off-by: Elson Serrao --- Documentation/ABI/testing/sysfs-driver-eud | 16 -------- drivers/usb/misc/qcom_eud.c | 43 ---------------------- 2 files changed, 59 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud index 67223f73ee606..2bab0db2d2f0f 100644 --- a/Documentation/ABI/testing/sysfs-driver-eud +++ b/Documentation/ABI/testing/sysfs-driver-eud @@ -7,19 +7,3 @@ Description: EUD based on a 1 or a 0 value. By enabling EUD, the user is able to activate the mini-usb hub of EUD for debug and trace capabilities. - -What: /sys/bus/platform/drivers/qcom_eud/.../port -Date: January 2026 -Contact: Elson Serrao -Description: - Selects which USB port the Embedded USB Debugger (EUD) - is mapped to on platforms providing multiple High-Speed - USB ports. - - Valid values: - 0 - Primary USB port - 1 - Secondary USB port - - The attribute is writable only while EUD is disabled. - Reading the attribute returns the currently selected - USB port number. diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 1a136f8f1ae52..926419ca560fc 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -23,11 +23,8 @@ #define EUD_REG_VBUS_INT_CLR 0x0080 #define EUD_REG_CSR_EUD_EN 0x1014 #define EUD_REG_SW_ATTACH_DET 0x1018 -#define EUD_REG_PORT_SEL 0x1028 #define EUD_REG_EUD_EN2 0x0000 -#define EUD_MAX_PORTS 2 - #define EUD_ENABLE BIT(0) #define EUD_INT_PET_EUD BIT(0) #define EUD_INT_VBUS BIT(2) @@ -43,7 +40,6 @@ struct eud_chip { int irq; bool enabled; bool usb_attached; - u8 port_idx; }; static int enable_eud(struct eud_chip *priv) @@ -108,47 +104,8 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR_RW(enable); -static ssize_t port_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct eud_chip *chip = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%u\n", chip->port_idx); -} - -static ssize_t port_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct eud_chip *chip = dev_get_drvdata(dev); - u8 port; - int ret; - - ret = kstrtou8(buf, 0, &port); - if (ret) - return ret; - - /* Only port 0 and port 1 are valid */ - if (port >= EUD_MAX_PORTS) - return -EINVAL; - - /* Port selection must be done before enabling EUD */ - if (chip->enabled) { - dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); - return -EBUSY; - } - - writel(port, chip->base + EUD_REG_PORT_SEL); - chip->port_idx = port; - - return count; -} - -static DEVICE_ATTR_RW(port); - static struct attribute *eud_attrs[] = { &dev_attr_enable.attr, - &dev_attr_port.attr, NULL, }; ATTRIBUTE_GROUPS(eud); From b69ce290813718b70d49f032811faee30bf77487 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:22:10 -0700 Subject: [PATCH 024/128] Revert "FROMLIST: dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware" This reverts commit cfe135bf3401dee9bbb5c726594894cc453d28ea. Signed-off-by: Elson Serrao --- .../bindings/soc/qcom/qcom,eud.yaml | 100 +++++------------- 1 file changed, 26 insertions(+), 74 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml index 0507252dbf27e..84218636c0d8d 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml @@ -10,11 +10,8 @@ maintainers: - Souradeep Chowdhury description: - This binding describes the Qualcomm Embedded USB Debugger (EUD), an on-chip - mini USB hub that enables USB-based debug capabilities. The EUD block is - positioned between the High-Speed USB PHY and the USB controller, where it - intercepts the UTMI interface to support debug and bypass modes. EUD can be - supported on up to two High-Speed USB ports. + This binding is used to describe the Qualcomm Embedded USB Debugger, which is + mini USB-hub implemented on chip to support USB-based debug capabilities. properties: compatible: @@ -32,62 +29,26 @@ properties: description: EUD interrupt maxItems: 1 - '#address-cells': - const: 1 - - '#size-cells': - const: 0 - -patternProperties: - "^eud-path@[0-1]$": - type: object + ports: + $ref: /schemas/graph.yaml#/properties/ports description: - Represents one High-Speed UTMI path that EUD intercepts. This node models - the physical data path intercepted by EUD and provides graph endpoints to - link the USB controller and the external connector associated with this path. + These ports is to be attached to the endpoint of the DWC3 controller node + and type C connector node. The controller has the "usb-role-switch" + property. properties: - reg: - maxItems: 1 - description: Path number - - phys: - maxItems: 1 - description: High-Speed USB PHY associated with this data path. - - usb-role-switch: - type: boolean - description: - Set this property if the USB port on this path is role switch capable. - In device role, debug mode inserts the EUD hub into the UTMI path. In - host role, the EUD hub is bypassed and UTMI traffic flows directly - between the PHY and the USB controller. - - ports: - $ref: /schemas/graph.yaml#/properties/ports - description: - These ports are to be attached to the endpoint of the USB controller node - and USB connector node. - - properties: - port@0: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the USB controller. + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the DWC3 controller. - port@1: - $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the USB connector. - - required: - - reg - - phys - - ports - - additionalProperties: false + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the type C connector. required: - compatible - reg + - ports additionalProperties: false @@ -97,30 +58,21 @@ examples: compatible = "qcom,sc7280-eud", "qcom,eud"; reg = <0x88e0000 0x2000>, <0x88e2000 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - - eud-path@0 { - reg = <0>; - phys = <&usb_1_hsphy>; - usb-role-switch; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; - }; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; }; + }; - port@1 { - reg = <1>; - eud_con: endpoint { - remote-endpoint = <&con_eud>; - }; + port@1 { + reg = <1>; + eud_con: endpoint { + remote-endpoint = <&con_eud>; }; }; }; From e8d6ecf09cb6a0441148eec041d918061139f7da Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:22:28 -0700 Subject: [PATCH 025/128] =?UTF-8?q?FROMLIST:=20dt-bindings:=20connector:?= =?UTF-8?q?=20Add=20role=E2=80=91switch=20provider=20phandle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional consumer→provider phandle on USB connectors to reference the USB role-switch provider when no direct graph link exists. The DRD controller remains the provider via its 'usb-role-switch' property. Link: https://lore.kernel.org/all/20260223191042.825136-2-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- .../devicetree/bindings/connector/usb-connector.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index 11e40d225b9f3..ef8d3d26461b2 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -95,6 +95,14 @@ properties: - device - dual + usb-role-switch: + $ref: /schemas/types.yaml#/definitions/phandle + description: + A phandle to the USB role-switch provider. The provider is typically + a dual-role (DRD) USB controller node that declares the boolean + 'usb-role-switch' property. Use this when the connector is not + directly linked to the provider in the OF graph. + typec-power-opmode: description: Determines the power operation mode that the Type C connector will support and will advertise through CC pins when it has no power From 94d8ce661ff7fb28168b57d31fdc2d520d081088 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:23:13 -0700 Subject: [PATCH 026/128] FROMLIST: dt-bindings: soc: qcom: eud: Add support for dual-port configuration EUD hardware supports debugging on up to two USB ports depending on the SoC configuration. Debugging can be selected on either the primary or secondary USB port as controlled by the EUD_PORT_SELECT register. Extend the binding to support dual-port configurations by adding port@2 and port@3 for secondary USB controller and Type-C connector connections. Link: https://lore.kernel.org/all/20260309203337.803986-2-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- .../bindings/soc/qcom/qcom,eud.yaml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml index 84218636c0d8d..12560342f37fb 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml @@ -32,18 +32,27 @@ properties: ports: $ref: /schemas/graph.yaml#/properties/ports description: - These ports is to be attached to the endpoint of the DWC3 controller node - and type C connector node. The controller has the "usb-role-switch" - property. + These ports attach to endpoints of DWC3 controller nodes and Type-C + connector nodes. The controller has the "usb-role-switch" property. + EUD supports up to 2 USB ports. For single-port configurations, use + port@0 and port@1. For dual-port configurations, use all four ports. properties: port@0: $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the DWC3 controller. + description: This port is to be attached to the primary DWC3 controller. port@1: $ref: /schemas/graph.yaml#/properties/port - description: This port is to be attached to the type C connector. + description: This port is to be attached to the primary Type-C connector. + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the secondary DWC3 controller. + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: This port is to be attached to the secondary Type-C connector. required: - compatible From 5c70d700487556db50429d60ccd0eb3a0f69ea60 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:23:36 -0700 Subject: [PATCH 027/128] FROMLIST: usb: misc: qcom_eud: add sysfs attribute for port selection EUD can be mapped to either the primary USB port or the secondary USB port depending on the value of the EUD_PORT_SEL register. Add a 'port' sysfs attribute to allow userspace to select which port EUD should operate on and update the ABI documentation. This is needed for systems with dual USB ports where EUD needs to be accessible on either port depending on the system configuration and use case. Link: https://lore.kernel.org/all/20260309203337.803986-3-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio --- Documentation/ABI/testing/sysfs-driver-eud | 16 +++++++++ drivers/usb/misc/qcom_eud.c | 41 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud index 2bab0db2d2f0f..67223f73ee606 100644 --- a/Documentation/ABI/testing/sysfs-driver-eud +++ b/Documentation/ABI/testing/sysfs-driver-eud @@ -7,3 +7,19 @@ Description: EUD based on a 1 or a 0 value. By enabling EUD, the user is able to activate the mini-usb hub of EUD for debug and trace capabilities. + +What: /sys/bus/platform/drivers/qcom_eud/.../port +Date: January 2026 +Contact: Elson Serrao +Description: + Selects which USB port the Embedded USB Debugger (EUD) + is mapped to on platforms providing multiple High-Speed + USB ports. + + Valid values: + 0 - Primary USB port + 1 - Secondary USB port + + The attribute is writable only while EUD is disabled. + Reading the attribute returns the currently selected + USB port number. diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 926419ca560fc..35324e1e1ea7e 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -23,8 +23,11 @@ #define EUD_REG_VBUS_INT_CLR 0x0080 #define EUD_REG_CSR_EUD_EN 0x1014 #define EUD_REG_SW_ATTACH_DET 0x1018 +#define EUD_REG_PORT_SEL 0x1028 #define EUD_REG_EUD_EN2 0x0000 +#define EUD_MAX_PORTS 2 + #define EUD_ENABLE BIT(0) #define EUD_INT_PET_EUD BIT(0) #define EUD_INT_VBUS BIT(2) @@ -40,6 +43,7 @@ struct eud_chip { int irq; bool enabled; bool usb_attached; + u8 port_idx; }; static int enable_eud(struct eud_chip *priv) @@ -104,8 +108,45 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR_RW(enable); +static ssize_t port_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", chip->port_idx); +} + +static ssize_t port_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct eud_chip *chip = dev_get_drvdata(dev); + u8 port; + int ret; + + ret = kstrtou8(buf, 0, &port); + if (ret) + return ret; + + /* Only port 0 and port 1 are valid */ + if (port >= EUD_MAX_PORTS) + return -EINVAL; + + /* Port selection must be done before enabling EUD */ + if (chip->enabled) { + dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); + return -EBUSY; + } + + writel(port, chip->base + EUD_REG_PORT_SEL); + chip->port_idx = port; + + return count; +} + +static DEVICE_ATTR_RW(port); + static struct attribute *eud_attrs[] = { &dev_attr_enable.attr, + &dev_attr_port.attr, NULL, }; ATTRIBUTE_GROUPS(eud); From 5f5237955ee30ff41c57467b40f2f324b781b862 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:35 -0700 Subject: [PATCH 028/128] FROMLIST: usb: misc: qcom_eud: add per-port High-Speed PHY control EUD hardware can support multiple High-Speed USB ports, each routed through its own PHY. The active port is selected in hardware via the EUD_PORT_SEL register. As a High-Speed hub, EUD requires access to the High-Speed PHY associated with the active port. To support this multi-port capability, the driver must manage PHY resources on a per-port basis, ensuring that the PHY for the currently selected port is properly initialized and powered. This patch adds per-port PHY management to the driver. The driver now powers the appropriate PHY based on the selected and enabled port, ensuring correct operation when EUD is enabled. Historically, EUD appeared to work on single-port systems because the USB controller kept the PHY initialized. However, EUD is designed to operate independently of the USB controller and therefore requires explicit PHY control for proper operation. Link: https://lore.kernel.org/all/20260309203337.803986-4-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- drivers/usb/misc/Kconfig | 1 + drivers/usb/misc/qcom_eud.c | 103 +++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 0b56b773dbdf7..2d9190c756f9c 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -147,6 +147,7 @@ config USB_APPLEDISPLAY config USB_QCOM_EUD tristate "QCOM Embedded USB Debugger(EUD) Driver" depends on ARCH_QCOM || COMPILE_TEST + depends on OF select QCOM_SCM select USB_ROLE_SWITCH help diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 35324e1e1ea7e..571b21323797b 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,23 +39,75 @@ struct eud_chip { struct device *dev; struct usb_role_switch *role_sw; + struct phy *phy[EUD_MAX_PORTS]; void __iomem *base; phys_addr_t mode_mgr; unsigned int int_status; int irq; bool enabled; bool usb_attached; + bool phy_enabled; u8 port_idx; }; +static int eud_phy_enable(struct eud_chip *chip) +{ + struct phy *phy; + int ret; + + if (chip->phy_enabled) + return 0; + + phy = chip->phy[chip->port_idx]; + + ret = phy_init(phy); + if (ret) { + dev_err(chip->dev, "Failed to initialize USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + return ret; + } + + ret = phy_power_on(phy); + if (ret) { + dev_err(chip->dev, "Failed to power on USB2 PHY for port %u: %d\n", + chip->port_idx, ret); + phy_exit(phy); + return ret; + } + + chip->phy_enabled = true; + + return 0; +} + +static void eud_phy_disable(struct eud_chip *chip) +{ + struct phy *phy; + + if (!chip->phy_enabled) + return; + + phy = chip->phy[chip->port_idx]; + + phy_power_off(phy); + phy_exit(phy); + chip->phy_enabled = false; +} + static int enable_eud(struct eud_chip *priv) { int ret; - ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + ret = eud_phy_enable(priv); if (ret) return ret; + ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + if (ret) { + eud_phy_disable(priv); + return ret; + } + writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); @@ -70,6 +124,8 @@ static int disable_eud(struct eud_chip *priv) return ret; writel(0, priv->base + EUD_REG_CSR_EUD_EN); + eud_phy_disable(priv); + return 0; } @@ -130,6 +186,11 @@ static ssize_t port_store(struct device *dev, struct device_attribute *attr, if (port >= EUD_MAX_PORTS) return -EINVAL; + if (!chip->phy[port]) { + dev_err(chip->dev, "EUD not supported on selected port\n"); + return -EOPNOTSUPP; + } + /* Port selection must be done before enabling EUD */ if (chip->enabled) { dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); @@ -222,6 +283,35 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) return IRQ_HANDLED; } +static int eud_parse_dt_port(struct eud_chip *chip, u8 port_id) +{ + struct device_node *controller_node; + struct phy *phy; + + /* + * Multiply port_id by 2 to get controller port number: + * port_id 0 -> port@0 (primary USB controller) + * port_id 1 -> port@2 (secondary USB controller) + */ + controller_node = of_graph_get_remote_node(chip->dev->of_node, + port_id * 2, -1); + if (!controller_node) + return dev_err_probe(chip->dev, -ENODEV, + "failed to get controller node for port %u\n", port_id); + + phy = devm_of_phy_get_by_index(chip->dev, controller_node, 0); + if (IS_ERR(phy)) { + of_node_put(controller_node); + return dev_err_probe(chip->dev, PTR_ERR(phy), + "failed to get HS PHY for port %u\n", port_id); + } + chip->phy[port_id] = phy; + + of_node_put(controller_node); + + return 0; +} + static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; @@ -241,6 +331,17 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; + /* + * Parse the DT resources for primary port. + * This is the default EUD port and is mandatory. + */ + ret = eud_parse_dt_port(chip, 0); + if (ret) + return ret; + + /* Secondary port is optional */ + eud_parse_dt_port(chip, 1); + chip->role_sw = usb_role_switch_get(&pdev->dev); if (IS_ERR(chip->role_sw)) return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), From 0987b89e360ef81b9e757487d44d18e84d6fe325 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:36 -0700 Subject: [PATCH 029/128] FROMLIST: usb: misc: qcom_eud: add per-port role switch support The EUD hardware can support multiple High-Speed USB ports, each connected to different USB controllers. The current implementation uses a single chip-level role switch, which cannot properly handle multi-port configurations where each USB port can operate in different role. Restructure the driver to support per-port role switches. Additionally, remove the unnecessary role switch call from enable_eud() as EUD need not modify the USB role upon enabling. Link: https://lore.kernel.org/all/20260309203337.803986-5-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 571b21323797b..c484fc88dea4d 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -38,7 +38,7 @@ struct eud_chip { struct device *dev; - struct usb_role_switch *role_sw; + struct usb_role_switch *role_sw[EUD_MAX_PORTS]; struct phy *phy[EUD_MAX_PORTS]; void __iomem *base; phys_addr_t mode_mgr; @@ -112,7 +112,7 @@ static int enable_eud(struct eud_chip *priv) writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); - return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); + return 0; } static int disable_eud(struct eud_chip *priv) @@ -270,9 +270,9 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) int ret; if (chip->usb_attached) - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE); + ret = usb_role_switch_set_role(chip->role_sw[chip->port_idx], USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST); + ret = usb_role_switch_set_role(chip->role_sw[chip->port_idx], USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); @@ -287,6 +287,7 @@ static int eud_parse_dt_port(struct eud_chip *chip, u8 port_id) { struct device_node *controller_node; struct phy *phy; + struct usb_role_switch *role_sw; /* * Multiply port_id by 2 to get controller port number: @@ -307,16 +308,31 @@ static int eud_parse_dt_port(struct eud_chip *chip, u8 port_id) } chip->phy[port_id] = phy; + /* Only fetch role switch if usb-role-switch property exists */ + if (!of_property_read_bool(controller_node, "usb-role-switch")) { + of_node_put(controller_node); + return 0; + } + + role_sw = usb_role_switch_find_by_fwnode(of_fwnode_handle(controller_node)); of_node_put(controller_node); + if (!role_sw) + return dev_err_probe(chip->dev, -EPROBE_DEFER, + "failed to get role switch for port %u\n", port_id); + + chip->role_sw[port_id] = role_sw; + return 0; } static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; + int i; - usb_role_switch_put(chip->role_sw); + for (i = 0; i < EUD_MAX_PORTS; i++) + usb_role_switch_put(chip->role_sw[i]); } static int eud_probe(struct platform_device *pdev) @@ -342,11 +358,6 @@ static int eud_probe(struct platform_device *pdev) /* Secondary port is optional */ eud_parse_dt_port(chip, 1); - chip->role_sw = usb_role_switch_get(&pdev->dev); - if (IS_ERR(chip->role_sw)) - return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), - "failed to get role switch\n"); - ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); if (ret) return ret; From a43abda884518c5a4795c2a2154959202e28f13b Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:36 -0700 Subject: [PATCH 030/128] FROMLIST: usb: misc: qcom_eud: improve enable_store API Currently enable_store() allows operations irrespective of the EUD state, which can result in redundant operations. Avoid this by adding duplicate state checks to skip requests when EUD is already in the desired state. Additionally, improve error handling with explicit logging to provide better feedback. Link: https://lore.kernel.org/all/20260309203337.803986-6-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio --- drivers/usb/misc/qcom_eud.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index c484fc88dea4d..eee79774f5f8d 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -148,18 +148,27 @@ static ssize_t enable_store(struct device *dev, if (kstrtobool(buf, &enable)) return -EINVAL; + /* Skip operation if already in desired state */ + if (chip->enabled == enable) + return count; + if (enable) { ret = enable_eud(chip); - if (!ret) - chip->enabled = enable; - else - disable_eud(chip); - + if (ret) { + dev_err(chip->dev, "failed to enable eud\n"); + return ret; + } } else { ret = disable_eud(chip); + if (ret) { + dev_err(chip->dev, "failed to disable eud\n"); + return ret; + } } - return ret < 0 ? ret : count; + chip->enabled = enable; + + return count; } static DEVICE_ATTR_RW(enable); From cbc24a407351ac7f12e13deed1c2eb507a8e1c00 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:36 -0700 Subject: [PATCH 031/128] FROMLIST: usb: misc: qcom_eud: fix virtual attach/detach event handling EUD provides virtual USB attach/detach events to simulate cable plug/unplug while maintaining the physical debug connection. However, the current implementation incorrectly sets the USB role to HOST on virtual detach, which doesn't represent the disconnected state. Fix the virtual detach handling by setting the USB role to NONE instead of HOST, correctly representing the disconnected state. Link: https://lore.kernel.org/all/20260309203337.803986-7-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio --- drivers/usb/misc/qcom_eud.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index eee79774f5f8d..ae0c5b2f022a2 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -278,10 +278,26 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data) struct eud_chip *chip = data; int ret; + /* + * EUD virtual attach/detach event handling for low power debugging: + * + * When EUD is enabled in debug mode, the device remains physically + * connected to the PC throughout the debug session, keeping the USB + * controller active. This prevents testing of low power scenarios that + * require USB disconnection. + * + * EUD solves this by providing virtual USB attach/detach events while + * maintaining the physical connection. These events are triggered from + * the Host PC via the enumerated EUD control interface and delivered + * to the EUD driver as interrupts. + * + * These notifications are forwarded to the USB controller through role + * switch framework. + */ if (chip->usb_attached) ret = usb_role_switch_set_role(chip->role_sw[chip->port_idx], USB_ROLE_DEVICE); else - ret = usb_role_switch_set_role(chip->role_sw[chip->port_idx], USB_ROLE_HOST); + ret = usb_role_switch_set_role(chip->role_sw[chip->port_idx], USB_ROLE_NONE); if (ret) dev_err(chip->dev, "failed to set role switch\n"); From edf1452564b0574f89ca502c3c6aa71bd2e19b9d Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:37 -0700 Subject: [PATCH 032/128] FROMLIST: usb: misc: qcom_eud: add host mode coordination EUD functions by presenting itself as a USB device to the host PC for debugging, making it incompatible with USB host mode configurations. Handle below two scenarios to prevent these conflicts: 1. Prevent user from enabling EUD via sysfs when the USB port is in host mode. 2. Automatically disable EUD when USB port switches to host mode and re-enable it when exiting host mode. This is achieved via the exported qcom_eud_usb_role_notify() API that allows the USB controller driver to notify EUD of role changes. This ensures consistent state management without creating conflicts between the EUD debug hub and the USB controller. Link: https://lore.kernel.org/all/20260309203337.803986-8-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 110 ++++++++++++++++++++++++++++++++++- include/linux/usb/qcom_eud.h | 21 +++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 include/linux/usb/qcom_eud.h diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index ae0c5b2f022a2..5b5cf11d6f526 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -12,11 +12,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #define EUD_REG_INT1_EN_MASK 0x0024 @@ -42,11 +44,14 @@ struct eud_chip { struct phy *phy[EUD_MAX_PORTS]; void __iomem *base; phys_addr_t mode_mgr; + /* serializes EUD control operations */ + struct mutex state_lock; unsigned int int_status; int irq; bool enabled; bool usb_attached; bool phy_enabled; + bool eud_disabled_for_host; u8 port_idx; }; @@ -142,17 +147,43 @@ static ssize_t enable_store(struct device *dev, const char *buf, size_t count) { struct eud_chip *chip = dev_get_drvdata(dev); + enum usb_role role; bool enable; int ret; if (kstrtobool(buf, &enable)) return -EINVAL; + guard(mutex)(&chip->state_lock); + /* Skip operation if already in desired state */ if (chip->enabled == enable) return count; + /* + * Handle double-disable scenario: User is disabling EUD that was already + * disabled due to host mode. Since the hardware is already disabled, we + * only need to clear the host-disabled flag to prevent unwanted re-enabling + * when exiting host mode. This respects the user's explicit disable request. + */ + if (!enable && chip->eud_disabled_for_host) { + chip->eud_disabled_for_host = false; + chip->enabled = false; + return count; + } + if (enable) { + /* + * EUD functions by presenting itself as a USB device to the host PC for + * debugging, making it incompatible with USB host mode configuration. + * Prevent enabling EUD in this configuration to avoid hardware conflicts. + */ + role = usb_role_switch_get_role(chip->role_sw[chip->port_idx]); + if (role == USB_ROLE_HOST) { + dev_err(chip->dev, "Cannot enable EUD: USB port is in host mode\n"); + return -EBUSY; + } + ret = enable_eud(chip); if (ret) { dev_err(chip->dev, "failed to enable eud\n"); @@ -351,6 +382,75 @@ static int eud_parse_dt_port(struct eud_chip *chip, u8 port_id) return 0; } +/** + * qcom_eud_usb_role_notify - Notify EUD of USB role change + * @eud_node: Device node of the EUD device + * @phy: HSUSB PHY of the port changing role + * @role: New role being set + * + * Notifies EUD that a USB port is changing roles. EUD will disable itself + * if the port is switching to HOST mode, as EUD is incompatible with host + * mode operation. This API should be called by the USB controller driver + * when it switches the USB role. + * + * The PHY parameter is used to identify which physical USB port is changing + * roles. This is important in multi-port systems where EUD may be active on + * one port while another port changes roles. + * + * This is a best-effort notification - failures are logged but do not affect + * the role change operation. + */ +void qcom_eud_usb_role_notify(struct device_node *eud_node, struct phy *phy, + enum usb_role role) +{ + struct platform_device *pdev; + struct eud_chip *chip; + int ret; + + if (!of_device_is_compatible(eud_node, "qcom,eud")) + return; + + pdev = of_find_device_by_node(eud_node); + if (!pdev) + return; + + chip = platform_get_drvdata(pdev); + if (!chip) + goto put_dev; + + mutex_lock(&chip->state_lock); + + /* Only act if this notification is for the currently active EUD port */ + if (!chip->enabled || chip->phy[chip->port_idx] != phy) { + mutex_unlock(&chip->state_lock); + goto put_dev; + } + + /* + * chip->enabled preserves user's sysfs configuration and is not modified + * during host mode transitions to preserve user intent. + */ + if (role == USB_ROLE_HOST && !chip->eud_disabled_for_host) { + ret = disable_eud(chip); + if (ret) + dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n", ret); + else + chip->eud_disabled_for_host = true; + } else if (role != USB_ROLE_HOST && chip->eud_disabled_for_host) { + ret = enable_eud(chip); + if (ret) + dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n", ret); + else + chip->eud_disabled_for_host = false; + } + + mutex_unlock(&chip->state_lock); + +put_dev: + platform_device_put(pdev); +} +EXPORT_SYMBOL_GPL(qcom_eud_usb_role_notify); + static void eud_role_switch_release(void *data) { struct eud_chip *chip = data; @@ -372,6 +472,8 @@ static int eud_probe(struct platform_device *pdev) chip->dev = &pdev->dev; + mutex_init(&chip->state_lock); + /* * Parse the DT resources for primary port. * This is the default EUD port and is mandatory. @@ -416,8 +518,14 @@ static void eud_remove(struct platform_device *pdev) { struct eud_chip *chip = platform_get_drvdata(pdev); - if (chip->enabled) + platform_set_drvdata(pdev, NULL); + + mutex_lock(&chip->state_lock); + if (chip->enabled) { disable_eud(chip); + chip->enabled = false; + } + mutex_unlock(&chip->state_lock); device_init_wakeup(&pdev->dev, false); disable_irq_wake(chip->irq); diff --git a/include/linux/usb/qcom_eud.h b/include/linux/usb/qcom_eud.h new file mode 100644 index 0000000000000..fe560426b78f3 --- /dev/null +++ b/include/linux/usb/qcom_eud.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __LINUX_USB_QCOM_EUD_H +#define __LINUX_USB_QCOM_EUD_H + +#include + +#if IS_ENABLED(CONFIG_USB_QCOM_EUD) +void qcom_eud_usb_role_notify(struct device_node *eud_node, struct phy *phy, + enum usb_role role); +#else +static inline void qcom_eud_usb_role_notify(struct device_node *eud_node, struct phy *phy, + enum usb_role role) +{ +} +#endif + +#endif /* __LINUX_USB_QCOM_EUD_H */ From 84bffcdc566466681c51c21a7245e7884e8c6442 Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:37 -0700 Subject: [PATCH 033/128] FROMLIST: usb: dwc3: qcom: notify EUD driver of role changes The EUD driver needs USB role information to control its operation as it is incompatible with host mode. Notify the EUD driver when role changes occur so it can manage its state accordingly. Link: https://lore.kernel.org/all/20260309203337.803986-9-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- drivers/usb/dwc3/Kconfig | 1 + drivers/usb/dwc3/dwc3-qcom.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 240b15bc52cbd..1a2d7c883b50d 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -132,6 +132,7 @@ config USB_DWC3_QCOM depends on ARCH_QCOM || COMPILE_TEST depends on EXTCON || !EXTCON depends on OF + depends on USB_QCOM_EUD || !USB_QCOM_EUD default USB_DWC3 help Some Qualcomm SoCs use DesignWare Core IP for USB2/3 diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 9ac75547820d9..b51fd97521df3 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include "core.h" #include "glue.h" @@ -561,6 +563,7 @@ static int dwc3_qcom_setup_irq(struct dwc3_qcom *qcom, struct platform_device *p static void dwc3_qcom_set_role_notifier(struct dwc3 *dwc, enum usb_role next_role) { struct dwc3_qcom *qcom = to_dwc3_qcom(dwc); + struct device_node *eud_node; if (qcom->current_role == next_role) return; @@ -570,6 +573,13 @@ static void dwc3_qcom_set_role_notifier(struct dwc3 *dwc, enum usb_role next_rol return; } + /* Notify EUD of role change */ + eud_node = of_graph_get_remote_node(qcom->dev->of_node, 0, -1); + if (eud_node) { + qcom_eud_usb_role_notify(eud_node, dwc->usb2_generic_phy[0], next_role); + of_node_put(eud_node); + } + if (qcom->current_role == USB_ROLE_DEVICE) dwc3_qcom_vbus_override_enable(qcom, false); else if (qcom->current_role != USB_ROLE_DEVICE) From 53c87be283ff3509b852428bceef181f58236a1f Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:38 -0700 Subject: [PATCH 034/128] FROMLIST: arm64: dts: qcom: kodiak: Fix EUD USB controller connection The EUD node is currently mapped to the secondary USB controller. This SoC only supports EUD on the primary High-Speed USB path. Fix the graph connections to properly map EUD to the primary USB controller. Add an empty connector endpoint for board DTS files to complete the connection. Also enable EUD so debug is available by default on this SoC. Link: https://lore.kernel.org/all/20260309203337.803986-10-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- arch/arm64/boot/dts/qcom/kodiak.dtsi | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index 6079e67ea829b..24483ff2d5ce1 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi @@ -4294,12 +4294,6 @@ phy-names = "usb2-phy"; maximum-speed = "high-speed"; usb-role-switch; - - port { - usb2_role_switch: endpoint { - remote-endpoint = <&eud_ep>; - }; - }; }; qspi: spi@88dc000 { @@ -4623,16 +4617,22 @@ <0 0x88e2000 0 0x1000>; interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; + eud_ep: endpoint { - remote-endpoint = <&usb2_role_switch>; + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + eud_con: endpoint { }; }; }; @@ -4858,6 +4858,7 @@ reg = <0>; usb_1_dwc3_hs: endpoint { + remote-endpoint = <&eud_ep>; }; }; From 8c7f91d8f5390117341ccedf03dbca8620e1fede Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 24 Mar 2026 15:25:38 -0700 Subject: [PATCH 035/128] FROMLIST: arm64: dts: qcom: Map USB connector to EUD for kodiak boards Map the USB connector HS endpoint to EUD for debug functionality on all boards using kodiak.dtsi. Since the controller is no longer a direct neighbor of the connector, add usb-role-switch phandle to map the USB role switch provider for this connector. Link: https://lore.kernel.org/all/20260309203337.803986-11-elson.serrao@oss.qualcomm.com/ Signed-off-by: Elson Serrao --- arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts | 11 ++++++----- arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts | 11 ++++++----- arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts | 11 ++++++----- arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 11 ++++++----- .../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 11 ++++++----- arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts | 11 ++++++----- 6 files changed, 36 insertions(+), 30 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts index 455e5c9bb072a..dbd968967dd54 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts @@ -88,6 +88,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -97,7 +98,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -1433,10 +1434,6 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c>; vdda18-supply = <&vreg_l1c>; @@ -1476,3 +1473,7 @@ qcom,calibration-variant = "Fairphone_5"; status = "okay"; }; + +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts index bf18c48520813..ca9c1a09ca733 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts @@ -65,6 +65,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -74,7 +75,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -826,10 +827,6 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; @@ -862,3 +859,7 @@ &usb_dp_qmpphy_out { remote-endpoint = <&pmic_glink_ss_in>; }; + +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts index 797f37596bf19..eb7e228787c24 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts @@ -75,6 +75,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -84,7 +85,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -952,10 +953,6 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c>; vdda18-supply = <&vreg_l1c>; @@ -986,6 +983,10 @@ remote-endpoint = <&pmic_glink_ss_in>; }; +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; + &venus { firmware-name = "qcom/qcm6490/SHIFT/otter/venus.mbn"; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index e3d2f01881ae0..3cb7494b16f7f 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -185,6 +185,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -194,7 +195,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -1303,14 +1304,14 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_dwc3_ss { remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; }; +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; + &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts index 0b64a0b912021..a75b8e118deba 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts @@ -84,6 +84,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -93,7 +94,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -1090,10 +1091,6 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vreg_l10c_0p88>; vdda33-supply = <&vreg_l2b_3p072>; @@ -1127,6 +1124,10 @@ remote-endpoint = <&pmic_glink_ss_in>; }; +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; + &ufs_mem_hc { reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; vcc-supply = <&vreg_l7b_2p952>; diff --git a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts index cb59c122f6f6a..f99a47334452f 100644 --- a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts +++ b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts @@ -90,6 +90,7 @@ reg = <0>; power-role = "dual"; data-role = "dual"; + usb-role-switch = <&usb_1>; ports { #address-cells = <1>; @@ -99,7 +100,7 @@ reg = <0>; pmic_glink_hs_in: endpoint { - remote-endpoint = <&usb_1_dwc3_hs>; + remote-endpoint = <&eud_con>; }; }; @@ -1440,10 +1441,6 @@ status = "okay"; }; -&usb_1_dwc3_hs { - remote-endpoint = <&pmic_glink_hs_in>; -}; - &usb_1_hsphy { vdda-pll-supply = <&vdd_a_usbhs_core>; vdda18-supply = <&vdd_a_usbhs_1p8>; @@ -1459,3 +1456,7 @@ &wifi { status = "okay"; }; + +&eud_con { + remote-endpoint = <&pmic_glink_hs_in>; +}; From 56ccbf40aba9e63c5917bd041bc51dce8a05a75d Mon Sep 17 00:00:00 2001 From: Vishnu Saini Date: Thu, 16 Apr 2026 08:42:11 +0530 Subject: [PATCH 036/128] FROMLIST: phy: qcom: edp: Initialize swing_pre_emph_cfg for sc7280 Aux timeout is observed on few monitors like Benq BL2420-T due to missing swing_pre_emph_cfg. Link: https://lore.kernel.org/r/20260403-phy_for_next-v1-1-3d336b555019@oss.qualcomm.com Signed-off-by: Vishnu Saini --- drivers/phy/qualcomm/phy-qcom-edp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c index 7372de05a0b81..dd5cfc0eb09d9 100644 --- a/drivers/phy/qualcomm/phy-qcom-edp.c +++ b/drivers/phy/qualcomm/phy-qcom-edp.c @@ -571,6 +571,7 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = { static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { .aux_cfg = edp_phy_aux_cfg_v4, .vco_div_cfg = edp_phy_vco_div_cfg_v4, + .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, .ver_ops = &qcom_edp_phy_ops_v4, }; From 0e120ffe2900f6801a6db4080f889f2518b327d2 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 2 Mar 2026 17:30:34 +0530 Subject: [PATCH 037/128] dt-bindings: arm: qcom,ids: Add SoC ID for Shikra IoT variants Document the IDs used by Shikra SoC IoT variants: - CQ2390M: Shikra Retail with modem - CQ2390S: Shikra Retail without modem - IQ2390S: Shikra Industrial without modem Signed-off-by: Komal Bajaj --- include/dt-bindings/arm/qcom,ids.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 336f7bb7188a8..c300ffb4a6a5e 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -299,6 +299,9 @@ #define QCOM_ID_QCS615 680 #define QCOM_ID_CQ7790M 731 #define QCOM_ID_CQ7790S 732 +#define QCOM_ID_CQ2390M 756 +#define QCOM_ID_CQ2390S 758 +#define QCOM_ID_IQ2390S 759 #define QCOM_ID_IPQ5200 765 #define QCOM_ID_IPQ5210 766 #define QCOM_ID_QCF2200 767 From 733a9e525eed94dcaf51c2bdbf1219738d3afcf9 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 3 Mar 2026 14:25:56 +0530 Subject: [PATCH 038/128] soc: qcom: socinfo: Add SoC ID for Shikra IoT variants Add SoC ID for Shikra IoT variants: CQ2390M, CQ2390S and IQ2390S. Signed-off-by: Komal Bajaj --- drivers/soc/qcom/socinfo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 8ffd903ebddbb..396a9c66b2403 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -528,6 +528,9 @@ static const struct soc_id soc_id[] = { { qcom_board_id(QCS615) }, { qcom_board_id(CQ7790M) }, { qcom_board_id(CQ7790S) }, + { qcom_board_id(CQ2390M) }, + { qcom_board_id(CQ2390S) }, + { qcom_board_id(IQ2390S) }, { qcom_board_id(IPQ5200) }, { qcom_board_id(IPQ5210) }, { qcom_board_id(QCF2200) }, From 1e60e6ff84cf6f6b9a2948cbe3f241ed8f7e4247 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 2 Mar 2026 18:43:41 +0530 Subject: [PATCH 039/128] dt-bindings: arm-smmu: Add compatible for Shikra SoC Qualcomm Shikra SoC implements arm,mmu-500. Document its compatible. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index 06fb5c8e7547c..1f544103b574c 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -55,6 +55,7 @@ properties: - qcom,sdx55-smmu-500 - qcom,sdx65-smmu-500 - qcom,sdx75-smmu-500 + - qcom,shikra-smmu-500 - qcom,sm6115-smmu-500 - qcom,sm6125-smmu-500 - qcom,sm6350-smmu-500 From 807f1542ddb64a987002686f57ad64c7af0a2744 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 3 Mar 2026 14:46:00 +0530 Subject: [PATCH 040/128] dt-bindings: firmware: qcom,scm: Document SCM on Shikra SoC Document the SCM compatible on the Shikra SoC. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 7918d31f58b4a..a34ae88c26ff0 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -65,6 +65,7 @@ properties: - qcom,scm-sdx55 - qcom,scm-sdx65 - qcom,scm-sdx75 + - qcom,scm-shikra - qcom,scm-sm6115 - qcom,scm-sm6125 - qcom,scm-sm6350 From c71f8be7190e9628534634d5cdb75fd390edbbfb Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 3 Mar 2026 16:11:55 +0530 Subject: [PATCH 041/128] dt-bindings: arm: qcom: Document Shikra and its evk boards Document the device tree binding for the Shikra EVK platform, which is built around a modular System-on-Module (SoM) mounted on a common carrier board. The SoM integrates the Shikra SoC, PMICs, and essential GPIOs, while the EVK carrier board provides additional peripherals such as UART and USB interfaces. Shikra EVK supports three SoM variants: retail with modem, retail without modem, and an industrial non-modem variant. Signed-off-by: Komal Bajaj --- .../devicetree/bindings/arm/qcom.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index b4943123d2e42..10845f8ef9a08 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -954,6 +954,24 @@ properties: - const: qcom,qcs9100 - const: qcom,sa8775p + - items: + - enum: + - qcom,shikra-cqm-evk + - const: qcom,shikra-cqm-som + - const: qcom,shikra + + - items: + - enum: + - qcom,shikra-cqs-evk + - const: qcom,shikra-cqs-som + - const: qcom,shikra + + - items: + - enum: + - qcom,shikra-iqs-evk + - const: qcom,shikra-iqs-som + - const: qcom,shikra + - items: - enum: - google,blueline From 518e927c618615770c0d35ac3e9d33e4a03edae4 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Wed, 4 Mar 2026 12:39:18 +0530 Subject: [PATCH 042/128] dt-bindings: sram: qcom,imem: Add the Shikra compatible Add compatible for Shikra SoC IMEM. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/sram/qcom,imem.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml index c63026904061d..2eb7566afef38 100644 --- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml +++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml @@ -36,6 +36,7 @@ properties: - qcom,sdx55-imem - qcom,sdx65-imem - qcom,sdx75-imem + - qcom,shikra-imem - qcom,sm6115-imem - qcom,sm6125-imem - qcom,sm6350-imem From cd1ef06d57d5f9c9cc6b10199c4a36010165a130 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 17 Mar 2026 18:27:36 +0530 Subject: [PATCH 043/128] dt-bindings: pinctrl: Document the Shikra Top Level Mode Multiplexer Document the Top Level Mode Multiplexer on the Shikra platform. Signed-off-by: Komal Bajaj --- .../bindings/pinctrl/qcom,shikra-tlmm.yaml | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,shikra-tlmm.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,shikra-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,shikra-tlmm.yaml new file mode 100644 index 0000000000000..411c402f9044f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,shikra-tlmm.yaml @@ -0,0 +1,123 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,shikra-tlmm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Shikra TLMM block + +maintainers: + - Komal Bajaj + +description: | + Top Level Mode Multiplexer pin controller in Qualcomm Shikra SoC. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,shikra-tlmm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + gpio-reserved-ranges: + minItems: 1 + maxItems: 83 + + gpio-line-names: + maxItems: 166 + +patternProperties: + "-state$": + oneOf: + - $ref: "#/$defs/qcom-shikra-tlmm-state" + - patternProperties: + "-pins$": + $ref: "#/$defs/qcom-shikra-tlmm-state" + additionalProperties: false + +$defs: + qcom-shikra-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state + unevaluatedProperties: false + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-5][0-9]|16[0-5])$" + - enum: [ sdc1_rclk, sdc1_clk, sdc1_cmd, sdc1_data, + sdc2_clk, sdc2_cmd, sdc2_data ] + minItems: 1 + maxItems: 36 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + + enum: [ gpio, agera_pll, atest_bbrx, atest_char, atest_gpsadc, + atest_tsens, atest_usb, cam_mclk, cci_async, cci_i2c0, + cci_i2c1, cci_timer, char_exec, cri_trng, dac_calib, + dbg_out_clk, ddr_bist, ddr_pxi, dmic, emac_dll, emac_mcg, + emac_phy, emac0_ptp_aux, emac0_ptp_pps, emac1_ptp_aux, + emac1_ptp_pps, ext_mclk, gcc_gp, gsm0_tx, i2s0, i2s1, + i2s2, i2s3, jitter_bist, m_voc, mdp_vsync_e, mdp_vsync_out0, + mdp_vsync_out1, mdp_vsync_p, mdp_vsync_s, mpm_pwr, mss_lte, + nav_gpio, pa_indicator_or, pbs_in, pbs_out, pcie0_clk_req_n, + phase_flag, pll, prng_rosc, pwm, qdss_cti, qup0_se0, + qup0_se1, qup0_se1_01, qup0_se1_23, qup0_se2, qup0_se3_01, + qup0_se3_23, qup0_se4_01, qup0_se4_23, qup0_se5, qup0_se6, + qup0_se7_01, qup0_se7_23, qup0_se8, qup0_se9, qup0_se9_01, + qup0_se9_23, rgmii, sd_write_protect, sdc_cdc, sdc_tb_trig, + ssbi_wtr, swr0_rx, swr0_tx, tgu_ch_trigout, tsc_async, + tsense_pwm, uim1, uim2, unused_adsp, unused_gsm1, usb0_phy_ps, + vfr, vsense_trigger_mirnat, wlan ] + + required: + - pins + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + tlmm: pinctrl@500000 { + compatible = "qcom,shikra-tlmm"; + reg = <0x00500000 0x800000>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + gpio-ranges = <&tlmm 0 0 166>; + + qup-uart0-default-state { + pins = "gpio0", "gpio1"; + function = "qup0_se1"; + drive-strength = <2>; + bias-disable; + }; + }; +... From c30280d55e30d9cbb9aefd56a5e79d0ae5e4206c Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 17 Mar 2026 16:11:34 +0530 Subject: [PATCH 044/128] pinctrl: qcom: Add Shikra pinctrl driver Add pinctrl driver for TLMM block found in the Shikra SoC. Signed-off-by: Komal Bajaj --- drivers/pinctrl/qcom/Kconfig.msm | 8 + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-shikra.c | 1262 +++++++++++++++++++++++++ 3 files changed, 1271 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-shikra.c diff --git a/drivers/pinctrl/qcom/Kconfig.msm b/drivers/pinctrl/qcom/Kconfig.msm index 836cdeca1006f..13a4b1fe2dec1 100644 --- a/drivers/pinctrl/qcom/Kconfig.msm +++ b/drivers/pinctrl/qcom/Kconfig.msm @@ -369,6 +369,14 @@ config PINCTRL_SDX75 Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc SDX75 platform. +config PINCTRL_SHIKRA + tristate "Qualcomm Technologies Inc Shikra pin controller driver" + depends on ARM64 || COMPILE_TEST + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc TLMM block found on the Qualcomm + Technologies Inc Shikra platform. + config PINCTRL_SM4450 tristate "Qualcomm Technologies Inc SM4450 pin controller driver" depends on ARM64 || COMPILE_TEST diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 84bda3ada8749..07c0d236d82f6 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o obj-$(CONFIG_PINCTRL_SDX55) += pinctrl-sdx55.o obj-$(CONFIG_PINCTRL_SDX65) += pinctrl-sdx65.o obj-$(CONFIG_PINCTRL_SDX75) += pinctrl-sdx75.o +obj-$(CONFIG_PINCTRL_SHIKRA) += pinctrl-shikra.o obj-$(CONFIG_PINCTRL_SM4250_LPASS_LPI) += pinctrl-sm4250-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM4450) += pinctrl-sm4450.o obj-$(CONFIG_PINCTRL_SM6115) += pinctrl-sm6115.o diff --git a/drivers/pinctrl/qcom/pinctrl-shikra.c b/drivers/pinctrl/qcom/pinctrl-shikra.c new file mode 100644 index 0000000000000..1acd7a78ecba2 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-shikra.c @@ -0,0 +1,1262 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include + +#include "pinctrl-msm.h" + +#define REG_SIZE 0x1000 +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \ + { \ + .grp = PINCTRL_PINGROUP("gpio" #id, \ + gpio##id##_pins, \ + ARRAY_SIZE(gpio##id##_pins)), \ + .funcs = (int[]){ \ + msm_mux_gpio, /* gpio mode */ \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9, \ + msm_mux_##f10, \ + msm_mux_##f11 /* egpio mode */ \ + }, \ + .nfuncs = 12, \ + .ctl_reg = REG_SIZE * id, \ + .io_reg = 0x4 + REG_SIZE * id, \ + .intr_cfg_reg = 0x8 + REG_SIZE * id, \ + .intr_status_reg = 0xc + REG_SIZE * id, \ + .intr_target_reg = 0x8 + REG_SIZE * id, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .egpio_enable = 12, \ + .egpio_present = 11, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_wakeup_enable_bit = 7, \ + .intr_wakeup_present_bit = 6, \ + .intr_target_bit = 8, \ + .intr_target_kpss_val = 3, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .grp = PINCTRL_PINGROUP(#pg_name, \ + pg_name##_pins, \ + ARRAY_SIZE(pg_name##_pins)), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +#define UFS_RESET(pg_name, ctl, io) \ + { \ + .grp = PINCTRL_PINGROUP(#pg_name, \ + pg_name##_pins, \ + ARRAY_SIZE(pg_name##_pins)), \ + .ctl_reg = ctl, \ + .io_reg = io, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = 3, \ + .drv_bit = 0, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = 0, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +static const struct pinctrl_pin_desc shikra_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "GPIO_128"), + PINCTRL_PIN(129, "GPIO_129"), + PINCTRL_PIN(130, "GPIO_130"), + PINCTRL_PIN(131, "GPIO_131"), + PINCTRL_PIN(132, "GPIO_132"), + PINCTRL_PIN(133, "GPIO_133"), + PINCTRL_PIN(134, "GPIO_134"), + PINCTRL_PIN(135, "GPIO_135"), + PINCTRL_PIN(136, "GPIO_136"), + PINCTRL_PIN(137, "GPIO_137"), + PINCTRL_PIN(138, "GPIO_138"), + PINCTRL_PIN(139, "GPIO_139"), + PINCTRL_PIN(140, "GPIO_140"), + PINCTRL_PIN(141, "GPIO_141"), + PINCTRL_PIN(142, "GPIO_142"), + PINCTRL_PIN(143, "GPIO_143"), + PINCTRL_PIN(144, "GPIO_144"), + PINCTRL_PIN(145, "GPIO_145"), + PINCTRL_PIN(146, "GPIO_146"), + PINCTRL_PIN(147, "GPIO_147"), + PINCTRL_PIN(148, "GPIO_148"), + PINCTRL_PIN(149, "GPIO_149"), + PINCTRL_PIN(150, "GPIO_150"), + PINCTRL_PIN(151, "GPIO_151"), + PINCTRL_PIN(152, "GPIO_152"), + PINCTRL_PIN(153, "GPIO_153"), + PINCTRL_PIN(154, "GPIO_154"), + PINCTRL_PIN(155, "GPIO_155"), + PINCTRL_PIN(156, "GPIO_156"), + PINCTRL_PIN(157, "GPIO_157"), + PINCTRL_PIN(158, "GPIO_158"), + PINCTRL_PIN(159, "GPIO_159"), + PINCTRL_PIN(160, "GPIO_160"), + PINCTRL_PIN(161, "GPIO_161"), + PINCTRL_PIN(162, "SDC1_DATA"), + PINCTRL_PIN(163, "SDC1_RCLK"), + PINCTRL_PIN(164, "SDC1_CMD"), + PINCTRL_PIN(165, "SDC1_CLK"), + PINCTRL_PIN(166, "SDC2_CLK"), + PINCTRL_PIN(167, "SDC2_CMD"), + PINCTRL_PIN(168, "SDC2_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); +DECLARE_MSM_GPIO_PINS(113); +DECLARE_MSM_GPIO_PINS(114); +DECLARE_MSM_GPIO_PINS(115); +DECLARE_MSM_GPIO_PINS(116); +DECLARE_MSM_GPIO_PINS(117); +DECLARE_MSM_GPIO_PINS(118); +DECLARE_MSM_GPIO_PINS(119); +DECLARE_MSM_GPIO_PINS(120); +DECLARE_MSM_GPIO_PINS(121); +DECLARE_MSM_GPIO_PINS(122); +DECLARE_MSM_GPIO_PINS(123); +DECLARE_MSM_GPIO_PINS(124); +DECLARE_MSM_GPIO_PINS(125); +DECLARE_MSM_GPIO_PINS(126); +DECLARE_MSM_GPIO_PINS(127); +DECLARE_MSM_GPIO_PINS(128); +DECLARE_MSM_GPIO_PINS(129); +DECLARE_MSM_GPIO_PINS(130); +DECLARE_MSM_GPIO_PINS(131); +DECLARE_MSM_GPIO_PINS(132); +DECLARE_MSM_GPIO_PINS(133); +DECLARE_MSM_GPIO_PINS(134); +DECLARE_MSM_GPIO_PINS(135); +DECLARE_MSM_GPIO_PINS(136); +DECLARE_MSM_GPIO_PINS(137); +DECLARE_MSM_GPIO_PINS(138); +DECLARE_MSM_GPIO_PINS(139); +DECLARE_MSM_GPIO_PINS(140); +DECLARE_MSM_GPIO_PINS(141); +DECLARE_MSM_GPIO_PINS(142); +DECLARE_MSM_GPIO_PINS(143); +DECLARE_MSM_GPIO_PINS(144); +DECLARE_MSM_GPIO_PINS(145); +DECLARE_MSM_GPIO_PINS(146); +DECLARE_MSM_GPIO_PINS(147); +DECLARE_MSM_GPIO_PINS(148); +DECLARE_MSM_GPIO_PINS(149); +DECLARE_MSM_GPIO_PINS(150); +DECLARE_MSM_GPIO_PINS(151); +DECLARE_MSM_GPIO_PINS(152); +DECLARE_MSM_GPIO_PINS(153); +DECLARE_MSM_GPIO_PINS(154); +DECLARE_MSM_GPIO_PINS(155); +DECLARE_MSM_GPIO_PINS(156); +DECLARE_MSM_GPIO_PINS(157); +DECLARE_MSM_GPIO_PINS(158); +DECLARE_MSM_GPIO_PINS(159); +DECLARE_MSM_GPIO_PINS(160); +DECLARE_MSM_GPIO_PINS(161); +DECLARE_MSM_GPIO_PINS(162); +DECLARE_MSM_GPIO_PINS(163); +DECLARE_MSM_GPIO_PINS(164); +DECLARE_MSM_GPIO_PINS(165); + +static const unsigned int sdc1_data_pins[] = { 162 }; +static const unsigned int sdc1_rclk_pins[] = { 163 }; +static const unsigned int sdc1_cmd_pins[] = { 164 }; +static const unsigned int sdc1_clk_pins[] = { 165 }; +static const unsigned int sdc2_clk_pins[] = { 166 }; +static const unsigned int sdc2_cmd_pins[] = { 167 }; +static const unsigned int sdc2_data_pins[] = { 168 }; + +enum shikra_functions { + msm_mux_gpio, + msm_mux_agera_pll, + msm_mux_atest_bbrx, + msm_mux_atest_char, + msm_mux_atest_gpsadc, + msm_mux_atest_tsens, + msm_mux_atest_usb, + msm_mux_cam_mclk, + msm_mux_cci_async, + msm_mux_cci_i2c0, + msm_mux_cci_i2c1, + msm_mux_cci_timer, + msm_mux_char_exec, + msm_mux_cri_trng, + msm_mux_dac_calib, + msm_mux_dbg_out_clk, + msm_mux_ddr_bist, + msm_mux_ddr_pxi, + msm_mux_dmic, + msm_mux_emac_dll, + msm_mux_emac_mcg, + msm_mux_emac_phy, + msm_mux_emac0_ptp_aux, + msm_mux_emac0_ptp_pps, + msm_mux_emac1_ptp_aux, + msm_mux_emac1_ptp_pps, + msm_mux_ext_mclk, + msm_mux_gcc_gp, + msm_mux_gsm0_tx, + msm_mux_i2s0, + msm_mux_i2s1, + msm_mux_i2s2, + msm_mux_i2s3, + msm_mux_jitter_bist, + msm_mux_m_voc, + msm_mux_mdp_vsync_e, + msm_mux_mdp_vsync_out0, + msm_mux_mdp_vsync_out1, + msm_mux_mdp_vsync_p, + msm_mux_mdp_vsync_s, + msm_mux_mpm_pwr, + msm_mux_mss_lte, + msm_mux_nav_gpio, + msm_mux_pa_indicator_or, + msm_mux_pbs_in, + msm_mux_pbs_out, + msm_mux_pcie0_clk_req_n, + msm_mux_phase_flag, + msm_mux_pll, + msm_mux_prng_rosc, + msm_mux_pwm, + msm_mux_qdss_cti, + msm_mux_qup0_se0, + msm_mux_qup0_se1, + msm_mux_qup0_se1_01, + msm_mux_qup0_se1_23, + msm_mux_qup0_se2, + msm_mux_qup0_se3_01, + msm_mux_qup0_se3_23, + msm_mux_qup0_se4_01, + msm_mux_qup0_se4_23, + msm_mux_qup0_se5, + msm_mux_qup0_se6, + msm_mux_qup0_se7_01, + msm_mux_qup0_se7_23, + msm_mux_qup0_se8, + msm_mux_qup0_se9, + msm_mux_qup0_se9_01, + msm_mux_qup0_se9_23, + msm_mux_rgmii, + msm_mux_sd_write_protect, + msm_mux_sdc_cdc, + msm_mux_sdc_tb_trig, + msm_mux_ssbi_wtr, + msm_mux_swr0_rx, + msm_mux_swr0_tx, + msm_mux_tgu_ch_trigout, + msm_mux_tsc_async, + msm_mux_tsense_pwm, + msm_mux_uim1, + msm_mux_uim2, + msm_mux_unused_adsp, + msm_mux_unused_gsm1, + msm_mux_usb0_phy_ps, + msm_mux_vfr, + msm_mux_vsense_trigger_mirnat, + msm_mux_wlan, + msm_mux__, +}; + +static const char *const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", + "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", + "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23", + "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", + "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", + "gpio42", "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", + "gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53", + "gpio54", "gpio55", "gpio56", "gpio57", "gpio58", "gpio59", + "gpio60", "gpio61", "gpio62", "gpio63", "gpio64", "gpio65", + "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", "gpio71", + "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", + "gpio84", "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", + "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", + "gpio96", "gpio97", "gpio98", "gpio99", "gpio100", "gpio101", + "gpio102", "gpio103", "gpio104", "gpio105", "gpio106", "gpio107", + "gpio108", "gpio109", "gpio110", "gpio111", "gpio112", "gpio113", + "gpio114", "gpio115", "gpio116", "gpio117", "gpio118", "gpio119", + "gpio120", "gpio121", "gpio122", "gpio123", "gpio124", "gpio125", + "gpio126", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131", + "gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137", + "gpio138", "gpio139", "gpio140", "gpio141", "gpio142", "gpio143", + "gpio144", "gpio145", "gpio146", "gpio147", "gpio148", "gpio149", + "gpio150", "gpio151", "gpio152", "gpio153", "gpio154", "gpio155", + "gpio156", "gpio157", "gpio158", "gpio159", "gpio160", "gpio161", +}; + +static const char *const agera_pll_groups[] = { + "gpio22", "gpio23", +}; + +static const char *const atest_bbrx_groups[] = { + "gpio58", "gpio59", +}; + +static const char *const atest_char_groups[] = { + "gpio56", "gpio57", "gpio54", "gpio55", "gpio62", +}; + +static const char *const atest_gpsadc_groups[] = { + "gpio60", "gpio96", +}; + +static const char *const atest_tsens_groups[] = { + "gpio1", "gpio2", +}; + +static const char *const atest_usb_groups[] = { + "gpio53", "gpio58", "gpio59", "gpio60", "gpio61", "gpio96", + "gpio98", "gpio99", "gpio100", "gpio101", +}; + +static const char *const cam_mclk_groups[] = { + "gpio34", "gpio35", "gpio96", "gpio98", +}; + +static const char *const cci_async_groups[] = { + "gpio39", +}; + +static const char *const cci_i2c0_groups[] = { + "gpio36", "gpio37", +}; + +static const char *const cci_i2c1_groups[] = { + "gpio41", "gpio42", +}; + +static const char *const cci_timer_groups[] = { + "gpio38", "gpio40", "gpio43", "gpio47", +}; + +static const char *const char_exec_groups[] = { + "gpio12", "gpio13", +}; + +static const char *const cri_trng_groups[] = { + "gpio6", "gpio7", "gpio20", +}; + +static const char *const dac_calib_groups[] = { + "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", + "gpio9", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", + "gpio19", "gpio63", "gpio64", "gpio66", "gpio68", "gpio69", + "gpio70", "gpio88", "gpio89", "gpio90", "gpio97", "gpio116", + "gpio117", "gpio118", + + +}; + +static const char *const dbg_out_clk_groups[] = { + "gpio61", +}; + +static const char *const ddr_bist_groups[] = { + "gpio1", "gpio2", "gpio3", "gpio4", +}; + +static const char *const ddr_pxi_groups[] = { + "gpio98", "gpio99", "gpio100", "gpio101", +}; + +static const char *const dmic_groups[] = { + "gpio96", "gpio97", "gpio98", "gpio99", +}; + +static const char *const emac_dll_groups[] = { + "gpio58", "gpio59", "gpio60", "gpio61", +}; + +static const char *const emac_mcg_groups[] = { + "gpio28", "gpio29", "gpio40", "gpio43", "gpio44", "gpio45", + "gpio46", "gpio47", +}; + +static const char *const emac_phy_groups[] = { + "gpio120", "gpio136", +}; + +static const char *const emac0_ptp_aux_groups[] = { + "gpio60", "gpio63", "gpio69", "gpio85", +}; + +static const char *const emac0_ptp_pps_groups[] = { + "gpio60", "gpio63", "gpio69", "gpio85", +}; + +static const char *const emac1_ptp_aux_groups[] = { + "gpio31", "gpio33", "gpio60", "gpio68", +}; + +static const char *const emac1_ptp_pps_groups[] = { + "gpio31", "gpio33", "gpio60", "gpio68", +}; + +static const char *const ext_mclk_groups[] = { + "gpio103", "gpio104", "gpio110", "gpio114", +}; + +static const char *const gcc_gp_groups[] = { + "gpio45", "gpio53", "gpio61", "gpio88", "gpio89", "gpio110", +}; + +static const char *const gsm0_tx_groups[] = { + "gpio75", +}; + +static const char *const i2s0_groups[] = { + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", +}; + +static const char *const i2s1_groups[] = { + "gpio96", "gpio97", "gpio98", "gpio99", +}; + +static const char *const i2s2_groups[] = { + "gpio100", "gpio101", "gpio102", "gpio103", +}; + +static const char *const i2s3_groups[] = { + "gpio111", "gpio112", "gpio113", "gpio114", +}; + +static const char *const jitter_bist_groups[] = { + "gpio96", "gpio99", +}; + +static const char *const m_voc_groups[] = { + "gpio0", +}; + +static const char *const mdp_vsync_e_groups[] = { + "gpio94", +}; + +static const char *const mdp_vsync_out0_groups[] = { + "gpio86", +}; + +static const char *const mdp_vsync_out1_groups[] = { + "gpio86", +}; + +static const char *const mdp_vsync_p_groups[] = { + "gpio86", +}; + +static const char *const mdp_vsync_s_groups[] = { + "gpio95", +}; + +static const char *const mpm_pwr_groups[] = { + "gpio1", +}; + +static const char *const mss_lte_groups[] = { + "gpio115", "gpio116", +}; + +static const char *const nav_gpio_groups[] = { + "gpio53", "gpio58", "gpio63", "gpio71", "gpio91", "gpio92", + "gpio95", "gpio100", "gpio101", "gpio104", +}; + +static const char *const pa_indicator_or_groups[] = { + "gpio61", +}; + +static const char *const pbs_in_groups[] = { + "gpio48", "gpio49", "gpio50", "gpio51", "gpio53", "gpio54", + "gpio55", "gpio56", "gpio57", "gpio58", "gpio59", "gpio60", + "gpio61", "gpio62", "gpio63", "gpio74", +}; + +static const char *const pbs_out_groups[] = { + "gpio22", "gpio23", "gpio24", +}; + +static const char *const pcie0_clk_req_n_groups[] = { + "gpio117", +}; + +static const char *const phase_flag_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", + "gpio6", "gpio7", "gpio8", "gpio9", "gpio11", "gpio16", + "gpio17", "gpio28", "gpio29", "gpio30", "gpio31", "gpio48", + "gpio49", "gpio50", "gpio54", "gpio55", "gpio56", "gpio57", + "gpio62", "gpio63", "gpio64", "gpio69", "gpio70", "gpio71", + "gpio72", "gpio74", "gpio102", +}; + +static const char *const pll_groups[] = { + "gpio14", "gpio22", "gpio43", "gpio44", "gpio74", "gpio76", +}; + +static const char *const prng_rosc_groups[] = { + "gpio27", "gpio28", +}; + +static const char *const pwm_groups[] = { + "gpio32", "gpio40", "gpio45", "gpio53", "gpio54", "gpio55", + "gpio56", "gpio57", "gpio58", "gpio61", "gpio62", "gpio68", + "gpio77", "gpio79", "gpio80", "gpio87", "gpio102" +}; + +static const char *const qdss_cti_groups[] = { + "gpio28", "gpio29", "gpio30", "gpio31", "gpio94", "gpio95", +}; + +static const char *const qup0_se0_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; + +static const char *const qup0_se1_groups[] = { + "gpio28", "gpio29", +}; + +static const char *const qup0_se1_01_groups[] = { + "gpio4", "gpio5", +}; + +static const char *const qup0_se1_23_groups[] = { + "gpio4", "gpio5", +}; + +static const char *const qup0_se2_groups[] = { + "gpio6", "gpio7", "gpio8", "gpio9", "gpio30", "gpio31", +}; + +static const char *const qup0_se3_01_groups[] = { + "gpio10", "gpio11", +}; + +static const char *const qup0_se3_23_groups[] = { + "gpio10", "gpio11", +}; + +static const char *const qup0_se4_01_groups[] = { + "gpio12", "gpio13", +}; + +static const char *const qup0_se4_23_groups[] = { + "gpio12", "gpio13", +}; + +static const char *const qup0_se5_groups[] = { + "gpio14", "gpio15", "gpio16", "gpio17", +}; + +static const char *const qup0_se6_groups[] = { + "gpio18", "gpio19", "gpio28", "gpio29", "gpio30", "gpio31", +}; + +static const char *const qup0_se7_01_groups[] = { + "gpio20", "gpio21", +}; + +static const char *const qup0_se7_23_groups[] = { + "gpio20", "gpio21", +}; + +static const char *const qup0_se8_groups[] = { + "gpio22", "gpio23", "gpio24", "gpio25", +}; + +static const char *const qup0_se9_groups[] = { + "gpio48", "gpio49", "gpio50", "gpio51", +}; + +static const char *const qup0_se9_01_groups[] = { + "gpio26", "gpio27", +}; + +static const char *const qup0_se9_23_groups[] = { + "gpio26", "gpio27", +}; + +static const char *const rgmii_groups[] = { + "gpio121", "gpio122", "gpio123", "gpio124", "gpio125", "gpio126", + "gpio127", "gpio128", "gpio129", "gpio130", "gpio131", "gpio132", + "gpio133", "gpio134", "gpio135", "gpio137", "gpio138", "gpio139", + "gpio140", "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", + "gpio146", "gpio147", "gpio148", "gpio149", "gpio150", "gpio151", +}; + +static const char *const sd_write_protect_groups[] = { + "gpio109", +}; + +static const char *const sdc_cdc_groups[] = { + "gpio98", "gpio99", "gpio100", "gpio101", +}; + +static const char *const sdc_tb_trig_groups[] = { + "gpio32", "gpio33", +}; + +static const char *const ssbi_wtr_groups[] = { + "gpio68", "gpio69", "gpio70", "gpio71", + +}; + +static const char *const swr0_rx_groups[] = { + "gpio107", "gpio108", "gpio109", +}; + +static const char *const swr0_tx_groups[] = { + "gpio105", "gpio106", +}; + +static const char *const tgu_ch_trigout_groups[] = { + "gpio14", "gpio15", "gpio16", "gpio17", +}; + +static const char *const tsc_async_groups[] = { + "gpio45", "gpio46", +}; + +static const char *const tsense_pwm_groups[] = { + "gpio21", +}; + +static const char *const uim1_groups[] = { + "gpio81", "gpio82", "gpio83", "gpio84", +}; + +static const char *const uim2_groups[] = { + "gpio77", "gpio78", "gpio79", "gpio80", +}; + +static const char *const unused_adsp_groups[] = { + "gpio35", +}; + +static const char *const unused_gsm1_groups[] = { + "gpio64", +}; + +static const char *const usb0_phy_ps_groups[] = { + "gpio90", +}; + +static const char *const vfr_groups[] = { + "gpio59", +}; + +static const char *const vsense_trigger_mirnat_groups[] = { + "gpio58", +}; + +static const char *const wlan_groups[] = { + "gpio14", "gpio15", +}; + +static const struct pinfunction shikra_functions[] = { + MSM_GPIO_PIN_FUNCTION(gpio), + MSM_PIN_FUNCTION(agera_pll), + MSM_PIN_FUNCTION(atest_bbrx), + MSM_PIN_FUNCTION(atest_char), + MSM_PIN_FUNCTION(atest_gpsadc), + MSM_PIN_FUNCTION(atest_tsens), + MSM_PIN_FUNCTION(atest_usb), + MSM_PIN_FUNCTION(cam_mclk), + MSM_PIN_FUNCTION(cci_async), + MSM_PIN_FUNCTION(cci_i2c0), + MSM_PIN_FUNCTION(cci_i2c1), + MSM_PIN_FUNCTION(cci_timer), + MSM_PIN_FUNCTION(char_exec), + MSM_PIN_FUNCTION(cri_trng), + MSM_PIN_FUNCTION(dac_calib), + MSM_PIN_FUNCTION(dbg_out_clk), + MSM_PIN_FUNCTION(ddr_bist), + MSM_PIN_FUNCTION(ddr_pxi), + MSM_PIN_FUNCTION(dmic), + MSM_PIN_FUNCTION(emac_dll), + MSM_PIN_FUNCTION(emac_mcg), + MSM_PIN_FUNCTION(emac_phy), + MSM_PIN_FUNCTION(emac0_ptp_aux), + MSM_PIN_FUNCTION(emac0_ptp_pps), + MSM_PIN_FUNCTION(emac1_ptp_aux), + MSM_PIN_FUNCTION(emac1_ptp_pps), + MSM_PIN_FUNCTION(ext_mclk), + MSM_PIN_FUNCTION(gcc_gp), + MSM_PIN_FUNCTION(gsm0_tx), + MSM_PIN_FUNCTION(i2s0), + MSM_PIN_FUNCTION(i2s1), + MSM_PIN_FUNCTION(i2s2), + MSM_PIN_FUNCTION(i2s3), + MSM_PIN_FUNCTION(jitter_bist), + MSM_PIN_FUNCTION(m_voc), + MSM_PIN_FUNCTION(mdp_vsync_e), + MSM_PIN_FUNCTION(mdp_vsync_out0), + MSM_PIN_FUNCTION(mdp_vsync_out1), + MSM_PIN_FUNCTION(mdp_vsync_p), + MSM_PIN_FUNCTION(mdp_vsync_s), + MSM_PIN_FUNCTION(mpm_pwr), + MSM_PIN_FUNCTION(mss_lte), + MSM_PIN_FUNCTION(nav_gpio), + MSM_PIN_FUNCTION(pa_indicator_or), + MSM_PIN_FUNCTION(pbs_in), + MSM_PIN_FUNCTION(pbs_out), + MSM_PIN_FUNCTION(pcie0_clk_req_n), + MSM_PIN_FUNCTION(phase_flag), + MSM_PIN_FUNCTION(pll), + MSM_PIN_FUNCTION(prng_rosc), + MSM_PIN_FUNCTION(pwm), + MSM_PIN_FUNCTION(qdss_cti), + MSM_PIN_FUNCTION(qup0_se0), + MSM_PIN_FUNCTION(qup0_se1), + MSM_PIN_FUNCTION(qup0_se1_01), + MSM_PIN_FUNCTION(qup0_se1_23), + MSM_PIN_FUNCTION(qup0_se2), + MSM_PIN_FUNCTION(qup0_se3_01), + MSM_PIN_FUNCTION(qup0_se3_23), + MSM_PIN_FUNCTION(qup0_se4_01), + MSM_PIN_FUNCTION(qup0_se4_23), + MSM_PIN_FUNCTION(qup0_se5), + MSM_PIN_FUNCTION(qup0_se6), + MSM_PIN_FUNCTION(qup0_se7_01), + MSM_PIN_FUNCTION(qup0_se7_23), + MSM_PIN_FUNCTION(qup0_se8), + MSM_PIN_FUNCTION(qup0_se9), + MSM_PIN_FUNCTION(qup0_se9_01), + MSM_PIN_FUNCTION(qup0_se9_23), + MSM_PIN_FUNCTION(rgmii), + MSM_PIN_FUNCTION(sd_write_protect), + MSM_PIN_FUNCTION(sdc_cdc), + MSM_PIN_FUNCTION(sdc_tb_trig), + MSM_PIN_FUNCTION(ssbi_wtr), + MSM_PIN_FUNCTION(swr0_rx), + MSM_PIN_FUNCTION(swr0_tx), + MSM_PIN_FUNCTION(tgu_ch_trigout), + MSM_PIN_FUNCTION(tsc_async), + MSM_PIN_FUNCTION(tsense_pwm), + MSM_PIN_FUNCTION(uim1), + MSM_PIN_FUNCTION(uim2), + MSM_PIN_FUNCTION(unused_adsp), + MSM_PIN_FUNCTION(unused_gsm1), + MSM_PIN_FUNCTION(usb0_phy_ps), + MSM_PIN_FUNCTION(vfr), + MSM_PIN_FUNCTION(vsense_trigger_mirnat), + MSM_PIN_FUNCTION(wlan), +}; + +/* Every pin is maintained as a single group, and missing or non-existing pin + * would be maintained as dummy group to synchronize pin group index with + * pin descriptor registered with pinctrl core. + * Clients would not be able to request these dummy pin groups. + */ +static const struct msm_pingroup shikra_groups[] = { + [0] = PINGROUP(0, qup0_se0, m_voc, _, phase_flag, _, _, _, _, _, _, _), + [1] = PINGROUP(1, qup0_se0, mpm_pwr, ddr_bist, _, phase_flag, atest_tsens, _, _, _, _, _), + [2] = PINGROUP(2, qup0_se0, ddr_bist, _, phase_flag, atest_tsens, _, _, _, _, _, _), + [3] = PINGROUP(3, qup0_se0, ddr_bist, _, phase_flag, dac_calib, _, _, _, _, _, _), + [4] = PINGROUP(4, qup0_se1_23, qup0_se1_01, ddr_bist, _, phase_flag, dac_calib, _, _, _, _, _), + [5] = PINGROUP(5, qup0_se1_23, qup0_se1_01, _, phase_flag, dac_calib, _, _, _, _, _, _), + [6] = PINGROUP(6, qup0_se2, cri_trng, _, phase_flag, dac_calib, _, _, _, _, _, _), + [7] = PINGROUP(7, qup0_se2, cri_trng, _, phase_flag, dac_calib, _, _, _, _, _, _), + [8] = PINGROUP(8, qup0_se2, _, phase_flag, dac_calib, _, _, _, _, _, _, _), + [9] = PINGROUP(9, qup0_se2, _, phase_flag, dac_calib, _, _, _, _, _, _, _), + [10] = PINGROUP(10, qup0_se3_01, qup0_se3_23, _, _, _, _, _, _, _, _, _), + [11] = PINGROUP(11, qup0_se3_01, qup0_se3_23, _, phase_flag, _, _, _, _, _, _, _), + [12] = PINGROUP(12, qup0_se4_01, qup0_se4_23, char_exec, _, _, _, _, _, _, _, _), + [13] = PINGROUP(13, qup0_se4_01, qup0_se4_23, char_exec, _, _, _, _, _, _, _, _), + [14] = PINGROUP(14, qup0_se5, pll, tgu_ch_trigout, dac_calib, wlan, _, _, _, _, _, _), + [15] = PINGROUP(15, qup0_se5, tgu_ch_trigout, _, dac_calib, wlan, _, _, _, _, _, _), + [16] = PINGROUP(16, qup0_se5, tgu_ch_trigout, _, phase_flag, dac_calib, _, _, _, _, _, _), + [17] = PINGROUP(17, qup0_se5, tgu_ch_trigout, _, phase_flag, dac_calib, _, _, _, _, _, _), + [18] = PINGROUP(18, qup0_se6, dac_calib, _, _, _, _, _, _, _, _, _), + [19] = PINGROUP(19, qup0_se6, dac_calib, _, _, _, _, _, _, _, _, _), + [20] = PINGROUP(20, qup0_se7_01, qup0_se7_23, cri_trng, _, _, _, _, _, _, _, _), + [21] = PINGROUP(21, qup0_se7_01, qup0_se7_23, tsense_pwm, _, _, _, _, _, _, _, _), + [22] = PINGROUP(22, qup0_se8, pll, agera_pll, pbs_out, _, _, _, _, _, _, _), + [23] = PINGROUP(23, qup0_se8, agera_pll, pbs_out, _, _, _, _, _, _, _, _), + [24] = PINGROUP(24, qup0_se8, pbs_out, _, _, _, _, _, _, _, _, _), + [25] = PINGROUP(25, qup0_se8, _, _, _, _, _, _, _, _, _, _), + [26] = PINGROUP(26, qup0_se9_23, qup0_se9_01, _, _, _, _, _, _, _, _, _), + [27] = PINGROUP(27, qup0_se9_23, qup0_se9_01, prng_rosc, _, _, _, _, _, _, _, _), + [28] = PINGROUP(28, qup0_se1, qup0_se6, emac_mcg, prng_rosc, _, phase_flag, qdss_cti, + _, _, _, _), + [29] = PINGROUP(29, qup0_se1, qup0_se6, emac_mcg, _, phase_flag, qdss_cti, _, _, _, _, _), + [30] = PINGROUP(30, qup0_se2, qup0_se6, _, phase_flag, qdss_cti, _, _, _, _, _, _), + [31] = PINGROUP(31, qup0_se2, qup0_se6, emac1_ptp_aux, emac1_ptp_pps, _, phase_flag, qdss_cti, _, _, + _, _), + [32] = PINGROUP(32, pwm, sdc_tb_trig, _, _, _, _, _, _, _, _, _), + [33] = PINGROUP(33, emac1_ptp_aux, emac1_ptp_pps, sdc_tb_trig, _, _, _, _, _, _, _, _), + [34] = PINGROUP(34, cam_mclk, _, _, _, _, _, _, _, _, _, _), + [35] = PINGROUP(35, cam_mclk, unused_adsp, _, _, _, _, _, _, _, _, _), + [36] = PINGROUP(36, cci_i2c0, _, _, _, _, _, _, _, _, _, _), + [37] = PINGROUP(37, cci_i2c0, _, _, _, _, _, _, _, _, _, _), + [38] = PINGROUP(38, cci_timer, _, _, _, _, _, _, _, _, _, _), + [39] = PINGROUP(39, cci_async, _, _, _, _, _, _, _, _, _, _), + [40] = PINGROUP(40, cci_timer, emac_mcg, pwm, _, _, _, _, _, _, _, _), + [41] = PINGROUP(41, cci_i2c1, _, _, _, _, _, _, _, _, _, _), + [42] = PINGROUP(42, cci_i2c1, _, _, _, _, _, _, _, _, _, _), + [43] = PINGROUP(43, cci_timer, emac_mcg, pll, _, _, _, _, _, _, _, _), + [44] = PINGROUP(44, emac_mcg, pll, _, _, _, _, _, _, _, _, _), + [45] = PINGROUP(45, tsc_async, emac_mcg, pwm, gcc_gp, _, _, _, _, _, _, _), + [46] = PINGROUP(46, tsc_async, emac_mcg, _, _, _, _, _, _, _, _, _), + [47] = PINGROUP(47, cci_timer, emac_mcg, _, _, _, _, _, _, _, _, _), + [48] = PINGROUP(48, _, qup0_se9, _, _, pbs_in, phase_flag, _, _, _, _, _), + [49] = PINGROUP(49, _, qup0_se9, _, _, pbs_in, phase_flag, _, _, _, _, _), + [50] = PINGROUP(50, _, qup0_se9, _, _, pbs_in, phase_flag, _, _, _, _, _), + [51] = PINGROUP(51, _, qup0_se9, pbs_in, _, _, _, _, _, _, _, _), + [52] = PINGROUP(52, _, _, _, _, _, _, _, _, _, _, _), + [53] = PINGROUP(53, _, nav_gpio, gcc_gp, pwm, _, pbs_in, atest_usb, _, _, _, _), + [54] = PINGROUP(54, _, pwm, _, pbs_in, phase_flag, atest_char, _, _, _, _, _), + [55] = PINGROUP(55, _, pwm, _, pbs_in, phase_flag, atest_char, _, _, _, _, _), + [56] = PINGROUP(56, _, pwm, _, pbs_in, phase_flag, atest_char, _, _, _, _, _), + [57] = PINGROUP(57, _, pwm, _, pbs_in, phase_flag, atest_char, _, _, _, _, _), + [58] = PINGROUP(58, _, nav_gpio, pwm, _, pbs_in, atest_bbrx, atest_usb, vsense_trigger_mirnat, + emac_dll, _, _), + [59] = PINGROUP(59, _, vfr, _, pbs_in, atest_bbrx, atest_usb, emac_dll, _, _, _, _), + [60] = PINGROUP(60, _, emac1_ptp_aux, emac1_ptp_pps, emac0_ptp_aux, emac0_ptp_pps, _, pbs_in, atest_gpsadc, + atest_usb, emac_dll, _), + [61] = PINGROUP(61, _, pwm, gcc_gp, pa_indicator_or, dbg_out_clk, pbs_in, atest_usb, emac_dll, + _, _, _), + [62] = PINGROUP(62, _, pwm, _, pbs_in, phase_flag, atest_char, _, _, _, _, _), + [63] = PINGROUP(63, _, nav_gpio, emac0_ptp_aux, emac0_ptp_pps, _, pbs_in, phase_flag, dac_calib, + _, _, _), + [64] = PINGROUP(64, _, unused_gsm1, dac_calib, _, _, _, _, _, _, _, _), + [65] = PINGROUP(65, _, _, _, _, _, _, _, _, _, _, _), + [66] = PINGROUP(66, _, dac_calib, _, _, _, _, _, _, _, _, _), + [67] = PINGROUP(67, _, _, _, _, _, _, _, _, _, _, _), + [68] = PINGROUP(68, _, ssbi_wtr, emac1_ptp_aux, emac1_ptp_pps, pwm, dac_calib, _, _, _, _, _), + [69] = PINGROUP(69, _, ssbi_wtr, emac0_ptp_aux, emac0_ptp_pps, _, phase_flag, dac_calib, _, _, _, _), + [70] = PINGROUP(70, _, ssbi_wtr, _, phase_flag, dac_calib, _, _, _, _, _, _), + [71] = PINGROUP(71, _, ssbi_wtr, nav_gpio, _, phase_flag, _, _, _, _, _, _), + [72] = PINGROUP(72, _, _, phase_flag, _, _, _, _, _, _, _, _), + [73] = PINGROUP(73, _, _, _, _, _, _, _, _, _, _, _), + [74] = PINGROUP(74, pll, _, pbs_in, phase_flag, _, _, _, _, _, _, _), + [75] = PINGROUP(75, gsm0_tx, _, _, _, _, _, _, _, _, _, _), + [76] = PINGROUP(76, pll, _, _, _, _, _, _, _, _, _, _), + [77] = PINGROUP(77, uim2, pwm, _, _, _, _, _, _, _, _, _), + [78] = PINGROUP(78, uim2, _, _, _, _, _, _, _, _, _, _), + [79] = PINGROUP(79, uim2, pwm, _, _, _, _, _, _, _, _, _), + [80] = PINGROUP(80, uim2, pwm, _, _, _, _, _, _, _, _, _), + [81] = PINGROUP(81, uim1, _, _, _, _, _, _, _, _, _, _), + [82] = PINGROUP(82, uim1, _, _, _, _, _, _, _, _, _, _), + [83] = PINGROUP(83, uim1, _, _, _, _, _, _, _, _, _, _), + [84] = PINGROUP(84, uim1, _, _, _, _, _, _, _, _, _, _), + [85] = PINGROUP(85, emac0_ptp_aux, emac0_ptp_pps, _, _, _, _, _, _, _, _, _), + [86] = PINGROUP(86, mdp_vsync_p, mdp_vsync_out0, mdp_vsync_out1, _, _, _, _, _, _, _, _), + [87] = PINGROUP(87, _, pwm, _, _, _, _, _, _, _, _, _), + [88] = PINGROUP(88, gcc_gp, _, dac_calib, _, _, _, _, _, _, _, _), + [89] = PINGROUP(89, gcc_gp, _, dac_calib, _, _, _, _, _, _, _, _), + [90] = PINGROUP(90, usb0_phy_ps, _, dac_calib, _, _, _, _, _, _, _, _), + [91] = PINGROUP(91, nav_gpio, _, _, _, _, _, _, _, _, _, _), + [92] = PINGROUP(92, nav_gpio, _, _, _, _, _, _, _, _, _, _), + [93] = PINGROUP(93, _, _, _, _, _, _, _, _, _, _, _), + [94] = PINGROUP(94, mdp_vsync_e, qdss_cti, qdss_cti, _, _, _, _, _, _, _, _), + [95] = PINGROUP(95, nav_gpio, mdp_vsync_s, qdss_cti, qdss_cti, _, _, _, _, _, _, _), + [96] = PINGROUP(96, dmic, cam_mclk, i2s1, jitter_bist, atest_gpsadc, atest_usb, _, _, _, + _, _), + [97] = PINGROUP(97, dmic, i2s1, dac_calib, _, _, _, _, _, _, _, _), + [98] = PINGROUP(98, dmic, cam_mclk, i2s1, _, sdc_cdc, atest_usb, ddr_pxi, _, _, _, _), + [99] = PINGROUP(99, dmic, i2s1, jitter_bist, sdc_cdc, atest_usb, ddr_pxi, _, _, _, _, _), + [100] = PINGROUP(100, i2s2, nav_gpio, _, sdc_cdc, atest_usb, ddr_pxi, _, _, _, _, _), + [101] = PINGROUP(101, i2s2, nav_gpio, _, sdc_cdc, atest_usb, ddr_pxi, _, _, _, _, _), + [102] = PINGROUP(102, i2s2, pwm, _, phase_flag, _, _, _, _, _, _, _), + [103] = PINGROUP(103, ext_mclk, i2s2, _, _, _, _, _, _, _, _, _), + [104] = PINGROUP(104, ext_mclk, nav_gpio, _, _, _, _, _, _, _, _, _), + [105] = PINGROUP(105, swr0_tx, i2s0, _, _, _, _, _, _, _, _, _), + [106] = PINGROUP(106, swr0_tx, i2s0, _, _, _, _, _, _, _, _, _), + [107] = PINGROUP(107, swr0_rx, i2s0, _, _, _, _, _, _, _, _, _), + [108] = PINGROUP(108, swr0_rx, i2s0, _, _, _, _, _, _, _, _, _), + [109] = PINGROUP(109, swr0_rx, i2s0, sd_write_protect, _, _, _, _, _, _, _, _), + [110] = PINGROUP(110, ext_mclk, i2s0, _, gcc_gp, _, _, _, _, _, _, _), + [111] = PINGROUP(111, i2s3, _, _, _, _, _, _, _, _, _, _), + [112] = PINGROUP(112, i2s3, _, _, _, _, _, _, _, _, _, _), + [113] = PINGROUP(113, i2s3, _, _, _, _, _, _, _, _, _, _), + [114] = PINGROUP(114, ext_mclk, i2s3, _, _, _, _, _, _, _, _, _), + [115] = PINGROUP(115, mss_lte, _, _, _, _, _, _, _, _, _, _), + [116] = PINGROUP(116, mss_lte, _, dac_calib, _, _, _, _, _, _, _, _), + [117] = PINGROUP(117, pcie0_clk_req_n, _, dac_calib, _, _, _, _, _, _, _, _), + [118] = PINGROUP(118, _, dac_calib, _, _, _, _, _, _, _, _, _), + [119] = PINGROUP(119, _, _, _, _, _, _, _, _, _, _, _), + [120] = PINGROUP(120, emac_phy, _, _, _, _, _, _, _, _, _, _), + [121] = PINGROUP(121, rgmii, _, _, _, _, _, _, _, _, _, _), + [122] = PINGROUP(122, rgmii, _, _, _, _, _, _, _, _, _, _), + [123] = PINGROUP(123, rgmii, _, _, _, _, _, _, _, _, _, _), + [124] = PINGROUP(124, rgmii, _, _, _, _, _, _, _, _, _, _), + [125] = PINGROUP(125, rgmii, _, _, _, _, _, _, _, _, _, _), + [126] = PINGROUP(126, rgmii, _, _, _, _, _, _, _, _, _, _), + [127] = PINGROUP(127, rgmii, _, _, _, _, _, _, _, _, _, _), + [128] = PINGROUP(128, rgmii, _, _, _, _, _, _, _, _, _, _), + [129] = PINGROUP(129, rgmii, _, _, _, _, _, _, _, _, _, _), + [130] = PINGROUP(130, rgmii, _, _, _, _, _, _, _, _, _, _), + [131] = PINGROUP(131, rgmii, _, _, _, _, _, _, _, _, _, _), + [132] = PINGROUP(132, rgmii, _, _, _, _, _, _, _, _, _, _), + [133] = PINGROUP(133, rgmii, _, _, _, _, _, _, _, _, _, _), + [134] = PINGROUP(134, rgmii, _, _, _, _, _, _, _, _, _, _), + [135] = PINGROUP(135, rgmii, _, _, _, _, _, _, _, _, _, _), + [136] = PINGROUP(136, emac_phy, _, _, _, _, _, _, _, _, _, _), + [137] = PINGROUP(137, rgmii, _, _, _, _, _, _, _, _, _, _), + [138] = PINGROUP(138, rgmii, _, _, _, _, _, _, _, _, _, _), + [139] = PINGROUP(139, rgmii, _, _, _, _, _, _, _, _, _, _), + [140] = PINGROUP(140, rgmii, _, _, _, _, _, _, _, _, _, _), + [141] = PINGROUP(141, rgmii, _, _, _, _, _, _, _, _, _, _), + [142] = PINGROUP(142, rgmii, _, _, _, _, _, _, _, _, _, _), + [143] = PINGROUP(143, rgmii, _, _, _, _, _, _, _, _, _, _), + [144] = PINGROUP(144, rgmii, _, _, _, _, _, _, _, _, _, _), + [145] = PINGROUP(145, rgmii, _, _, _, _, _, _, _, _, _, _), + [146] = PINGROUP(146, rgmii, _, _, _, _, _, _, _, _, _, _), + [147] = PINGROUP(147, rgmii, _, _, _, _, _, _, _, _, _, _), + [148] = PINGROUP(148, rgmii, _, _, _, _, _, _, _, _, _, _), + [149] = PINGROUP(149, rgmii, _, _, _, _, _, _, _, _, _, _), + [150] = PINGROUP(150, rgmii, _, _, _, _, _, _, _, _, _, _), + [151] = PINGROUP(151, _, _, _, _, _, _, _, _, _, _, _), + [152] = PINGROUP(152, _, _, _, _, _, _, _, _, _, _, _), + [153] = PINGROUP(153, _, _, _, _, _, _, _, _, _, _, _), + [154] = PINGROUP(154, _, _, _, _, _, _, _, _, _, _, _), + [155] = PINGROUP(155, _, _, _, _, _, _, _, _, _, _, _), + [156] = PINGROUP(156, _, _, _, _, _, _, _, _, _, _, _), + [157] = PINGROUP(157, _, _, _, _, _, _, _, _, _, _, _), + [158] = PINGROUP(158, _, _, _, _, _, _, _, _, _, _, _), + [159] = PINGROUP(159, _, _, _, _, _, _, _, _, _, _, _), + [160] = PINGROUP(160, _, _, _, _, _, _, _, _, _, _, _), + [161] = PINGROUP(161, _, _, _, _, _, _, _, _, _, _, _), + [162] = SDC_QDSD_PINGROUP(sdc1_data, 0x1AC000, 9, 0), + [163] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x1AC004, 0, 0), + [164] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x1AC000, 11, 3), + [165] = SDC_QDSD_PINGROUP(sdc1_clk, 0x1AC000, 13, 6), + [166] = SDC_QDSD_PINGROUP(sdc2_clk, 0x1AA000, 14, 6), + [167] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x1AA000, 11, 3), + [168] = SDC_QDSD_PINGROUP(sdc2_data, 0x1AA000, 9, 0), +}; + +static const struct msm_pinctrl_soc_data shikra_tlmm = { + .pins = shikra_pins, + .npins = ARRAY_SIZE(shikra_pins), + .functions = shikra_functions, + .nfunctions = ARRAY_SIZE(shikra_functions), + .groups = shikra_groups, + .ngroups = ARRAY_SIZE(shikra_groups), + .ngpios = 166, + .egpio_func = 11, +}; + +static int shikra_tlmm_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &shikra_tlmm); +} + +static const struct of_device_id shikra_tlmm_of_match[] = { + { .compatible = "qcom,shikra-tlmm", .data = &shikra_tlmm }, + {}, +}; + +static struct platform_driver shikra_tlmm_driver = { + .driver = { + .name = "shikra-tlmm", + .of_match_table = shikra_tlmm_of_match, + }, + .probe = shikra_tlmm_probe, +}; + +static int __init shikra_tlmm_init(void) +{ + return platform_driver_register(&shikra_tlmm_driver); +} +arch_initcall(shikra_tlmm_init); + +static void __exit shikra_tlmm_exit(void) +{ + platform_driver_unregister(&shikra_tlmm_driver); +} +module_exit(shikra_tlmm_exit); + +MODULE_DESCRIPTION("QTI Shikra TLMM driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, shikra_tlmm_of_match); From 623cc0996eae657957d9f17e9bde60a1dba47b96 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Fri, 6 Mar 2026 15:25:18 +0530 Subject: [PATCH 045/128] dt-bindings: power: qcom,rpmpd: document the Shikra RPM Power Domains Document the RPM Power Domains on the Shikra Platform. Signed-off-by: Rakesh Kota --- Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 0bf1e13a99646..1abb4b733fe79 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -55,6 +55,7 @@ properties: - qcom,sdx55-rpmhpd - qcom,sdx65-rpmhpd - qcom,sdx75-rpmhpd + - qcom,shikra-rpmpd - qcom,sm4450-rpmhpd - qcom,sm6115-rpmpd - qcom,sm6125-rpmpd From c4e9b6709eaffabece52fdc90eaa35b98c85f676 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Fri, 6 Mar 2026 15:53:10 +0530 Subject: [PATCH 046/128] soc: qcom: rpmpd: Add Shikra RPM support Shikra has the same RPM power domains as QCM2290. Add shikra support by reusing QCM2290 power domains. Signed-off-by: Rakesh Kota --- drivers/pmdomain/qcom/rpmpd.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c index 15a11ff282c3f..8ccb5d4358b17 100644 --- a/drivers/pmdomain/qcom/rpmpd.c +++ b/drivers/pmdomain/qcom/rpmpd.c @@ -863,6 +863,21 @@ static const struct rpmpd_desc sdm660_desc = { .max_state = RPM_SMD_LEVEL_TURBO, }; +static struct rpmpd *shikra_rpmpds[] = { + [RPMPD_VDDCX] = &cx_rwcx0_lvl, + [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl, + [RPMPD_VDDMX] = &mx_rwmx0_lvl, + [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl, +}; + +static const struct rpmpd_desc shikra_desc = { + .rpmpds = shikra_rpmpds, + .num_pds = ARRAY_SIZE(shikra_rpmpds), + .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, +}; + static struct rpmpd *sm6115_rpmpds[] = { [SM6115_VDDCX] = &cx_rwcx0_lvl, [SM6115_VDDCX_AO] = &cx_rwcx0_lvl_ao, From a220769a86d8f3e3878175a1eed04f61673de729 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Wed, 11 Mar 2026 18:05:55 +0530 Subject: [PATCH 047/128] dt-bindings: regulator: qcom,smd-rpm-regulator: Document PM8150 IC Document the pm8150 compatible string and available regulators in the QCOM SMD RPM regulator documentation. Signed-off-by: Rakesh Kota --- .../devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml index b7241ce975b96..c00d481bcc079 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml @@ -35,6 +35,9 @@ description: For pm660l s1, s2, s3, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, bob + For pm8150, s1, s2, s3, s4, s5, s6, s7, s8, s9,s10, l1, l2, l3, l4, l5, l6, + l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18 + For pm8226, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, l25, l26, l27, l28, lvs1 @@ -91,6 +94,7 @@ properties: - qcom,rpm-pm6125-regulators - qcom,rpm-pm660-regulators - qcom,rpm-pm660l-regulators + - qcom,rpm-pm8150-regulators - qcom,rpm-pm8226-regulators - qcom,rpm-pm8841-regulators - qcom,rpm-pm8909-regulators From b61b97eaa331a4dee7207a8a08158fffe816bf9b Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Wed, 11 Mar 2026 17:02:20 +0530 Subject: [PATCH 048/128] regulator: qcom_smd: Add PM8150 regulators The PM8150 is found on boards with shikra SoCs and It provides 10 SMPS and 18 LDO regulators. Signed-off-by: Rakesh Kota --- drivers/regulator/qcom_smd-regulator.c | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 25ed9f713974b..03ec2bdc27a37 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -913,6 +913,38 @@ static const struct rpm_regulator_data rpm_pm660l_regulators[] = { { } }; +static const struct rpm_regulator_data rpm_pm8150_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pmic5_ftsmps520, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pmic5_ftsmps520, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pmic5_ftsmps520, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8998_hfsmps, "vdd_s4" }, + { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8998_hfsmps, "vdd_s5" }, + { "s6", QCOM_SMD_RPM_SMPA, 6, &pmic5_ftsmps520, "vdd_s6" }, + { "s7", QCOM_SMD_RPM_SMPA, 7, &pmic5_ftsmps520, "vdd_s7" }, + { "s8", QCOM_SMD_RPM_SMPA, 8, &pmic5_ftsmps520, "vdd_s8" }, + { "s9", QCOM_SMD_RPM_SMPA, 9, &pmic5_ftsmps520, "vdd_s9" }, + { "s10", QCOM_SMD_RPM_SMPA, 10, &pmic5_ftsmps520, "vdd_s10" }, + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm660_nldo660, "vdd_l1_l8_l11" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm660_pldo660, "vdd_l2_l10" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm660_nldo660, "vdd_l3_l4_l5_l18" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm660_nldo660, "vdd_l3_l4_l5_l18" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm660_nldo660, "vdd_l3_l4_l5_l18" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm660_nldo660, "vdd_l6_l9" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm660_pldo660, "vdd_l7_l12_l14_l15" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm660_nldo660, "vdd_l1_l8_l11" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm660_nldo660, "vdd_l6_l9" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm660_pldo660, "vdd_l2_l10" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm660_nldo660, "vdd_l1_l8_l11" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm660_ht_lvpldo, "vdd_l7_l12_l14_l15" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm660_pldo660, "vdd_l13_l16_l17" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm660_ht_lvpldo, "vdd_l7_l12_l14_l15" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm660_ht_lvpldo, "vdd_l7_l12_l14_l15" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm660_pldo660, "vdd_l13_l16_l17" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm660_pldo660, "vdd_l13_l16_l17" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm660_nldo660, "vdd_l3_l4_l5_l18" }, + { } +}; + static const struct rpm_regulator_data rpm_pm8226_regulators[] = { { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8226_hfsmps, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8226_ftsmps, "vdd_s2" }, @@ -1358,6 +1390,7 @@ static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm6125-regulators", .data = &rpm_pm6125_regulators }, { .compatible = "qcom,rpm-pm660-regulators", .data = &rpm_pm660_regulators }, { .compatible = "qcom,rpm-pm660l-regulators", .data = &rpm_pm660l_regulators }, + { .compatible = "qcom,rpm-pm8150-regulators", .data = &rpm_pm8150_regulators }, { .compatible = "qcom,rpm-pm8226-regulators", .data = &rpm_pm8226_regulators }, { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, { .compatible = "qcom,rpm-pm8909-regulators", .data = &rpm_pm8909_regulators }, From b56a9053f4464c24a2a3d6a695ef28c10815bf0a Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Wed, 25 Mar 2026 11:19:46 +0530 Subject: [PATCH 049/128] soc: qcom: rpmpd: Add Shikra RPM compatiable Add the rpmpd compatable string for shikra. Signed-off-by: Rakesh Kota --- drivers/pmdomain/qcom/rpmpd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c index 8ccb5d4358b17..6f751ee5a7833 100644 --- a/drivers/pmdomain/qcom/rpmpd.c +++ b/drivers/pmdomain/qcom/rpmpd.c @@ -964,6 +964,7 @@ static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, { .compatible = "qcom,qm215-rpmpd", .data = &qm215_desc }, { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, + { .compatible = "qcom,shikra-rpmpd", .data = &shikra_desc }, { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, { .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc }, From 632284a856d968ae4698e1534cbea2f80fa39a2a Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Thu, 26 Mar 2026 15:11:01 +0530 Subject: [PATCH 050/128] dt-bindings: arm-smmu: Add adreno-smmu compatible for Shikra SoC Qualcomm Shikra SoC implements qcom,smmu-500 for adreno-smmu. Document its corresponding compatible. Signed-off-by: Bibek Kumar Patro --- Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml index 1f544103b574c..fb58dde93690a 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -106,6 +106,7 @@ properties: - qcom,sc7280-smmu-500 - qcom,sc8180x-smmu-500 - qcom,sc8280xp-smmu-500 + - qcom,shikra-smmu-500 - qcom,sm6115-smmu-500 - qcom,sm6125-smmu-500 - qcom,sm8150-smmu-500 From 68281a4f8519aeb65b62903e4c94fbaee6f455b5 Mon Sep 17 00:00:00 2001 From: Vishnu Santhosh Date: Tue, 27 Jan 2026 13:43:04 +0530 Subject: [PATCH 051/128] mailbox: qcom-apcs-ipc-mailbox: Add compatible string Add "qcom,shikra-apcs-hmss-global" compatibility string in qcom_apcs_ipc mailbox driver to match apcs_glb device node. Signed-off-by: Vishnu Santhosh --- drivers/mailbox/qcom-apcs-ipc-mailbox.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c index d3a8f6b4a03b3..8e544dbe3c5ff 100644 --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c @@ -168,6 +168,7 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = { { .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq6018_apcs_data }, { .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data }, { .compatible = "qcom,sc8180x-apss-shared", .data = &apps_shared_apcs_data }, + { .compatible = "qcom,shikra-apcs-hmss-global", .data = &apps_shared_apcs_data }, { .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data }, {} }; From e26b2ada4858ee415ae44a6a828957a3096422c8 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 27 Mar 2026 17:17:17 +0530 Subject: [PATCH 052/128] dt-bindings: nvmem: qfprom: Add Shikra compatible Document compatible string for the QFPROM on Shikra platform. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml index 2ab047f2bb69d..52b86133ee00d 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml @@ -48,6 +48,7 @@ properties: - qcom,sdm630-qfprom - qcom,sdm670-qfprom - qcom,sdm845-qfprom + - qcom,shikra-qfprom - qcom,sm6115-qfprom - qcom,sm6350-qfprom - qcom,sm6375-qfprom From 09709ff26029f363ebbc41e99c06bb4886542b13 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 27 Mar 2026 18:01:13 +0530 Subject: [PATCH 053/128] dt-bindings: remoteproc: qcom: Add Shikra RPM processor compatible Add the qcom,shikra-rpm-proc compatible string to the Qualcomm RPM remote processor device tree binding. Signed-off-by: Sneh Mankad Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml index 540bdfca53d97..823304afaa98f 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml @@ -87,6 +87,7 @@ properties: - qcom,qcm2290-rpm-proc - qcom,qcs404-rpm-proc - qcom,sdm660-rpm-proc + - qcom,shikra-rpm-proc - qcom,sm6115-rpm-proc - qcom,sm6125-rpm-proc - qcom,sm6375-rpm-proc From 82c1d2bea2e1d4c32bd839a2d85895577235b848 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 27 Mar 2026 18:14:37 +0530 Subject: [PATCH 054/128] dt-bindings: mailbox: qcom: Add the Shikra APCS compatible Add compatible for the Qualcomm Shikra APCS block to the Qualcomm APCS binding. Signed-off-by: Sneh Mankad Signed-off-by: Komal Bajaj --- .../devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml index f40dc90483272..bc1dc44fc2de8 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml @@ -65,6 +65,7 @@ properties: - qcom,msm8996-apcs-hmss-global - qcom,qcm2290-apcs-hmss-global - qcom,sdm845-apss-shared + - qcom,shikra-apcs-hmss-global reg: maxItems: 1 @@ -238,6 +239,7 @@ allOf: - qcom,msm8996-apcs-hmss-global - qcom,qcm2290-apcs-hmss-global - qcom,sdm845-apss-shared + - qcom,shikra-apcs-hmss-global then: properties: clocks: false From 43123ea68173997a59391678868188fcfa8e244f Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 27 Mar 2026 18:19:38 +0530 Subject: [PATCH 055/128] dt-bindings: soc: qcom: qcom,smd-rpm: Add compatible for Shikra Document the compatible for Shikra. Signed-off-by: Sneh Mankad Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml index 270bcd079f886..bd1d32898461c 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml @@ -57,6 +57,7 @@ properties: - qcom,rpm-qcm2290 - qcom,rpm-qcs404 - qcom,rpm-sdm660 + - qcom,rpm-shikra - qcom,rpm-sm6115 - qcom,rpm-sm6125 - qcom,rpm-sm6375 From 30a040f84c25706b50aa0e661fed769ccf5df3b2 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 13 Mar 2026 19:17:43 +0530 Subject: [PATCH 056/128] dt-bindings: clock: qcom,rpmcc: Add Shikra compatible Document the qcom,rpmcc-shikra compatible. Signed-off-by: Imran Shaik --- Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index ab97d4b7dba8b..06f8439bb032a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -46,6 +46,7 @@ properties: - qcom,rpmcc-qcs404 - qcom,rpmcc-sdm429 - qcom,rpmcc-sdm660 + - qcom,rpmcc-shikra - qcom,rpmcc-sm6115 - qcom,rpmcc-sm6125 - qcom,rpmcc-sm6375 From 4575e1eef5e20ea2f1327d8f2e3202a4b9ac4886 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 13 Mar 2026 18:38:09 +0530 Subject: [PATCH 057/128] dt-bindings: clock: qcom: Add GCC clocks for Shikra Add support for qcom global clock controller bindings for Shikra platform. Signed-off-by: Imran Shaik --- .../bindings/clock/qcom,shikra-gcc.yaml | 63 +++++ include/dt-bindings/clock/qcom,shikra-gcc.h | 258 ++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml create mode 100644 include/dt-bindings/clock/qcom,shikra-gcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml new file mode 100644 index 0000000000000..39cf7383df8bc --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,shikra-gcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller on Shikra + +maintainers: + - Imran Shaik + - Taniya Das + +description: | + Qualcomm global clock control module provides the clocks, resets and power + domains on Shikra. + + See also: include/dt-bindings/clock/qcom,shikra-gcc.h + +properties: + compatible: + const: qcom,shikra-gcc + + clocks: + items: + - description: Board XO source + - description: Sleep clock source + - description: EMAC0 sgmiiphy mac rclk source + - description: EMAC0 sgmiiphy mac tclk source + - description: EMAC1 sgmiiphy mac rclk source + - description: EMAC1 sgmiiphy mac tclk source + - description: PCIE Pipe clock source + - description: USB3 phy wrapper pipe clock source + +required: + - compatible + - clocks + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + clock-controller@1400000 { + compatible = "qcom,shikra-gcc"; + reg = <0x01400000 0x1f0000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <&emac0_sgmiiphy_rclk>, + <&emac0_sgmiiphy_tclk>, + <&emac1_sgmiiphy_rclk>, + <&emac1_sgmiiphy_tclk>, + <&pcie_pipe_clk>, + <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + +... diff --git a/include/dt-bindings/clock/qcom,shikra-gcc.h b/include/dt-bindings/clock/qcom,shikra-gcc.h new file mode 100644 index 0000000000000..77c6159755ce9 --- /dev/null +++ b/include/dt-bindings/clock/qcom,shikra-gcc.h @@ -0,0 +1,258 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SHIKRA_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SHIKRA_H + +/* GCC clocks */ +#define GPLL0 0 +#define GPLL0_OUT_AUX2 1 +#define GPLL1 2 +#define GPLL10 3 +#define GPLL11 4 +#define GPLL12 5 +#define GPLL12_OUT_AUX2 6 +#define GPLL3 7 +#define GPLL3_OUT_MAIN 8 +#define GPLL4 9 +#define GPLL5 10 +#define GPLL6 11 +#define GPLL6_OUT_MAIN 12 +#define GPLL7 13 +#define GPLL8 14 +#define GPLL8_OUT_MAIN 15 +#define GPLL9 16 +#define GPLL9_OUT_MAIN 17 +#define GCC_AHB2PHY_CSI_CLK 18 +#define GCC_AHB2PHY_USB_CLK 19 +#define GCC_BOOT_ROM_AHB_CLK 20 +#define GCC_CAM_THROTTLE_NRT_CLK 21 +#define GCC_CAM_THROTTLE_RT_CLK 22 +#define GCC_CAMERA_AHB_CLK 23 +#define GCC_CAMERA_XO_CLK 24 +#define GCC_CAMSS_AXI_CLK 25 +#define GCC_CAMSS_AXI_CLK_SRC 26 +#define GCC_CAMSS_CAMNOC_ATB_CLK 27 +#define GCC_CAMSS_CAMNOC_DRAGONLINK_ATB_CLK 28 +#define GCC_CAMSS_CAMNOC_NTS_XO_CLK 29 +#define GCC_CAMSS_CCI_0_CLK 30 +#define GCC_CAMSS_CCI_CLK_SRC 31 +#define GCC_CAMSS_CPHY_0_CLK 32 +#define GCC_CAMSS_CPHY_1_CLK 33 +#define GCC_CAMSS_CSI0PHYTIMER_CLK 34 +#define GCC_CAMSS_CSI0PHYTIMER_CLK_SRC 35 +#define GCC_CAMSS_CSI1PHYTIMER_CLK 36 +#define GCC_CAMSS_CSI1PHYTIMER_CLK_SRC 37 +#define GCC_CAMSS_MCLK0_CLK 38 +#define GCC_CAMSS_MCLK0_CLK_SRC 39 +#define GCC_CAMSS_MCLK1_CLK 40 +#define GCC_CAMSS_MCLK1_CLK_SRC 41 +#define GCC_CAMSS_MCLK2_CLK 42 +#define GCC_CAMSS_MCLK2_CLK_SRC 43 +#define GCC_CAMSS_MCLK3_CLK 44 +#define GCC_CAMSS_MCLK3_CLK_SRC 45 +#define GCC_CAMSS_NRT_AXI_CLK 46 +#define GCC_CAMSS_OPE_AHB_CLK 47 +#define GCC_CAMSS_OPE_AHB_CLK_SRC 48 +#define GCC_CAMSS_OPE_CLK 49 +#define GCC_CAMSS_OPE_CLK_SRC 50 +#define GCC_CAMSS_RT_AXI_CLK 51 +#define GCC_CAMSS_TFE_0_CLK 52 +#define GCC_CAMSS_TFE_0_CLK_SRC 53 +#define GCC_CAMSS_TFE_0_CPHY_RX_CLK 54 +#define GCC_CAMSS_TFE_0_CSID_CLK 55 +#define GCC_CAMSS_TFE_0_CSID_CLK_SRC 56 +#define GCC_CAMSS_TFE_1_CLK 57 +#define GCC_CAMSS_TFE_1_CLK_SRC 58 +#define GCC_CAMSS_TFE_1_CPHY_RX_CLK 59 +#define GCC_CAMSS_TFE_1_CSID_CLK 60 +#define GCC_CAMSS_TFE_1_CSID_CLK_SRC 61 +#define GCC_CAMSS_TFE_CPHY_RX_CLK_SRC 62 +#define GCC_CAMSS_TOP_AHB_CLK 63 +#define GCC_CAMSS_TOP_AHB_CLK_SRC 64 +#define GCC_CFG_NOC_USB2_PRIM_AXI_CLK 65 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 66 +#define GCC_DDRSS_GPU_AXI_CLK 67 +#define GCC_DDRSS_MEMNOC_PCIE_SF_CLK 68 +#define GCC_DISP_AHB_CLK 69 +#define GCC_DISP_GPLL0_CLK_SRC 70 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 71 +#define GCC_DISP_HF_AXI_CLK 72 +#define GCC_DISP_THROTTLE_CORE_CLK 73 +#define GCC_DISP_XO_CLK 74 +#define GCC_EMAC0_AHB_CLK 75 +#define GCC_EMAC0_AXI_CLK 76 +#define GCC_EMAC0_AXI_CLK_SRC 77 +#define GCC_EMAC0_AXI_SYS_NOC_CLK 78 +#define GCC_EMAC0_CC_SGMIIPHY_RX_CLK 79 +#define GCC_EMAC0_CC_SGMIIPHY_RX_CLK_SRC 80 +#define GCC_EMAC0_CC_SGMIIPHY_TX_CLK 81 +#define GCC_EMAC0_CC_SGMIIPHY_TX_CLK_SRC 82 +#define GCC_EMAC0_PHY_AUX_CLK 83 +#define GCC_EMAC0_PHY_AUX_CLK_SRC 84 +#define GCC_EMAC0_PTP_CLK 85 +#define GCC_EMAC0_PTP_CLK_SRC 86 +#define GCC_EMAC0_RGMII_CLK 87 +#define GCC_EMAC0_RGMII_CLK_SRC 88 +#define GCC_EMAC1_AHB_CLK 89 +#define GCC_EMAC1_AXI_CLK 90 +#define GCC_EMAC1_AXI_CLK_SRC 91 +#define GCC_EMAC1_AXI_SYS_NOC_CLK 92 +#define GCC_EMAC1_CC_SGMIIPHY_RX_CLK 93 +#define GCC_EMAC1_CC_SGMIIPHY_RX_CLK_SRC 94 +#define GCC_EMAC1_CC_SGMIIPHY_TX_CLK 95 +#define GCC_EMAC1_CC_SGMIIPHY_TX_CLK_SRC 96 +#define GCC_EMAC1_PHY_AUX_CLK 97 +#define GCC_EMAC1_PHY_AUX_CLK_SRC 98 +#define GCC_EMAC1_PTP_CLK 99 +#define GCC_EMAC1_PTP_CLK_SRC 100 +#define GCC_EMAC1_RGMII_CLK 101 +#define GCC_EMAC1_RGMII_CLK_SRC 102 +#define GCC_GP1_CLK 103 +#define GCC_GP1_CLK_SRC 104 +#define GCC_GP2_CLK 105 +#define GCC_GP2_CLK_SRC 106 +#define GCC_GP3_CLK 107 +#define GCC_GP3_CLK_SRC 108 +#define GCC_GPU_CFG_AHB_CLK 109 +#define GCC_GPU_GPLL0_CLK_SRC 110 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 111 +#define GCC_GPU_MEMNOC_GFX_CLK 112 +#define GCC_GPU_SMMU_VOTE_CLK 113 +#define GCC_GPU_SNOC_DVM_GFX_CLK 114 +#define GCC_GPU_THROTTLE_CORE_CLK 115 +#define GCC_MMU_TCU_VOTE_CLK 116 +#define GCC_PCIE_AUX_CLK 117 +#define GCC_PCIE_AUX_CLK_SRC 118 +#define GCC_PCIE_AUX_PHY_CLK_SRC 119 +#define GCC_PCIE_CFG_AHB_CLK 120 +#define GCC_PCIE_CLKREF_EN 121 +#define GCC_PCIE_MSTR_AXI_CLK 122 +#define GCC_PCIE_PIPE_CLK 123 +#define GCC_PCIE_PIPE_CLK_SRC 124 +#define GCC_PCIE_RCHNG_PHY_CLK 125 +#define GCC_PCIE_RCHNG_PHY_CLK_SRC 126 +#define GCC_PCIE_SLEEP_CLK 127 +#define GCC_PCIE_SLV_AXI_CLK 128 +#define GCC_PCIE_SLV_Q2A_AXI_CLK 129 +#define GCC_PCIE_TBU_CLK 130 +#define GCC_PCIE_THROTTLE_CORE_CLK 131 +#define GCC_PCIE_THROTTLE_XO_CLK 132 +#define GCC_PCIE_TILE_AXI_SYS_NOC_CLK 133 +#define GCC_PDM2_CLK 134 +#define GCC_PDM2_CLK_SRC 135 +#define GCC_PDM_AHB_CLK 136 +#define GCC_PDM_XO4_CLK 137 +#define GCC_PWM0_XO512_CLK 138 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 139 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 140 +#define GCC_QMIP_DISP_AHB_CLK 141 +#define GCC_QMIP_GPU_CFG_AHB_CLK 142 +#define GCC_QMIP_PCIE_CFG_AHB_CLK 143 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 144 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 145 +#define GCC_QUPV3_WRAP0_CORE_CLK 146 +#define GCC_QUPV3_WRAP0_S0_CLK 147 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 148 +#define GCC_QUPV3_WRAP0_S1_CLK 149 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 150 +#define GCC_QUPV3_WRAP0_S2_CLK 151 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 152 +#define GCC_QUPV3_WRAP0_S3_CLK 153 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 154 +#define GCC_QUPV3_WRAP0_S4_CLK 155 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 156 +#define GCC_QUPV3_WRAP0_S5_CLK 157 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 158 +#define GCC_QUPV3_WRAP0_S6_CLK 159 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 160 +#define GCC_QUPV3_WRAP0_S7_CLK 161 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 162 +#define GCC_QUPV3_WRAP0_S8_CLK 163 +#define GCC_QUPV3_WRAP0_S8_CLK_SRC 164 +#define GCC_QUPV3_WRAP0_S9_CLK 165 +#define GCC_QUPV3_WRAP0_S9_CLK_SRC 166 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 167 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 168 +#define GCC_SDCC1_AHB_CLK 169 +#define GCC_SDCC1_APPS_CLK 170 +#define GCC_SDCC1_APPS_CLK_SRC 171 +#define GCC_SDCC1_ICE_CORE_CLK 172 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 173 +#define GCC_SDCC2_AHB_CLK 174 +#define GCC_SDCC2_APPS_CLK 175 +#define GCC_SDCC2_APPS_CLK_SRC 176 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 177 +#define GCC_SYS_NOC_USB2_PRIM_AXI_CLK 178 +#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK 179 +#define GCC_TSCSS_AHB_CLK 180 +#define GCC_TSCSS_CLK_SRC 181 +#define GCC_TSCSS_CNTR_CLK 182 +#define GCC_TSCSS_ETU_CLK 183 +#define GCC_UFS_CLKREF_EN 184 +#define GCC_USB20_MASTER_CLK 185 +#define GCC_USB20_MASTER_CLK_SRC 186 +#define GCC_USB20_MOCK_UTMI_CLK 187 +#define GCC_USB20_MOCK_UTMI_CLK_SRC 188 +#define GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC 189 +#define GCC_USB20_SLEEP_CLK 190 +#define GCC_USB30_PRIM_MASTER_CLK 191 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 192 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 193 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 194 +#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 195 +#define GCC_USB30_PRIM_SLEEP_CLK 196 +#define GCC_USB3_PRIM_CLKREF_EN 197 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 198 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 199 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 200 +#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 201 +#define GCC_VCODEC0_AXI_CLK 202 +#define GCC_VENUS_AHB_CLK 203 +#define GCC_VENUS_CTL_AXI_CLK 204 +#define GCC_VIDEO_AHB_CLK 205 +#define GCC_VIDEO_AXI0_CLK 206 +#define GCC_VIDEO_THROTTLE_CORE_CLK 207 +#define GCC_VIDEO_VCODEC0_SYS_CLK 208 +#define GCC_VIDEO_VENUS_CLK_SRC 209 +#define GCC_VIDEO_VENUS_CTL_CLK 210 +#define GCC_VIDEO_XO_CLK 211 + +/* GCC power domains */ +#define GCC_CAMSS_TOP_GDSC 0 +#define GCC_EMAC0_GDSC 1 +#define GCC_EMAC1_GDSC 2 +#define GCC_PCIE_GDSC 3 +#define GCC_USB20_GDSC 4 +#define GCC_USB30_PRIM_GDSC 5 +#define GCC_VCODEC0_GDSC 6 +#define GCC_VENUS_GDSC 7 + +/* GCC resets */ +#define GCC_CAMSS_OPE_BCR 0 +#define GCC_CAMSS_TFE_BCR 1 +#define GCC_CAMSS_TOP_BCR 2 +#define GCC_EMAC0_BCR 3 +#define GCC_EMAC1_BCR 4 +#define GCC_GPU_BCR 5 +#define GCC_MMSS_BCR 6 +#define GCC_PCIE_BCR 7 +#define GCC_PCIE_PHY_BCR 8 +#define GCC_PDM_BCR 9 +#define GCC_QUPV3_WRAPPER_0_BCR 10 +#define GCC_QUSB2PHY_PRIM_BCR 11 +#define GCC_SDCC1_BCR 12 +#define GCC_SDCC2_BCR 13 +#define GCC_TSCSS_BCR 14 +#define GCC_USB20_BCR 15 +#define GCC_USB30_PRIM_BCR 16 +#define GCC_USB3PHY_PHY_PRIM_SP0_BCR 17 +#define GCC_USB3_PHY_PRIM_SP0_BCR 18 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 19 +#define GCC_VCODEC0_BCR 20 +#define GCC_VENUS_BCR 21 +#define GCC_VIDEO_INTERFACE_BCR 22 + +#endif From 049cf4d6c41ded5dc8dd84cbdbb666b908b4fb29 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 13 Mar 2026 19:20:30 +0530 Subject: [PATCH 058/128] clk: qcom: smd-rpm: Add clocks for Shikra Add support for RPM-managed clocks on the Shikra platform. Signed-off-by: Imran Shaik --- drivers/clk/qcom/clk-smd-rpm.c | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 103db984a40b9..50daa2b0b8235 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -1289,6 +1289,44 @@ static const struct rpm_smd_clk_desc rpm_clk_qcm2290 = { .num_icc_clks = ARRAY_SIZE(qcm2290_icc_clks) }; +static struct clk_smd_rpm *shikra_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, + [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_branch_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_branch_qdss_a_clk, + [RPM_SMD_LN_BB_CLK2] = &clk_smd_rpm_ln_bb_clk2, + [RPM_SMD_LN_BB_CLK2_A] = &clk_smd_rpm_ln_bb_clk2_a, + [RPM_SMD_RF_CLK1] = &clk_smd_rpm_rf_clk1, + [RPM_SMD_RF_CLK1_A]= &clk_smd_rpm_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, + [RPM_SMD_RF_CLK3] = &clk_smd_rpm_38m4_rf_clk3, + [RPM_SMD_RF_CLK3_A] = &clk_smd_rpm_38m4_rf_clk3_a, + [RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk, + [RPM_SMD_SNOC_PERIPH_CLK] = &clk_smd_rpm_bus_0_snoc_periph_clk, + [RPM_SMD_SNOC_PERIPH_A_CLK] = &clk_smd_rpm_bus_0_snoc_periph_a_clk, + [RPM_SMD_SNOC_LPASS_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_clk, + [RPM_SMD_SNOC_LPASS_A_CLK] = &clk_smd_rpm_bus_5_snoc_lpass_a_clk, + [RPM_SMD_CE1_CLK] = &clk_smd_rpm_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &clk_smd_rpm_ce1_a_clk, + [RPM_SMD_QPIC_CLK] = &clk_smd_rpm_qpic_clk, + [RPM_SMD_QPIC_CLK_A] = &clk_smd_rpm_qpic_a_clk, + [RPM_SMD_HWKM_CLK] = &clk_smd_rpm_hwkm_clk, + [RPM_SMD_HWKM_A_CLK] = &clk_smd_rpm_hwkm_a_clk, + [RPM_SMD_PKA_CLK] = &clk_smd_rpm_pka_clk, + [RPM_SMD_PKA_A_CLK] = &clk_smd_rpm_pka_a_clk, + [RPM_SMD_BIMC_GPU_CLK] = &clk_smd_rpm_bimc_gpu_clk, + [RPM_SMD_BIMC_GPU_A_CLK] = &clk_smd_rpm_bimc_gpu_a_clk, +}; + +static const struct rpm_smd_clk_desc rpm_clk_shikra = { + .clks = shikra_clks, + .num_clks = ARRAY_SIZE(shikra_clks), + .icc_clks = qcm2290_icc_clks, + .num_icc_clks = ARRAY_SIZE(qcm2290_icc_clks) +}; + static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 }, { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, @@ -1309,6 +1347,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, { .compatible = "qcom,rpmcc-sdm429", .data = &rpm_clk_sdm429 }, { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 }, + { .compatible = "qcom,rpmcc-shikra", .data = &rpm_clk_shikra }, { .compatible = "qcom,rpmcc-sm6115", .data = &rpm_clk_sm6115 }, { .compatible = "qcom,rpmcc-sm6125", .data = &rpm_clk_sm6125 }, { .compatible = "qcom,rpmcc-sm6375", .data = &rpm_clk_sm6375 }, From 94dce2391a4ea2c07b06c8b8183ef6772ae90850 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 13 Mar 2026 17:37:50 +0530 Subject: [PATCH 059/128] clk: qcom: Add support for Global clock controller on Shikra Add support for Global clock controller for Shikra Qualcomm SoC. Signed-off-by: Imran Shaik --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-shikra.c | 4484 +++++++++++++++++++++++++++++++++ 3 files changed, 4494 insertions(+) create mode 100644 drivers/clk/qcom/gcc-shikra.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index df21ef5ffd686..a2c7751b091a4 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -155,6 +155,15 @@ config CLK_NORD_GCC SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination of GCC, SE_GCC, NE_GCC and NW_GCC. +config CLK_SHIKRA_GCC + tristate "Shikra Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on Shikra devices. + Say Y if you want to use multimedia devices or peripheral + devices such as Camera, Video, UART, SPI, I2C, USB, SD/eMMC etc. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 89d07c35e4d93..08a2cf68cb9cb 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o +obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/gcc-shikra.c b/drivers/clk/qcom/gcc-shikra.c new file mode 100644 index 0000000000000..3ca5ed7cd48a1 --- /dev/null +++ b/drivers/clk/qcom/gcc-shikra.c @@ -0,0 +1,4484 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_EMAC0_SGMIIPHY_RCLK, + DT_EMAC0_SGMIIPHY_TCLK, + DT_EMAC1_SGMIIPHY_RCLK, + DT_EMAC1_SGMIIPHY_TCLK, + DT_PCIE_PIPE_CLK, + DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_EMAC0_SGMIIPHY_RCLK, + P_EMAC0_SGMIIPHY_TCLK, + P_EMAC1_SGMIIPHY_RCLK, + P_EMAC1_SGMIIPHY_TCLK, + P_GPLL0_OUT_AUX2, + P_GPLL0_OUT_EARLY, + P_GPLL10_OUT_MAIN, + P_GPLL11_OUT_AUX, + P_GPLL11_OUT_AUX2, + P_GPLL11_OUT_MAIN, + P_GPLL12_OUT_AUX2, + P_GPLL12_OUT_EARLY, + P_GPLL3_OUT_EARLY, + P_GPLL3_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_GPLL5_OUT_MAIN, + P_GPLL6_OUT_EARLY, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_GPLL8_OUT_EARLY, + P_GPLL8_OUT_MAIN, + P_GPLL9_OUT_EARLY, + P_GPLL9_OUT_MAIN, + P_PCIE_PIPE_CLK, + P_SLEEP_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static const struct pll_vco brammo_vco[] = { + { 500000000, 1250000000, 0 }, +}; + +static const struct pll_vco spark_vco[] = { + { 750000000, 1500000000, 1 }, + { 500000000, 1000000000, 2 }, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_aux2[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll0_out_aux2, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_aux2", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gpll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +/* 1152.0 MHz Configuration */ +static const struct alpha_pll_config gpll10_config = { + .l = 0x3c, + .alpha = 0x0, + .vco_val = BIT(20), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .config_ctl_val = 0x4001055b, + .test_ctl_hi1_val = 0x1, +}; + +static struct clk_alpha_pll gpll10 = { + .offset = 0xa000, + .config = &gpll10_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gpll10", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config gpll11_config = { + .l = 0x1f, + .alpha = 0x0, + .alpha_hi = 0x40, + .alpha_en_mask = BIT(24), + .vco_val = BIT(21), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .config_ctl_val = 0x4001055b, + .test_ctl_hi1_val = 0x1, +}; + +static struct clk_alpha_pll gpll11 = { + .offset = 0xb000, + .config = &gpll11_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gpll11", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll12 = { + .offset = 0xc000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gpll12", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll12_out_aux2[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll12_out_aux2 = { + .offset = 0xc000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll12_out_aux2, + .num_post_div = ARRAY_SIZE(post_div_table_gpll12_out_aux2), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll12_out_aux2", + .parent_hws = (const struct clk_hw*[]) { + &gpll12.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gpll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll3_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll3_out_main = { + .offset = 0x3000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll3_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll3_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll3_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll3.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll5 = { + .offset = 0x5000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gpll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6 = { + .offset = 0x6000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gpll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll6_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll6_out_main = { + .offset = 0x6000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll6_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll6_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll6.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +/* 533.2 MHz Configuration */ +static const struct alpha_pll_config gpll8_config = { + .l = 0x1b, + .alpha = 0x55555555, + .alpha_hi = 0xc5, + .alpha_en_mask = BIT(24), + .vco_val = BIT(21), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .early_output_mask = BIT(3), + .post_div_val = BIT(8), + .post_div_mask = GENMASK(11, 8), + .config_ctl_val = 0x4001055b, + .test_ctl_hi1_val = 0x1, +}; + +static struct clk_alpha_pll gpll8 = { + .offset = 0x8000, + .config = &gpll8_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gpll8", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll8_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll8_out_main = { + .offset = 0x8000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll8_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll8_out_main", + .parent_hws = (const struct clk_hw*[]) { + &gpll8.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +/* 1152.0 MHz Configuration */ +static const struct alpha_pll_config gpll9_config = { + .l = 0x3c, + .alpha = 0x0, + .post_div_val = BIT(8), + .post_div_mask = GENMASK(9, 8), + .main_output_mask = BIT(0), + .early_output_mask = BIT(3), + .config_ctl_val = 0x00004289, + .test_ctl_val = 0x08000000, +}; + +static struct clk_alpha_pll gpll9 = { + .offset = 0x9000, + .config = &gpll9_config, + .vco_table = brammo_vco, + .num_vco = ARRAY_SIZE(brammo_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll9_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll9_out_main = { + .offset = 0x9000, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll9_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main), + .width = 2, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO], + .clkr.hw.init = &(const struct clk_init_data){ + .name = "gpll9_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll9.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL6_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll6_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL9_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL6_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll6_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL12_OUT_AUX2, 4 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL12_OUT_AUX2, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_13[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_13[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_14[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL9_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_14[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll8_out_main.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_15[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 2 }, + { P_GPLL10_OUT_MAIN, 3 }, + { P_GPLL6_OUT_EARLY, 5 }, + { P_GPLL3_OUT_MAIN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_15[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll8.clkr.hw }, + { .hw = &gpll10.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll3_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_21[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_21[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_aux2.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll4.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_22[] = { + { P_BI_TCXO, 0 }, + { P_GPLL12_OUT_EARLY, 1 }, + { P_GPLL5_OUT_MAIN, 3 }, + { P_GPLL12_OUT_AUX2, 4 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_22[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll12.clkr.hw }, + { .hw = &gpll5.clkr.hw }, + { .hw = &gpll12_out_aux2.clkr.hw }, + { .hw = &gpll3.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_24[] = { + { P_BI_TCXO, 0 }, + { P_GPLL11_OUT_MAIN, 1 }, + { P_GPLL11_OUT_AUX, 2 }, + { P_GPLL11_OUT_AUX2, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_24[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpll11.clkr.hw }, + { .hw = &gpll11.clkr.hw }, + { .hw = &gpll11.clkr.hw }, +}; + +static struct clk_regmap_phy_mux gcc_emac0_cc_sgmiiphy_rx_clk_src = { + .reg = 0xad048, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_rx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC0_SGMIIPHY_RCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac0_cc_sgmiiphy_tx_clk_src = { + .reg = 0xad040, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_tx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC0_SGMIIPHY_TCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac1_cc_sgmiiphy_rx_clk_src = { + .reg = 0xae048, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_rx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC1_SGMIIPHY_RCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_emac1_cc_sgmiiphy_tx_clk_src = { + .reg = 0xae040, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_tx_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_EMAC1_SGMIIPHY_TCLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_pipe_clk_src = { + .reg = 0xaf058, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_pipe_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_PCIE_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x1a05c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_axi_clk_src = { + .cmd_rcgr = 0x5802c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_camss_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_axi_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cci_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_cci_clk_src = { + .cmd_rcgr = 0x56000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_14, + .freq_tbl = ftbl_gcc_camss_cci_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cci_clk_src", + .parent_data = gcc_parent_data_14, + .num_parents = ARRAY_SIZE(gcc_parent_data_14), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(268800000, P_GPLL4_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = { + .cmd_rcgr = 0x45000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi0phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = { + .cmd_rcgr = 0x4501c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi1phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_mclk0_clk_src[] = { + F(19200000, P_GPLL9_OUT_EARLY, 1, 1, 60), + F(24000000, P_GPLL9_OUT_MAIN, 1, 1, 24), + F(64000000, P_GPLL9_OUT_EARLY, 9, 1, 2), + { } +}; + +static struct clk_rcg2 gcc_camss_mclk0_clk_src = { + .cmd_rcgr = 0x51000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk0_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk1_clk_src = { + .cmd_rcgr = 0x5101c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk1_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk2_clk_src = { + .cmd_rcgr = 0x51038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk2_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk3_clk_src = { + .cmd_rcgr = 0x51054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk3_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_ope_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(171428571, P_GPLL0_OUT_EARLY, 3.5, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = { + .cmd_rcgr = 0x55024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_ope_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_ahb_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_ope_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL8_OUT_MAIN, 2, 0, 0), + F(266600000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(465000000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(580000000, P_GPLL8_OUT_EARLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_ope_clk_src = { + .cmd_rcgr = 0x55004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_ope_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(128000000, P_GPLL10_OUT_MAIN, 9, 0, 0), + F(135529412, P_GPLL10_OUT_MAIN, 8.5, 0, 0), + F(144000000, P_GPLL10_OUT_MAIN, 8, 0, 0), + F(153600000, P_GPLL10_OUT_MAIN, 7.5, 0, 0), + F(164571429, P_GPLL10_OUT_MAIN, 7, 0, 0), + F(177230769, P_GPLL10_OUT_MAIN, 6.5, 0, 0), + F(192000000, P_GPLL10_OUT_MAIN, 6, 0, 0), + F(209454545, P_GPLL10_OUT_MAIN, 5.5, 0, 0), + F(230400000, P_GPLL10_OUT_MAIN, 5, 0, 0), + F(256000000, P_GPLL10_OUT_MAIN, 4.5, 0, 0), + F(288000000, P_GPLL10_OUT_MAIN, 4, 0, 0), + F(329142857, P_GPLL10_OUT_MAIN, 3.5, 0, 0), + F(384000000, P_GPLL10_OUT_MAIN, 3, 0, 0), + F(460800000, P_GPLL10_OUT_MAIN, 2.5, 0, 0), + F(576000000, P_GPLL10_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_0_clk_src = { + .cmd_rcgr = 0x52004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(120000000, P_GPLL0_OUT_EARLY, 5, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + F(426400000, P_GPLL3_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = { + .cmd_rcgr = 0x52094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_csid_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_tfe_1_clk_src = { + .cmd_rcgr = 0x52024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = { + .cmd_rcgr = 0x520b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_csid_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_tfe_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + F(341333333, P_GPLL6_OUT_EARLY, 1, 4, 9), + F(384000000, P_GPLL6_OUT_EARLY, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = { + .cmd_rcgr = 0x52064, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_15, + .freq_tbl = ftbl_gcc_camss_tfe_cphy_rx_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_cphy_rx_clk_src", + .parent_data = gcc_parent_data_15, + .num_parents = ARRAY_SIZE(gcc_parent_data_15), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_top_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(40000000, P_GPLL0_OUT_AUX2, 7.5, 0, 0), + F(80000000, P_GPLL0_OUT_EARLY, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_top_ahb_clk_src = { + .cmd_rcgr = 0x58010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_camss_top_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_top_ahb_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_axi_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_axi_clk_src = { + .cmd_rcgr = 0x109dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_phy_aux_clk_src = { + .cmd_rcgr = 0xad01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_phy_aux_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_ptp_clk_src[] = { + F(250000000, P_GPLL12_OUT_AUX2, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_ptp_clk_src = { + .cmd_rcgr = 0xad064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ptp_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac0_rgmii_clk_src[] = { + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(125000000, P_GPLL12_OUT_AUX2, 4, 0, 0), + F(250000000, P_GPLL12_OUT_EARLY, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac0_rgmii_clk_src = { + .cmd_rcgr = 0xad04c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .freq_tbl = ftbl_gcc_emac0_rgmii_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_rgmii_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_axi_clk_src = { + .cmd_rcgr = 0x109fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_phy_aux_clk_src = { + .cmd_rcgr = 0xae01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_phy_aux_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_ptp_clk_src = { + .cmd_rcgr = 0xae064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ptp_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_emac1_rgmii_clk_src = { + .cmd_rcgr = 0xae04c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .freq_tbl = ftbl_gcc_emac0_rgmii_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_rgmii_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x4d004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x4e004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x4f004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_aux_clk_src = { + .cmd_rcgr = 0xaf074, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = { + .cmd_rcgr = 0xaf05c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_phy_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_rchng_phy_clk_src[] = { + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = { + .cmd_rcgr = 0xaf028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_rchng_phy_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rchng_phy_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_AUX2, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x20010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_AUX2, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_AUX2, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_AUX2, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_AUX2, 1, 8, 75), + F(48000000, P_GPLL0_OUT_AUX2, 1, 4, 25), + F(64000000, P_GPLL0_OUT_AUX2, 1, 16, 75), + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(80000000, P_GPLL0_OUT_AUX2, 1, 4, 15), + F(96000000, P_GPLL0_OUT_AUX2, 1, 8, 25), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(102400000, P_GPLL0_OUT_AUX2, 1, 128, 375), + F(112000000, P_GPLL0_OUT_AUX2, 1, 28, 75), + F(117964800, P_GPLL0_OUT_AUX2, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x1f148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x1f278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x1f3a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x1f4d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x1f608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x1f738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { + .cmd_rcgr = 0x1f868, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { + .cmd_rcgr = 0x1f998, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s8_clk_src_init = { + .name = "gcc_qupv3_wrap0_s8_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s8_clk_src = { + .cmd_rcgr = 0x1fac8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s8_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s9_clk_src_init = { + .name = "gcc_qupv3_wrap0_s9_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s9_clk_src = { + .cmd_rcgr = 0x1fbf8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &gcc_qupv3_wrap0_s9_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_AUX2, 5, 1, 3), + F(25000000, P_GPLL0_OUT_AUX2, 6, 1, 2), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x38028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x38010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1e00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_21, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_21, + .num_parents = ARRAY_SIZE(gcc_parent_data_21), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static struct clk_rcg2 gcc_tscss_clk_src = { + .cmd_rcgr = 0xac004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_22, + .freq_tbl = ftbl_gcc_emac0_ptp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_clk_src", + .parent_data = gcc_parent_data_22, + .num_parents = ARRAY_SIZE(gcc_parent_data_22), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb20_master_clk_src[] = { + F(60000000, P_GPLL0_OUT_AUX2, 5, 0, 0), + F(120000000, P_GPLL0_OUT_EARLY, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb20_master_clk_src = { + .cmd_rcgr = 0xb003c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb20_master_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0xb0020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_13, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk_src", + .parent_data = gcc_parent_data_13, + .num_parents = ARRAY_SIZE(gcc_parent_data_13), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_AUX2, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_EARLY, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x1a01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x1a034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x1a060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_video_venus_clk_src[] = { + F(133333333, P_GPLL11_OUT_MAIN, 4.5, 0, 0), + F(240000000, P_GPLL11_OUT_MAIN, 2.5, 0, 0), + F(300000000, P_GPLL11_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL11_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_video_venus_clk_src = { + .cmd_rcgr = 0x6d000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_24, + .freq_tbl = ftbl_gcc_video_venus_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_video_venus_clk_src", + .parent_data = gcc_parent_data_24, + .num_parents = ARRAY_SIZE(gcc_parent_data_24), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = { + .reg = 0xb0038, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x1a04c, + .shift = 0, + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_ahb2phy_csi_clk = { + .halt_reg = 0x1d004, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x1d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_csi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ahb2phy_usb_clk = { + .halt_reg = 0x1d008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1d008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ahb2phy_usb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cam_throttle_nrt_clk = { + .halt_reg = 0x17070, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cam_throttle_nrt_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cam_throttle_rt_clk = { + .halt_reg = 0x1706c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1706c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cam_throttle_rt_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_axi_clk = { + .halt_reg = 0x58044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_atb_clk = { + .halt_reg = 0x5804c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x5804c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_dragonlink_atb_clk = { + .halt_reg = 0x58060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x58060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x58060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_dragonlink_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_camnoc_nts_xo_clk = { + .halt_reg = 0x58050, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x58050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x58050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_camnoc_nts_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_0_clk = { + .halt_reg = 0x56018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x56018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_cci_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_0_clk = { + .halt_reg = 0x52088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cphy_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_1_clk = { + .halt_reg = 0x5208c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5208c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_cphy_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0phytimer_clk = { + .halt_reg = 0x45018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x45018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1phytimer_clk = { + .halt_reg = 0x45034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x45034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk0_clk = { + .halt_reg = 0x51018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk1_clk = { + .halt_reg = 0x51034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk2_clk = { + .halt_reg = 0x51050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk3_clk = { + .halt_reg = 0x5106c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5106c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_nrt_axi_clk = { + .halt_reg = 0x58054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_nrt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ope_ahb_clk = { + .halt_reg = 0x5503c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5503c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_ope_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ope_clk = { + .halt_reg = 0x5501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5501c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_ope_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_ope_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_rt_axi_clk = { + .halt_reg = 0x5805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_rt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_clk = { + .halt_reg = 0x5201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5201c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_cphy_rx_clk = { + .halt_reg = 0x5207c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5207c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_0_csid_clk = { + .halt_reg = 0x520ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x520ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_0_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_0_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_clk = { + .halt_reg = 0x5203c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5203c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_cphy_rx_clk = { + .halt_reg = 0x52080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_tfe_1_csid_clk = { + .halt_reg = 0x520cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x520cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_tfe_1_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_tfe_1_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_top_ahb_clk = { + .halt_reg = 0x58028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x58028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camss_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_camss_top_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_prim_axi_clk = { + .halt_reg = 0x111c4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x111c4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x111c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a07c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1a07c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a07c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x71000, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x71000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_memnoc_pcie_sf_clk = { + .halt_reg = 0x29044, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x29044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x29044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_memnoc_pcie_sf_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap_div gcc_disp_gpll0_clk_src = { + .reg = 0x17058, + .shift = 0, + .width = 2, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gcc_disp_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_disp_gpll0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x17020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_throttle_core_clk = { + .halt_reg = 0x17064, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17064, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_ahb_clk = { + .halt_reg = 0xad010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xad010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_axi_clk = { + .halt_reg = 0xad014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xad014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_axi_sys_noc_clk = { + .halt_reg = 0x109d4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x109d4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x109d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_cc_sgmiiphy_rx_clk = { + .halt_reg = 0xad044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xad044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_cc_sgmiiphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_cc_sgmiiphy_tx_clk = { + .halt_reg = 0xad03c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xad03c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xad03c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_cc_sgmiiphy_tx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_cc_sgmiiphy_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_phy_aux_clk = { + .halt_reg = 0xad018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_ptp_clk = { + .halt_reg = 0xad034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_ptp_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_ptp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac0_rgmii_clk = { + .halt_reg = 0xad038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xad038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac0_rgmii_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_rgmii_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_ahb_clk = { + .halt_reg = 0xae010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xae010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_axi_clk = { + .halt_reg = 0xae014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xae014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_axi_sys_noc_clk = { + .halt_reg = 0x109f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x109f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x109f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_cc_sgmiiphy_rx_clk = { + .halt_reg = 0xae044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xae044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_cc_sgmiiphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_cc_sgmiiphy_tx_clk = { + .halt_reg = 0xae03c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xae03c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xae03c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_cc_sgmiiphy_tx_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_cc_sgmiiphy_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_phy_aux_clk = { + .halt_reg = 0xae018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_ptp_clk = { + .halt_reg = 0xae034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_ptp_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_ptp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac1_rgmii_clk = { + .halt_reg = 0xae038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xae038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_emac1_rgmii_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac1_rgmii_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x4d000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x4e000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x4f000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4f000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0_out_aux2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x3600c, + .halt_check = BRANCH_VOTED, + .hwcg_reg = 0x3600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_smmu_vote_clk = { + .halt_reg = 0x7d000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x36018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_throttle_core_clk = { + .halt_reg = 0x36048, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x36048, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mmu_tcu_vote_clk = { + .halt_reg = 0x7d06c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7d06c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_mmu_tcu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_aux_clk = { + .halt_reg = 0xaf044, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_cfg_ahb_clk = { + .halt_reg = 0xaf010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_clkref_en = { + .halt_reg = 0xb8000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb8000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_mstr_axi_clk = { + .halt_reg = 0xaf020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_pipe_clk = { + .halt_reg = 0xaf050, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xaf050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_rchng_phy_clk = { + .halt_reg = 0xaf040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rchng_phy_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_rchng_phy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_sleep_clk = { + .halt_reg = 0xaf04c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf04c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_sleep_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_aux_phy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_slv_axi_clk = { + .halt_reg = 0xaf018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_slv_q2a_axi_clk = { + .halt_reg = 0xaf014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_tbu_clk = { + .halt_reg = 0xaf098, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf098, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_throttle_core_clk = { + .halt_reg = 0xaf094, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_throttle_xo_clk = { + .halt_reg = 0xaf090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_throttle_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_tile_axi_sys_noc_clk = { + .halt_reg = 0x10f2c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x10f2c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x10f2c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_tile_axi_sys_noc_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_emac0_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x2000c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x20004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x20004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x20004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x20008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pwm0_xo512_clk = { + .halt_reg = 0x2002c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2002c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pwm0_xo512_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x17060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_ahb_clk = { + .halt_reg = 0x17018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_cfg_ahb_clk = { + .halt_reg = 0x36040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x36040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_cfg_ahb_clk = { + .halt_reg = 0xaf08c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xaf08c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79018, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x17010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x1f014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1f00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x1f144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x1f274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x1f3a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x1f4d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x1f604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x1f734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s6_clk = { + .halt_reg = 0x1f864, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s7_clk = { + .halt_reg = 0x1f994, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s8_clk = { + .halt_reg = 0x1fac4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s8_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s8_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s9_clk = { + .halt_reg = 0x1fbf4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s9_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s9_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x1f004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1f004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x1f008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x38008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x38008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x38008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x38004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x3800c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x3800c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1e008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1e008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb2_prim_axi_clk = { + .halt_reg = 0x10a14, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x10a14, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x10a14, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sys_noc_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a078, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1a078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sys_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_ahb_clk = { + .halt_reg = 0xac024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xac024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xac024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_cntr_clk = { + .halt_reg = 0xac020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xac020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_cntr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_tscss_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tscss_etu_clk = { + .halt_reg = 0xac01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xac01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_tscss_etu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_tscss_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_clkref_en = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0xb0010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb0010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb0010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0xb001c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb001c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0xb0018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xb0018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x1a010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1a010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x1a018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x1a014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_en = { + .halt_reg = 0x9f000, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x9f000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x1a054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x1a058, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x1a058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1a058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vcodec0_axi_clk = { + .halt_reg = 0x6e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_vcodec0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus_ahb_clk = { + .halt_reg = 0x6e010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_venus_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_venus_ctl_axi_clk = { + .halt_reg = 0x6e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6e004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_venus_ctl_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x1701c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1701c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_throttle_core_clk = { + .halt_reg = 0x17068, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17068, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_vcodec0_sys_clk = { + .halt_reg = 0x6d044, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x6d044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6d044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_vcodec0_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_video_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_venus_ctl_clk = { + .halt_reg = 0x6d02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6d02c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_venus_ctl_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_video_venus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_camss_top_gdsc = { + .gdscr = 0x58004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_camss_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_emac0_gdsc = { + .gdscr = 0xad004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_emac0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_emac1_gdsc = { + .gdscr = 0xae004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_emac1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_pcie_gdsc = { + .gdscr = 0xaf004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb20_gdsc = { + .gdscr = 0xb0004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb20_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x1a004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_venus_gdsc = { + .gdscr = 0x6d01c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_venus_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_vcodec0_gdsc = { + .gdscr = 0x6d038, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_vcodec0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &gcc_venus_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_shikra_clocks[] = { + [GCC_AHB2PHY_CSI_CLK] = &gcc_ahb2phy_csi_clk.clkr, + [GCC_AHB2PHY_USB_CLK] = &gcc_ahb2phy_usb_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr, + [GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr, + [GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr, + [GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr, + [GCC_CAMSS_CAMNOC_ATB_CLK] = &gcc_camss_camnoc_atb_clk.clkr, + [GCC_CAMSS_CAMNOC_DRAGONLINK_ATB_CLK] = &gcc_camss_camnoc_dragonlink_atb_clk.clkr, + [GCC_CAMSS_CAMNOC_NTS_XO_CLK] = &gcc_camss_camnoc_nts_xo_clk.clkr, + [GCC_CAMSS_CCI_0_CLK] = &gcc_camss_cci_0_clk.clkr, + [GCC_CAMSS_CCI_CLK_SRC] = &gcc_camss_cci_clk_src.clkr, + [GCC_CAMSS_CPHY_0_CLK] = &gcc_camss_cphy_0_clk.clkr, + [GCC_CAMSS_CPHY_1_CLK] = &gcc_camss_cphy_1_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK_SRC] = &gcc_camss_csi0phytimer_clk_src.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK_SRC] = &gcc_camss_csi1phytimer_clk_src.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK0_CLK_SRC] = &gcc_camss_mclk0_clk_src.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MCLK1_CLK_SRC] = &gcc_camss_mclk1_clk_src.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MCLK2_CLK_SRC] = &gcc_camss_mclk2_clk_src.clkr, + [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr, + [GCC_CAMSS_MCLK3_CLK_SRC] = &gcc_camss_mclk3_clk_src.clkr, + [GCC_CAMSS_NRT_AXI_CLK] = &gcc_camss_nrt_axi_clk.clkr, + [GCC_CAMSS_OPE_AHB_CLK] = &gcc_camss_ope_ahb_clk.clkr, + [GCC_CAMSS_OPE_AHB_CLK_SRC] = &gcc_camss_ope_ahb_clk_src.clkr, + [GCC_CAMSS_OPE_CLK] = &gcc_camss_ope_clk.clkr, + [GCC_CAMSS_OPE_CLK_SRC] = &gcc_camss_ope_clk_src.clkr, + [GCC_CAMSS_RT_AXI_CLK] = &gcc_camss_rt_axi_clk.clkr, + [GCC_CAMSS_TFE_0_CLK] = &gcc_camss_tfe_0_clk.clkr, + [GCC_CAMSS_TFE_0_CLK_SRC] = &gcc_camss_tfe_0_clk_src.clkr, + [GCC_CAMSS_TFE_0_CPHY_RX_CLK] = &gcc_camss_tfe_0_cphy_rx_clk.clkr, + [GCC_CAMSS_TFE_0_CSID_CLK] = &gcc_camss_tfe_0_csid_clk.clkr, + [GCC_CAMSS_TFE_0_CSID_CLK_SRC] = &gcc_camss_tfe_0_csid_clk_src.clkr, + [GCC_CAMSS_TFE_1_CLK] = &gcc_camss_tfe_1_clk.clkr, + [GCC_CAMSS_TFE_1_CLK_SRC] = &gcc_camss_tfe_1_clk_src.clkr, + [GCC_CAMSS_TFE_1_CPHY_RX_CLK] = &gcc_camss_tfe_1_cphy_rx_clk.clkr, + [GCC_CAMSS_TFE_1_CSID_CLK] = &gcc_camss_tfe_1_csid_clk.clkr, + [GCC_CAMSS_TFE_1_CSID_CLK_SRC] = &gcc_camss_tfe_1_csid_clk_src.clkr, + [GCC_CAMSS_TFE_CPHY_RX_CLK_SRC] = &gcc_camss_tfe_cphy_rx_clk_src.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr, + [GCC_CFG_NOC_USB2_PRIM_AXI_CLK] = &gcc_cfg_noc_usb2_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DDRSS_MEMNOC_PCIE_SF_CLK] = &gcc_ddrss_memnoc_pcie_sf_clk.clkr, + [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr, + [GCC_EMAC0_AHB_CLK] = &gcc_emac0_ahb_clk.clkr, + [GCC_EMAC0_AXI_CLK] = &gcc_emac0_axi_clk.clkr, + [GCC_EMAC0_AXI_CLK_SRC] = &gcc_emac0_axi_clk_src.clkr, + [GCC_EMAC0_AXI_SYS_NOC_CLK] = &gcc_emac0_axi_sys_noc_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_RX_CLK] = &gcc_emac0_cc_sgmiiphy_rx_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_RX_CLK_SRC] = &gcc_emac0_cc_sgmiiphy_rx_clk_src.clkr, + [GCC_EMAC0_CC_SGMIIPHY_TX_CLK] = &gcc_emac0_cc_sgmiiphy_tx_clk.clkr, + [GCC_EMAC0_CC_SGMIIPHY_TX_CLK_SRC] = &gcc_emac0_cc_sgmiiphy_tx_clk_src.clkr, + [GCC_EMAC0_PHY_AUX_CLK] = &gcc_emac0_phy_aux_clk.clkr, + [GCC_EMAC0_PHY_AUX_CLK_SRC] = &gcc_emac0_phy_aux_clk_src.clkr, + [GCC_EMAC0_PTP_CLK] = &gcc_emac0_ptp_clk.clkr, + [GCC_EMAC0_PTP_CLK_SRC] = &gcc_emac0_ptp_clk_src.clkr, + [GCC_EMAC0_RGMII_CLK] = &gcc_emac0_rgmii_clk.clkr, + [GCC_EMAC0_RGMII_CLK_SRC] = &gcc_emac0_rgmii_clk_src.clkr, + [GCC_EMAC1_AHB_CLK] = &gcc_emac1_ahb_clk.clkr, + [GCC_EMAC1_AXI_CLK] = &gcc_emac1_axi_clk.clkr, + [GCC_EMAC1_AXI_CLK_SRC] = &gcc_emac1_axi_clk_src.clkr, + [GCC_EMAC1_AXI_SYS_NOC_CLK] = &gcc_emac1_axi_sys_noc_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_RX_CLK] = &gcc_emac1_cc_sgmiiphy_rx_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_RX_CLK_SRC] = &gcc_emac1_cc_sgmiiphy_rx_clk_src.clkr, + [GCC_EMAC1_CC_SGMIIPHY_TX_CLK] = &gcc_emac1_cc_sgmiiphy_tx_clk.clkr, + [GCC_EMAC1_CC_SGMIIPHY_TX_CLK_SRC] = &gcc_emac1_cc_sgmiiphy_tx_clk_src.clkr, + [GCC_EMAC1_PHY_AUX_CLK] = &gcc_emac1_phy_aux_clk.clkr, + [GCC_EMAC1_PHY_AUX_CLK_SRC] = &gcc_emac1_phy_aux_clk_src.clkr, + [GCC_EMAC1_PTP_CLK] = &gcc_emac1_ptp_clk.clkr, + [GCC_EMAC1_PTP_CLK_SRC] = &gcc_emac1_ptp_clk_src.clkr, + [GCC_EMAC1_RGMII_CLK] = &gcc_emac1_rgmii_clk.clkr, + [GCC_EMAC1_RGMII_CLK_SRC] = &gcc_emac1_rgmii_clk_src.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SMMU_VOTE_CLK] = &gcc_gpu_smmu_vote_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_GPU_THROTTLE_CORE_CLK] = &gcc_gpu_throttle_core_clk.clkr, + [GCC_MMU_TCU_VOTE_CLK] = &gcc_mmu_tcu_vote_clk.clkr, + [GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr, + [GCC_PCIE_AUX_CLK_SRC] = &gcc_pcie_aux_clk_src.clkr, + [GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr, + [GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr, + [GCC_PCIE_CLKREF_EN] = &gcc_pcie_clkref_en.clkr, + [GCC_PCIE_MSTR_AXI_CLK] = &gcc_pcie_mstr_axi_clk.clkr, + [GCC_PCIE_PIPE_CLK] = &gcc_pcie_pipe_clk.clkr, + [GCC_PCIE_PIPE_CLK_SRC] = &gcc_pcie_pipe_clk_src.clkr, + [GCC_PCIE_RCHNG_PHY_CLK] = &gcc_pcie_rchng_phy_clk.clkr, + [GCC_PCIE_RCHNG_PHY_CLK_SRC] = &gcc_pcie_rchng_phy_clk_src.clkr, + [GCC_PCIE_SLEEP_CLK] = &gcc_pcie_sleep_clk.clkr, + [GCC_PCIE_SLV_AXI_CLK] = &gcc_pcie_slv_axi_clk.clkr, + [GCC_PCIE_SLV_Q2A_AXI_CLK] = &gcc_pcie_slv_q2a_axi_clk.clkr, + [GCC_PCIE_TBU_CLK] = &gcc_pcie_tbu_clk.clkr, + [GCC_PCIE_THROTTLE_CORE_CLK] = &gcc_pcie_throttle_core_clk.clkr, + [GCC_PCIE_THROTTLE_XO_CLK] = &gcc_pcie_throttle_xo_clk.clkr, + [GCC_PCIE_TILE_AXI_SYS_NOC_CLK] = &gcc_pcie_tile_axi_sys_noc_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PWM0_XO512_CLK] = &gcc_pwm0_xo512_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_GPU_CFG_AHB_CLK] = &gcc_qmip_gpu_cfg_ahb_clk.clkr, + [GCC_QMIP_PCIE_CFG_AHB_CLK] = &gcc_qmip_pcie_cfg_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr, + [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr, + [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr, + [GCC_QUPV3_WRAP0_S8_CLK] = &gcc_qupv3_wrap0_s8_clk.clkr, + [GCC_QUPV3_WRAP0_S8_CLK_SRC] = &gcc_qupv3_wrap0_s8_clk_src.clkr, + [GCC_QUPV3_WRAP0_S9_CLK] = &gcc_qupv3_wrap0_s9_clk.clkr, + [GCC_QUPV3_WRAP0_S9_CLK_SRC] = &gcc_qupv3_wrap0_s9_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_USB2_PRIM_AXI_CLK] = &gcc_sys_noc_usb2_prim_axi_clk.clkr, + [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr, + [GCC_TSCSS_AHB_CLK] = &gcc_tscss_ahb_clk.clkr, + [GCC_TSCSS_CLK_SRC] = &gcc_tscss_clk_src.clkr, + [GCC_TSCSS_CNTR_CLK] = &gcc_tscss_cntr_clk.clkr, + [GCC_TSCSS_ETU_CLK] = &gcc_tscss_etu_clk.clkr, + [GCC_UFS_CLKREF_EN] = &gcc_ufs_clkref_en.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK_SRC] = &gcc_usb20_mock_utmi_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb20_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_EN] = &gcc_usb3_prim_clkref_en.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_VCODEC0_AXI_CLK] = &gcc_vcodec0_axi_clk.clkr, + [GCC_VENUS_AHB_CLK] = &gcc_venus_ahb_clk.clkr, + [GCC_VENUS_CTL_AXI_CLK] = &gcc_venus_ctl_axi_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_THROTTLE_CORE_CLK] = &gcc_video_throttle_core_clk.clkr, + [GCC_VIDEO_VCODEC0_SYS_CLK] = &gcc_video_vcodec0_sys_clk.clkr, + [GCC_VIDEO_VENUS_CLK_SRC] = &gcc_video_venus_clk_src.clkr, + [GCC_VIDEO_VENUS_CTL_CLK] = &gcc_video_venus_ctl_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_AUX2] = &gpll0_out_aux2.clkr, + [GPLL1] = &gpll1.clkr, + [GPLL10] = &gpll10.clkr, + [GPLL11] = &gpll11.clkr, + [GPLL12] = &gpll12.clkr, + [GPLL12_OUT_AUX2] = &gpll12_out_aux2.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_OUT_MAIN] = &gpll3_out_main.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL5] = &gpll5.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL6_OUT_MAIN] = &gpll6_out_main.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL8] = &gpll8.clkr, + [GPLL8_OUT_MAIN] = &gpll8_out_main.clkr, + [GPLL9] = &gpll9.clkr, + [GPLL9_OUT_MAIN] = &gpll9_out_main.clkr, +}; + +static struct gdsc *gcc_shikra_gdscs[] = { + [GCC_CAMSS_TOP_GDSC] = &gcc_camss_top_gdsc, + [GCC_EMAC0_GDSC] = &gcc_emac0_gdsc, + [GCC_EMAC1_GDSC] = &gcc_emac1_gdsc, + [GCC_PCIE_GDSC] = &gcc_pcie_gdsc, + [GCC_USB20_GDSC] = &gcc_usb20_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_VCODEC0_GDSC] = &gcc_vcodec0_gdsc, + [GCC_VENUS_GDSC] = &gcc_venus_gdsc, +}; + +static const struct qcom_reset_map gcc_shikra_resets[] = { + [GCC_CAMSS_OPE_BCR] = { 0x55000 }, + [GCC_CAMSS_TFE_BCR] = { 0x52000 }, + [GCC_CAMSS_TOP_BCR] = { 0x58000 }, + [GCC_EMAC0_BCR] = { 0xad000 }, + [GCC_EMAC1_BCR] = { 0xae000 }, + [GCC_GPU_BCR] = { 0x36000 }, + [GCC_MMSS_BCR] = { 0x17000 }, + [GCC_PCIE_BCR] = { 0xaf000 }, + [GCC_PCIE_PHY_BCR] = { 0xb1000 }, + [GCC_PDM_BCR] = { 0x20000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x1f000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 }, + [GCC_SDCC1_BCR] = { 0x38000 }, + [GCC_SDCC2_BCR] = { 0x1e000 }, + [GCC_TSCSS_BCR] = { 0xac000 }, + [GCC_USB20_BCR] = { 0xb0000 }, + [GCC_USB30_PRIM_BCR] = { 0x1a000 }, + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 }, + [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 }, + [GCC_VCODEC0_BCR] = { 0x6d034 }, + [GCC_VENUS_BCR] = { 0x6d018 }, + [GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 }, +}; + +static struct clk_alpha_pll *gcc_shikra_plls[] = { + &gpll10, + &gpll11, + &gpll8, + &gpll9, +}; + +static u32 gcc_shikra_critical_cbcrs[] = { + 0x17008, /* GCC_CAMERA_AHB_CLK */ + 0x17028, /* GCC_CAMERA_XO_CLK */ + 0x1700c, /* GCC_DISP_AHB_CLK */ + 0x1702c, /* GCC_DISP_XO_CLK */ + 0x36004, /* GCC_GPU_CFG_AHB_CLK */ + 0x36100, /* GCC_GPU_IREF_CLK */ + 0x79004, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ + 0x17004, /* GCC_VIDEO_AHB_CLK */ + 0x17024, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct clk_rcg_dfs_data gcc_shikra_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s8_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s9_clk_src), +}; + +static const struct regmap_config gcc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xc7000, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gcc_shikra_driver_data = { + .alpha_plls = gcc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(gcc_shikra_plls), + .clk_cbcrs = gcc_shikra_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_shikra_critical_cbcrs), + .dfs_rcgs = gcc_shikra_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_shikra_dfs_clocks), +}; + +static const struct qcom_cc_desc gcc_shikra_desc = { + .config = &gcc_shikra_regmap_config, + .clks = gcc_shikra_clocks, + .num_clks = ARRAY_SIZE(gcc_shikra_clocks), + .resets = gcc_shikra_resets, + .num_resets = ARRAY_SIZE(gcc_shikra_resets), + .gdscs = gcc_shikra_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_shikra_gdscs), + .driver_data = &gcc_shikra_driver_data, +}; + +static const struct of_device_id gcc_shikra_match_table[] = { + { .compatible = "qcom,shikra-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_shikra_match_table); + +static int gcc_shikra_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_shikra_desc); +} + +static struct platform_driver gcc_shikra_driver = { + .probe = gcc_shikra_probe, + .driver = { + .name = "gcc-shikra", + .of_match_table = gcc_shikra_match_table, + }, +}; + +static int __init gcc_shikra_init(void) +{ + return platform_driver_register(&gcc_shikra_driver); +} +subsys_initcall(gcc_shikra_init); + +static void __exit gcc_shikra_exit(void) +{ + platform_driver_unregister(&gcc_shikra_driver); +} +module_exit(gcc_shikra_exit); + +MODULE_DESCRIPTION("QTI GCC SHIKRA Driver"); +MODULE_LICENSE("GPL"); From 301e1998a615bb8882d4b6fd7ad77e336c83cca1 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 13 Mar 2026 18:16:03 +0530 Subject: [PATCH 060/128] arm64: defconfig: Enable GCC on Shikra EVK boards Enable the GCC driver on the Qualcomm Shikra EVK boards. Signed-off-by: Imran Shaik --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index d905a0777f939..76088593c3cc6 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1458,6 +1458,7 @@ CONFIG_CLK_IMX8QXP=y CONFIG_CLK_IMX8ULP=y CONFIG_CLK_IMX93=y CONFIG_CLK_IMX95_BLK_CTL=y +CONFIG_CLK_SHIKRA_GCC=y CONFIG_TI_SCI_CLK=y CONFIG_COMMON_CLK_MT8192_AUDSYS=y CONFIG_COMMON_CLK_MT8192_CAMSYS=y From 9c70e79cb41d967fe5abf90900f1ce30627310ed Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Wed, 1 Apr 2026 19:22:14 +0530 Subject: [PATCH 061/128] dt-bindings: watchdog: qcom-wdt: Document Shikra watchdog Add devicetree binding for watchdog present on Qualcomm's Shikra SoC. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index 9f861045b71e8..69ab3bf5db903 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -40,6 +40,7 @@ properties: - qcom,apss-wdt-sdm845 - qcom,apss-wdt-sdx55 - qcom,apss-wdt-sdx65 + - qcom,apss-wdt-shikra - qcom,apss-wdt-sm6115 - qcom,apss-wdt-sm6350 - qcom,apss-wdt-sm8150 From dd2d77509d6a24f8e0bc94865395ec18fb927b02 Mon Sep 17 00:00:00 2001 From: Xueyao An Date: Thu, 26 Mar 2026 10:42:33 +0800 Subject: [PATCH 062/128] dt-bindings: dma: qcom,gpi: Document GPI DMA engine for Shikra SoC Document the GPI DMA engine on Shikra platform. Signed-off-by: Xueyao An Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/dma/qcom,gpi.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml index fde1df035ad12..9a376265d8718 100644 --- a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml +++ b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml @@ -35,6 +35,7 @@ properties: - qcom,sc7280-gpi-dma - qcom,sc8280xp-gpi-dma - qcom,sdx75-gpi-dma + - qcom,shikra-gpi-dma - qcom,sm6115-gpi-dma - qcom,sm6375-gpi-dma - qcom,sm8350-gpi-dma From 588a1808736f1402bde5c6e4c2402fbb19afcaaa Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sat, 21 Mar 2026 22:42:58 +0530 Subject: [PATCH 063/128] dt-bindings: phy: qcom,msm8998-qmp-usb3-phy: Add support for Shikra Update dt-bindings to add Shikra to QMP Phy list. Signed-off-by: Krishna Kurapati --- .../devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml index 1636285fbe535..8402fe4a96e03 100644 --- a/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,msm8998-qmp-usb3-phy.yaml @@ -20,6 +20,7 @@ properties: - qcom,qcm2290-qmp-usb3-phy - qcom,qcs615-qmp-usb3-phy - qcom,sdm660-qmp-usb3-phy + - qcom,shikra-qmp-usb3-phy - qcom,sm6115-qmp-usb3-phy reg: @@ -116,6 +117,7 @@ allOf: contains: enum: - qcom,qcm2290-qmp-usb3-phy + - qcom,shikra-qmp-usb3-phy - qcom,sm6115-qmp-usb3-phy then: properties: From 11e223ccc7532eeafd4f54ac90c347fb0acce67d Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sat, 21 Mar 2026 22:43:45 +0530 Subject: [PATCH 064/128] dt-bindings: phy: qcom,qusb2: Add bindings for Shikra Update dt-bindings to add Shikra to QUSB2 Phy list. Signed-off-by: Krishna Kurapati --- Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index 39851ba9de436..ddbddeec6fb16 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -28,6 +28,7 @@ properties: - qcom,qcm2290-qusb2-phy - qcom,qcs615-qusb2-phy - qcom,sdm660-qusb2-phy + - qcom,shikra-qusb2-phy - qcom,sm4250-qusb2-phy - qcom,sm6115-qusb2-phy - items: From d3a76a6773166a28221ab5083100796420bbacb0 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sat, 21 Mar 2026 22:45:05 +0530 Subject: [PATCH 065/128] dt-bindings: usb: qcom,snps-dwc3: Add Shikra compatible Introduce the compatible definition for Shikra QCOM SNPS DWC3. Signed-off-by: Krishna Kurapati --- Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml index 8201656b41ed7..d5368b423a9ac 100644 --- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml @@ -60,6 +60,7 @@ properties: - qcom,sdx55-dwc3 - qcom,sdx65-dwc3 - qcom,sdx75-dwc3 + - qcom,shikra-dwc3 - qcom,sm4250-dwc3 - qcom,sm6115-dwc3 - qcom,sm6125-dwc3 @@ -358,6 +359,7 @@ allOf: - qcom,sar2130p-dwc3 - qcom,sc8180x-dwc3 - qcom,sc8180x-dwc3-mp + - qcom,shikra-dwc3 - qcom,sm4250-dwc3 - qcom,sm6115-dwc3 - qcom,sm6125-dwc3 @@ -434,6 +436,7 @@ allOf: - qcom,ipq8074-dwc3 - qcom,msm8953-dwc3 - qcom,msm8998-dwc3 + - qcom,shikra-dwc3 then: properties: interrupts: From 11e34e80ea71a20af56566607ff1b9d288a429c5 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sat, 21 Mar 2026 22:47:32 +0530 Subject: [PATCH 066/128] phy: qcom-qusb2: Add support for Shikra Add init sequence and phy configuration for Shikra. Signed-off-by: Krishna Kurapati --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index eb93015be841f..8014141e92f2a 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -381,6 +381,19 @@ static const struct qusb2_phy_cfg sdm660_phy_cfg = { .autoresume_en = BIT(3), }; +static const struct qusb2_phy_cfg shikra_phy_cfg = { + .tbl = qcs615_init_tbl, + .tbl_num = ARRAY_SIZE(qcs615_init_tbl), + .regs = ipq6018_regs_layout, + + .has_pll_test = true, + .se_clk_scheme_default = true, + .disable_ctrl = (CLAMP_N_EN | FREEZIO_N | POWER_DOWN), + .mask_core_ready = PLL_LOCKED, + .autoresume_en = BIT(3), + .update_tune1_with_efuse = false, +}; + static const struct qusb2_phy_cfg sm6115_phy_cfg = { .tbl = sm6115_init_tbl, .tbl_num = ARRAY_SIZE(sm6115_init_tbl), @@ -958,6 +971,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { }, { .compatible = "qcom,sdm660-qusb2-phy", .data = &sdm660_phy_cfg, + }, { + .compatible = "qcom,shikra-qusb2-phy", + .data = &shikra_phy_cfg, }, { .compatible = "qcom,sm4250-qusb2-phy", .data = &sm6115_phy_cfg, From 36fde32c1b5570075ea9c26fb7e3a6c3c20e7d64 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sat, 21 Mar 2026 22:48:49 +0530 Subject: [PATCH 067/128] phy: qcom: qmp-usbc: Add qmp configuration for Shikra Provide PHY configuration for the USB QMP PHY for Shikra Platform. Signed-off-by: Krishna Kurapati --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index c342479a37980..400dcebf8222d 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -2019,6 +2019,9 @@ static const struct of_device_id qmp_usbc_of_match_table[] = { }, { .compatible = "qcom,sdm660-qmp-usb3-phy", .data = &sdm660_usb3phy_cfg, + }, { + .compatible = "qcom,shikra-qmp-usb3-phy", + .data = &qcs615_usb3phy_cfg, }, { .compatible = "qcom,sm6115-qmp-usb3-phy", .data = &qcm2290_usb3phy_cfg, From ada9ccf8cbe9c3b41564d60a7794ca389ba5eb30 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Wed, 1 Apr 2026 11:39:17 +0530 Subject: [PATCH 068/128] dt-bindings: interconnect: document the RPM Network-On-Chip interconnect in Shikra SoC Document the RPM Network-On-Chip Interconnect for the Qualcomm Shikra platform. Signed-off-by: Raviteja Laggyshetty --- .../bindings/interconnect/qcom,shikra.yaml | 165 ++++++++++++++++++ .../dt-bindings/interconnect/qcom,shikra.h | 121 +++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,shikra.yaml create mode 100644 include/dt-bindings/interconnect/qcom,shikra.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,shikra.yaml b/Documentation/devicetree/bindings/interconnect/qcom,shikra.yaml new file mode 100644 index 0000000000000..f48fd25d6a33f --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,shikra.yaml @@ -0,0 +1,165 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,shikra.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Shikra Network-On-Chip interconnect + +maintainers: + - Raviteja Laggyshetty + +description: | + The Qualcomm Shikra interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + compatible: + enum: + - qcom,shikra-config-noc + - qcom,shikra-mem-noc-core + - qcom,shikra-sys-noc + + reg: + maxItems: 1 + + clocks: + minItems: 1 + maxItems: 4 + + clock-names: + minItems: 1 + maxItems: 4 + +# Child node's properties +patternProperties: + '^interconnect-[a-z0-9]+$': + type: object + description: + The interconnect providers do not have a separate QoS register space, + but share parent's space. + + allOf: + - $ref: qcom,rpm-common.yaml# + + properties: + compatible: + enum: + - qcom,shikra-clk-virt + - qcom,shikra-mc-virt + - qcom,shikra-mmrt-virt + - qcom,shikra-mmnrt-virt + + required: + - compatible + + unevaluatedProperties: false + +required: + - compatible + - reg + +allOf: + - $ref: qcom,rpm-common.yaml# + - if: + properties: + compatible: + const: qcom,shikra-mem-noc-core + + then: + properties: + clocks: + items: + - description: GPU-NoC AXI clock + + clock-names: + items: + - const: gpu_axi + + - if: + properties: + compatible: + const: qcom,shikra-sys-noc + + then: + properties: + clocks: + items: + - description: EMAC0-NoC AXI clock. + - description: EMAC1-NoC AXI clock. + - description: USB2-NoC AXI clock. + - description: USB3-NoC AXI clock. + + clock-names: + items: + - const: emac0_axi + - const: emac1_axi + - const: usb2_axi + - const: usb3_axi + + - if: + properties: + compatible: + enum: + - qcom,sm6115-clk-virt + - qcom,sm6115-config-noc + - qcom,sm6115-mc-virt + - qcom,sm6115-mmrt-virt + - qcom,sm6115-mmnrt-virt + + then: + properties: + clocks: false + clock-names: false + +unevaluatedProperties: false + +examples: + - | + system_noc: interconnect@1880000 { + compatible = "qcom,shikra-sys-noc"; + reg = <0x01880000 0x6a080>; + #interconnect-cells = <2>; + clocks = <&gcc_emac0_axi_sys_noc_clk>, + <&gcc_emac1_axi_sys_noc_clk>, + <&gcc_sys_noc_usb2_prim_axi_clk>, + <&gcc_sys_noc_usb3_prim_axi_clk>; + clock-names = "emac0_axi", + "emac1_axi", + "usb2_axi", + "usb3_axi"; + + clk_virt: interconnect-clk { + compatible = "qcom,shikra-clk-virt"; + #interconnect-cells = <2>; + }; + + mc_virt: interconnect-mc { + compatible = "qcom,shikra-mc-virt"; + #interconnect-cells = <2>; + }; + + mmnrt_virt: interconnect-mmnrt { + compatible = "qcom,shikra-mmnrt-virt"; + #interconnect-cells = <2>; + }; + + mmrt_virt: interconnect-mmrt { + compatible = "qcom,shikra-mmrt-virt"; + #interconnect-cells = <2>; + }; + }; + + config_noc: interconnect@1900000 { + compatible = "qcom,shikra-config-noc"; + reg = <0x01900000 0x8080>; + #interconnect-cells = <2>; + }; + + mem_noc: interconnect@d00000 { + compatible = "qcom,shikra-mem-noc-core"; + reg = <0x00d00000 0x43080>; + #interconnect-cells = <2>; + clocks = <&gcc_ddrss_gpu_axi_clk>; + clock-names = "gpu_axi"; + }; diff --git a/include/dt-bindings/interconnect/qcom,shikra.h b/include/dt-bindings/interconnect/qcom,shikra.h new file mode 100644 index 0000000000000..a42ea22ee162c --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,shikra.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SHIKRA_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SHIKRA_H + +#define MASTER_QUP_CORE_0 0 +#define SLAVE_QUP_CORE_0 1 + +#define SNOC_CNOC_MAS 0 +#define MASTER_QDSS_DAP 1 +#define SLAVE_AHB2PHY_USB 2 +#define SLAVE_APSS_THROTTLE_CFG 3 +#define SLAVE_AUDIO 4 +#define SLAVE_BOOT_ROM 5 +#define SLAVE_CAMERA_NRT_THROTTLE_CFG 6 +#define SLAVE_CAMERA_CFG 7 +#define SLAVE_CDSP_THROTTLE_CFG 8 +#define SLAVE_CLK_CTL 9 +#define SLAVE_DSP_CFG 10 +#define SLAVE_RBCPR_CX_CFG 11 +#define SLAVE_RBCPR_MX_CFG 12 +#define SLAVE_CRYPTO_0_CFG 13 +#define SLAVE_DDR_SS_CFG 14 +#define SLAVE_DISPLAY_CFG 15 +#define SLAVE_EMAC0_CFG 16 +#define SLAVE_EMAC1_CFG 17 +#define SLAVE_GPU_CFG 18 +#define SLAVE_GPU_THROTTLE_CFG 19 +#define SLAVE_HWKM 20 +#define SLAVE_IMEM_CFG 21 +#define SLAVE_MAPSS 22 +#define SLAVE_MDSP_MPU_CFG 23 +#define SLAVE_MESSAGE_RAM 24 +#define SLAVE_MSS 25 +#define SLAVE_PCIE_CFG 26 +#define SLAVE_PDM 27 +#define SLAVE_PIMEM_CFG 28 +#define SLAVE_PKA_WRAPPER_CFG 29 +#define SLAVE_PMIC_ARB 30 +#define SLAVE_QDSS_CFG 31 +#define SLAVE_QM_CFG 32 +#define SLAVE_QM_MPU_CFG 33 +#define SLAVE_QPIC 34 +#define SLAVE_QUP_0 35 +#define SLAVE_RPM 36 +#define SLAVE_SDCC_1 37 +#define SLAVE_SDCC_2 38 +#define SLAVE_SECURITY 39 +#define SLAVE_SNOC_CFG 40 +#define SNOC_SF_THROTTLE_CFG 41 +#define SLAVE_TLMM 42 +#define SLAVE_TSCSS 43 +#define SLAVE_USB2 44 +#define SLAVE_USB3 45 +#define SLAVE_VENUS_CFG 46 +#define SLAVE_VENUS_THROTTLE_CFG 47 +#define SLAVE_VSENSE_CTRL_CFG 48 +#define SLAVE_SERVICE_CNOC 49 + +#define MASTER_LLCC 0 +#define SLAVE_EBI_CH0 1 + +#define MASTER_GRAPHICS_3D 0 +#define MASTER_MNOC_HF_MEM_NOC 1 +#define MASTER_ANOC_PCIE_MEM_NOC 2 +#define MASTER_SNOC_SF_MEM_NOC 3 +#define MASTER_AMPSS_M0 4 +#define MASTER_SYS_TCU 5 +#define SLAVE_LLCC 6 +#define SLAVE_MEMNOC_SNOC 7 +#define SLAVE_MEM_NOC_PCIE_SNOC 8 + +#define MASTER_CAMNOC_SF 0 +#define MASTER_VIDEO_P0 1 +#define MASTER_VIDEO_PROC 2 +#define SLAVE_MMNRT_VIRT 3 + +#define MASTER_CAMNOC_HF 0 +#define MASTER_MDP_PORT0 1 +#define MASTER_MMRT_VIRT 2 +#define SLAVE_MM_MEMNOC 3 + +#define MASTER_SNOC_CFG 0 +#define MASTER_TIC 1 +#define MASTER_ANOC_SNOC 2 +#define MASTER_MEMNOC_PCIE 3 +#define MASTER_MEMNOC_SNOC 4 +#define MASTER_PIMEM 5 +#define MASTER_PCIE2_0 6 +#define MASTER_QDSS_BAM 7 +#define MASTER_QPIC 8 +#define MASTER_QUP_0 9 +#define CNOC_SNOC_MAS 10 +#define MASTER_AUDIO 11 +#define MASTER_EMAC_0 12 +#define MASTER_EMAC_1 13 +#define MASTER_QDSS_ETR 14 +#define MASTER_SDCC_1 15 +#define MASTER_SDCC_2 16 +#define MASTER_USB2_0 17 +#define MASTER_USB3 18 +#define MASTER_CRYPTO_CORE0 19 +#define SLAVE_APPSS 20 +#define SLAVE_MCUSS 21 +#define SLAVE_WCSS 22 +#define SLAVE_MEMNOC_SF 23 +#define SNOC_CNOC_SLV 24 +#define SLAVE_BOOTIMEM 25 +#define SLAVE_OCIMEM 26 +#define SLAVE_PIMEM 27 +#define SLAVE_SERVICE_SNOC 28 +#define SLAVE_PCIE2_0 29 +#define SLAVE_QDSS_STM 30 +#define SLAVE_TCU 31 +#define SLAVE_PCIE_MEMNOC 32 +#define SLAVE_ANOC_SNOC 33 + +#endif From 0f43d105a7ebc48c42c80b49aee6e9b1dd3dc564 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Wed, 1 Apr 2026 11:44:52 +0530 Subject: [PATCH 069/128] interconnect: qcom: add Shikra interconnect provider driver Add driver for the Qualcomm interconnect buses found in Shikra based platforms. The topology consists of several NoCs that are controlled by a remote processor that collects the aggregated bandwidth for each master-slave pairs. Signed-off-by: Raviteja Laggyshetty --- drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/shikra.c | 1810 ++++++++++++++++++++++++++++ 3 files changed, 1821 insertions(+) create mode 100644 drivers/interconnect/qcom/shikra.c diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index 786b4eda44b4f..c7c7df2a6ddbb 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -283,6 +283,15 @@ config INTERCONNECT_QCOM_SDX75 This is a driver for the Qualcomm Network-on-Chip on sdx75-based platforms. +config INTERCONNECT_QCOM_SHIKRA + tristate "Qualcomm SHIKRA interconnect driver" + depends on INTERCONNECT_QCOM + depends on QCOM_SMD_RPM + select INTERCONNECT_QCOM_SMD_RPM + help + This is a driver for the Qualcomm Network-on-Chip on shikra-based + platforms. + config INTERCONNECT_QCOM_SM6115 tristate "Qualcomm SM6115 interconnect driver" depends on INTERCONNECT_QCOM diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index cdf2c6c9fbf32..7c1834d383d2f 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -35,6 +35,7 @@ qnoc-sdm845-objs := sdm845.o qnoc-sdx55-objs := sdx55.o qnoc-sdx65-objs := sdx65.o qnoc-sdx75-objs := sdx75.o +qnoc-shikra-objs := shikra.o qnoc-sm6115-objs := sm6115.o qnoc-sm6350-objs := sm6350.o qnoc-sm7150-objs := sm7150.o @@ -80,6 +81,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o obj-$(CONFIG_INTERCONNECT_QCOM_SDX55) += qnoc-sdx55.o obj-$(CONFIG_INTERCONNECT_QCOM_SDX65) += qnoc-sdx65.o obj-$(CONFIG_INTERCONNECT_QCOM_SDX75) += qnoc-sdx75.o +obj-$(CONFIG_INTERCONNECT_QCOM_SHIKRA) += qnoc-shikra.o obj-$(CONFIG_INTERCONNECT_QCOM_SM6115) += qnoc-sm6115.o obj-$(CONFIG_INTERCONNECT_QCOM_SM6350) += qnoc-sm6350.o obj-$(CONFIG_INTERCONNECT_QCOM_SM7150) += qnoc-sm7150.o diff --git a/drivers/interconnect/qcom/shikra.c b/drivers/interconnect/qcom/shikra.c new file mode 100644 index 0000000000000..30a9a5b10db86 --- /dev/null +++ b/drivers/interconnect/qcom/shikra.c @@ -0,0 +1,1810 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "icc-rpm.h" + +static const char * const sys_noc_intf_clocks[] = { + "emac0_axi", + "emac1_axi", + "usb2_axi", + "usb3_axi", +}; + +static const char * const memnoc_intf_clocks[] = { + "gpu_axi", +}; + +enum { + SHIKRA_MASTER_QUP_CORE_0 = 1, + SHIKRA_SNOC_CNOC_MAS, + SHIKRA_MASTER_QDSS_DAP, + SHIKRA_MASTER_LLCC, + SHIKRA_MASTER_GRAPHICS_3D, + SHIKRA_MASTER_MNOC_HF_MEM_NOC, + SHIKRA_MASTER_ANOC_PCIE_MEM_NOC, + SHIKRA_MASTER_SNOC_SF_MEM_NOC, + SHIKRA_MASTER_AMPSS_M0, + SHIKRA_MASTER_SYS_TCU, + SHIKRA_MASTER_CAMNOC_SF, + SHIKRA_MASTER_VIDEO_P0, + SHIKRA_MASTER_VIDEO_PROC, + SHIKRA_MASTER_CAMNOC_HF, + SHIKRA_MASTER_MDP_PORT0, + SHIKRA_MASTER_MMRT_VIRT, + SHIKRA_MASTER_SNOC_CFG, + SHIKRA_MASTER_TIC, + SHIKRA_MASTER_ANOC_SNOC, + SHIKRA_MASTER_MEMNOC_PCIE, + SHIKRA_MASTER_MEMNOC_SNOC, + SHIKRA_MASTER_PIMEM, + SHIKRA_MASTER_PCIE2_0, + SHIKRA_MASTER_QDSS_BAM, + SHIKRA_MASTER_QPIC, + SHIKRA_MASTER_QUP_0, + SHIKRA_CNOC_SNOC_MAS, + SHIKRA_MASTER_AUDIO, + SHIKRA_MASTER_EMAC_0, + SHIKRA_MASTER_EMAC_1, + SHIKRA_MASTER_QDSS_ETR, + SHIKRA_MASTER_SDCC_1, + SHIKRA_MASTER_SDCC_2, + SHIKRA_MASTER_USB2_0, + SHIKRA_MASTER_USB3, + SHIKRA_MASTER_CRYPTO_CORE0, + + SHIKRA_SLAVE_QUP_CORE_0, + SHIKRA_SLAVE_AHB2PHY_USB, + SHIKRA_SLAVE_APSS_THROTTLE_CFG, + SHIKRA_SLAVE_AUDIO, + SHIKRA_SLAVE_BOOT_ROM, + SHIKRA_SLAVE_CAMERA_NRT_THROTTLE_CFG, + SHIKRA_SLAVE_CAMERA_CFG, + SHIKRA_SLAVE_CDSP_THROTTLE_CFG, + SHIKRA_SLAVE_CLK_CTL, + SHIKRA_SLAVE_DSP_CFG, + SHIKRA_SLAVE_RBCPR_CX_CFG, + SHIKRA_SLAVE_RBCPR_MX_CFG, + SHIKRA_SLAVE_CRYPTO_0_CFG, + SHIKRA_SLAVE_DDR_SS_CFG, + SHIKRA_SLAVE_DISPLAY_CFG, + SHIKRA_SLAVE_EMAC0_CFG, + SHIKRA_SLAVE_EMAC1_CFG, + SHIKRA_SLAVE_GPU_CFG, + SHIKRA_SLAVE_GPU_THROTTLE_CFG, + SHIKRA_SLAVE_HWKM, + SHIKRA_SLAVE_IMEM_CFG, + SHIKRA_SLAVE_MAPSS, + SHIKRA_SLAVE_MDSP_MPU_CFG, + SHIKRA_SLAVE_MESSAGE_RAM, + SHIKRA_SLAVE_MSS, + SHIKRA_SLAVE_PCIE_CFG, + SHIKRA_SLAVE_PDM, + SHIKRA_SLAVE_PIMEM_CFG, + SHIKRA_SLAVE_PKA_WRAPPER_CFG, + SHIKRA_SLAVE_PMIC_ARB, + SHIKRA_SLAVE_QDSS_CFG, + SHIKRA_SLAVE_QM_CFG, + SHIKRA_SLAVE_QM_MPU_CFG, + SHIKRA_SLAVE_QPIC, + SHIKRA_SLAVE_QUP_0, + SHIKRA_SLAVE_RPM, + SHIKRA_SLAVE_SDCC_1, + SHIKRA_SLAVE_SDCC_2, + SHIKRA_SLAVE_SECURITY, + SHIKRA_SLAVE_SNOC_CFG, + SHIKRA_SNOC_SF_THROTTLE_CFG, + SHIKRA_SLAVE_TLMM, + SHIKRA_SLAVE_TSCSS, + SHIKRA_SLAVE_USB2, + SHIKRA_SLAVE_USB3, + SHIKRA_SLAVE_VENUS_CFG, + SHIKRA_SLAVE_VENUS_THROTTLE_CFG, + SHIKRA_SLAVE_VSENSE_CTRL_CFG, + SHIKRA_SLAVE_SERVICE_CNOC, + SHIKRA_SLAVE_EBI_CH0, + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, + SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, + SHIKRA_SLAVE_MMNRT_VIRT, + SHIKRA_SLAVE_MM_MEMNOC, + SHIKRA_SLAVE_APPSS, + SHIKRA_SLAVE_MCUSS, + SHIKRA_SLAVE_WCSS, + SHIKRA_SLAVE_MEMNOC_SF, + SHIKRA_SNOC_CNOC_SLV, + SHIKRA_SLAVE_BOOTIMEM, + SHIKRA_SLAVE_OCIMEM, + SHIKRA_SLAVE_PIMEM, + SHIKRA_SLAVE_SERVICE_SNOC, + SHIKRA_SLAVE_PCIE2_0, + SHIKRA_SLAVE_QDSS_STM, + SHIKRA_SLAVE_TCU, + SHIKRA_SLAVE_PCIE_MEMNOC, + SHIKRA_SLAVE_ANOC_SNOC, +}; + +/* Master nodes */ +static const u16 qup0_core_master_links[] = { + SHIKRA_SLAVE_QUP_CORE_0, +}; + +static struct qcom_icc_node qup0_core_master = { + .id = SHIKRA_MASTER_QUP_CORE_0, + .name = "qup0_core_master", + .buswidth = 4, + .mas_rpm_id = 170, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qup0_core_master_links), + .links = qup0_core_master_links, +}; + +static const u16 qnm_snoc_cnoc_links[] = { + SHIKRA_SLAVE_AHB2PHY_USB, + SHIKRA_SLAVE_APSS_THROTTLE_CFG, + SHIKRA_SLAVE_AUDIO, + SHIKRA_SLAVE_BOOT_ROM, + SHIKRA_SLAVE_CAMERA_NRT_THROTTLE_CFG, + SHIKRA_SLAVE_CAMERA_CFG, + SHIKRA_SLAVE_CDSP_THROTTLE_CFG, + SHIKRA_SLAVE_CLK_CTL, + SHIKRA_SLAVE_DSP_CFG, + SHIKRA_SLAVE_RBCPR_CX_CFG, + SHIKRA_SLAVE_RBCPR_MX_CFG, + SHIKRA_SLAVE_CRYPTO_0_CFG, + SHIKRA_SLAVE_DDR_SS_CFG, + SHIKRA_SLAVE_DISPLAY_CFG, + SHIKRA_SLAVE_EMAC0_CFG, + SHIKRA_SLAVE_EMAC1_CFG, + SHIKRA_SLAVE_GPU_CFG, + SHIKRA_SLAVE_GPU_THROTTLE_CFG, + SHIKRA_SLAVE_HWKM, + SHIKRA_SLAVE_IMEM_CFG, + SHIKRA_SLAVE_MAPSS, + SHIKRA_SLAVE_MDSP_MPU_CFG, + SHIKRA_SLAVE_MESSAGE_RAM, + SHIKRA_SLAVE_MSS, + SHIKRA_SLAVE_PCIE_CFG, + SHIKRA_SLAVE_PDM, + SHIKRA_SLAVE_PIMEM_CFG, + SHIKRA_SLAVE_PKA_WRAPPER_CFG, + SHIKRA_SLAVE_PMIC_ARB, + SHIKRA_SLAVE_QDSS_CFG, + SHIKRA_SLAVE_QM_CFG, + SHIKRA_SLAVE_QM_MPU_CFG, + SHIKRA_SLAVE_QPIC, + SHIKRA_SLAVE_QUP_0, + SHIKRA_SLAVE_RPM, + SHIKRA_SLAVE_SDCC_1, + SHIKRA_SLAVE_SDCC_2, + SHIKRA_SLAVE_SECURITY, + SHIKRA_SLAVE_SNOC_CFG, + SHIKRA_SNOC_SF_THROTTLE_CFG, + SHIKRA_SLAVE_TLMM, + SHIKRA_SLAVE_TSCSS, + SHIKRA_SLAVE_USB2, + SHIKRA_SLAVE_USB3, + SHIKRA_SLAVE_VENUS_CFG, + SHIKRA_SLAVE_VENUS_THROTTLE_CFG, + SHIKRA_SLAVE_VSENSE_CTRL_CFG, + SHIKRA_SLAVE_SERVICE_CNOC, +}; + +static struct qcom_icc_node qnm_snoc_cnoc = { + .id = SHIKRA_SNOC_CNOC_MAS, + .name = "qnm_snoc_cnoc", + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_snoc_cnoc_links), + .links = qnm_snoc_cnoc_links, +}; + +static const u16 xm_dap_links[] = { + SHIKRA_SLAVE_AHB2PHY_USB, + SHIKRA_SLAVE_APSS_THROTTLE_CFG, + SHIKRA_SLAVE_AUDIO, + SHIKRA_SLAVE_BOOT_ROM, + SHIKRA_SLAVE_CAMERA_NRT_THROTTLE_CFG, + SHIKRA_SLAVE_CAMERA_CFG, + SHIKRA_SLAVE_CDSP_THROTTLE_CFG, + SHIKRA_SLAVE_CLK_CTL, + SHIKRA_SLAVE_DSP_CFG, + SHIKRA_SLAVE_RBCPR_CX_CFG, + SHIKRA_SLAVE_RBCPR_MX_CFG, + SHIKRA_SLAVE_CRYPTO_0_CFG, + SHIKRA_SLAVE_DDR_SS_CFG, + SHIKRA_SLAVE_DISPLAY_CFG, + SHIKRA_SLAVE_EMAC0_CFG, + SHIKRA_SLAVE_EMAC1_CFG, + SHIKRA_SLAVE_GPU_CFG, + SHIKRA_SLAVE_GPU_THROTTLE_CFG, + SHIKRA_SLAVE_HWKM, + SHIKRA_SLAVE_IMEM_CFG, + SHIKRA_SLAVE_MAPSS, + SHIKRA_SLAVE_MDSP_MPU_CFG, + SHIKRA_SLAVE_MESSAGE_RAM, + SHIKRA_SLAVE_MSS, + SHIKRA_SLAVE_PCIE_CFG, + SHIKRA_SLAVE_PDM, + SHIKRA_SLAVE_PIMEM_CFG, + SHIKRA_SLAVE_PKA_WRAPPER_CFG, + SHIKRA_SLAVE_PMIC_ARB, + SHIKRA_SLAVE_QDSS_CFG, + SHIKRA_SLAVE_QM_CFG, + SHIKRA_SLAVE_QM_MPU_CFG, + SHIKRA_SLAVE_QPIC, + SHIKRA_SLAVE_QUP_0, + SHIKRA_SLAVE_RPM, + SHIKRA_SLAVE_SDCC_1, + SHIKRA_SLAVE_SDCC_2, + SHIKRA_SLAVE_SECURITY, + SHIKRA_SLAVE_SNOC_CFG, + SHIKRA_SNOC_SF_THROTTLE_CFG, + SHIKRA_SLAVE_TLMM, + SHIKRA_SLAVE_TSCSS, + SHIKRA_SLAVE_USB2, + SHIKRA_SLAVE_USB3, + SHIKRA_SLAVE_VENUS_CFG, + SHIKRA_SLAVE_VENUS_THROTTLE_CFG, + SHIKRA_SLAVE_VSENSE_CTRL_CFG, + SHIKRA_SLAVE_SERVICE_CNOC, +}; + +static struct qcom_icc_node xm_dap = { + .id = SHIKRA_MASTER_QDSS_DAP, + .name = "xm_dap", + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_dap_links), + .links = xm_dap_links, +}; + +static const u16 llcc_mc_links[] = { + SHIKRA_SLAVE_EBI_CH0, +}; + +static struct qcom_icc_node llcc_mc = { + .id = SHIKRA_MASTER_LLCC, + .name = "llcc_mc", + .buswidth = 4, + .channels = 2, + .mas_rpm_id = 190, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(llcc_mc_links), + .links = llcc_mc_links, +}; + +static const u16 qnm_gpu_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, + SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, +}; + +static struct qcom_icc_node qnm_gpu = { + .id = SHIKRA_MASTER_GRAPHICS_3D, + .name = "qnm_gpu", + .buswidth = 16, + .qos.ap_owned = true, + .qos.qos_port = 6, + .qos.urg_fwd_en = false, + .qos.areq_prio = 0, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_gpu_links), + .links = qnm_gpu_links, +}; + +static const u16 qnm_mnoc_hf_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, + SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, +}; + +static struct qcom_icc_node qnm_mnoc_hf = { + .id = SHIKRA_MASTER_MNOC_HF_MEM_NOC, + .name = "qnm_mnoc_hf", + .buswidth = 16, + .qos.ap_owned = true, + .qos.qos_port = 7, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_mnoc_hf_links), + .links = qnm_mnoc_hf_links, +}; + +static const u16 qnm_pcie_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, +}; + +static struct qcom_icc_node qnm_pcie = { + .id = SHIKRA_MASTER_ANOC_PCIE_MEM_NOC, + .name = "qnm_pcie", + .buswidth = 8, + .qos.qos_port = 4, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = 185, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_pcie_links), + .links = qnm_pcie_links, +}; + +static const u16 qnm_snoc_sf_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, + SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, +}; + +static struct qcom_icc_node qnm_snoc_sf = { + .id = SHIKRA_MASTER_SNOC_SF_MEM_NOC, + .name = "qnm_snoc_sf", + .buswidth = 16, + .qos.qos_port = 3, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = 76, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_snoc_sf_links), + .links = qnm_snoc_sf_links, +}; + +static const u16 xm_apps_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, + SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, +}; + +static struct qcom_icc_node xm_apps = { + .id = SHIKRA_MASTER_AMPSS_M0, + .name = "xm_apps", + .buswidth = 16, + .qos.qos_port = 5, + .qos.urg_fwd_en = false, + .qos.areq_prio = 0, + .mas_rpm_id = 0, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_apps_links), + .links = xm_apps_links, +}; + +static const u16 xm_tcu_links[] = { + SHIKRA_SLAVE_LLCC, + SHIKRA_SLAVE_MEMNOC_SNOC, +}; + +static struct qcom_icc_node xm_tcu = { + .id = SHIKRA_MASTER_SYS_TCU, + .name = "xm_tcu", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 2, + .qos.urg_fwd_en = false, + .qos.areq_prio = 6, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_tcu_links), + .links = xm_tcu_links, +}; + +static const u16 qnm_camera_nrt_links[] = { + SHIKRA_SLAVE_MMNRT_VIRT, +}; + +static struct qcom_icc_node qnm_camera_nrt = { + .id = SHIKRA_MASTER_CAMNOC_SF, + .name = "qnm_camera_nrt", + .buswidth = 32, + .qos.ap_owned = true, + .qos.qos_port = 3, + .qos.urg_fwd_en = false, + .qos.areq_prio = 3, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_camera_nrt_links), + .links = qnm_camera_nrt_links, +}; + +static const u16 qxm_venus0_links[] = { + SHIKRA_SLAVE_MMNRT_VIRT, +}; + +static struct qcom_icc_node qxm_venus0 = { + .id = SHIKRA_MASTER_VIDEO_P0, + .name = "qxm_venus0", + .buswidth = 16, + .qos.ap_owned = true, + .qos.qos_port = 8, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qxm_venus0_links), + .links = qxm_venus0_links, +}; + +static const u16 qxm_venus_cpu_links[] = { + SHIKRA_SLAVE_MMNRT_VIRT, +}; + +static struct qcom_icc_node qxm_venus_cpu = { + .id = SHIKRA_MASTER_VIDEO_PROC, + .name = "qxm_venus_cpu", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 12, + .qos.urg_fwd_en = false, + .qos.areq_prio = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qxm_venus_cpu_links), + .links = qxm_venus_cpu_links, +}; + +static const u16 qnm_camera_rt_links[] = { + SHIKRA_SLAVE_MM_MEMNOC, +}; + +static struct qcom_icc_node qnm_camera_rt = { + .id = SHIKRA_MASTER_CAMNOC_HF, + .name = "qnm_camera_rt", + .buswidth = 32, + .qos.ap_owned = true, + .qos.qos_port = 9, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_camera_rt_links), + .links = qnm_camera_rt_links, +}; + +static const u16 qxm_mdp0_links[] = { + SHIKRA_SLAVE_MM_MEMNOC, +}; + +static struct qcom_icc_node qxm_mdp0 = { + .id = SHIKRA_MASTER_MDP_PORT0, + .name = "qxm_mdp0", + .buswidth = 16, + .qos.ap_owned = true, + .qos.qos_port = 4, + .qos.urg_fwd_en = true, + .qos.areq_prio = 0, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qxm_mdp0_links), + .links = qxm_mdp0_links, +}; + +static const u16 mmrt_virt_master_links[] = { + SHIKRA_SLAVE_MM_MEMNOC, +}; + +static struct qcom_icc_node mmrt_virt_master = { + .id = SHIKRA_MASTER_MMRT_VIRT, + .name = "mmrt_virt_master", + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(mmrt_virt_master_links), + .links = mmrt_virt_master_links, +}; + +static const u16 qhm_snoc_cfg_links[] = { + SHIKRA_SLAVE_SERVICE_SNOC, +}; + +static struct qcom_icc_node qhm_snoc_cfg = { + .id = SHIKRA_MASTER_SNOC_CFG, + .name = "qhm_snoc_cfg", + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qhm_snoc_cfg_links), + .links = qhm_snoc_cfg_links, +}; + +static const u16 qhm_tic_links[] = { + SHIKRA_SLAVE_APPSS, + SHIKRA_SLAVE_MCUSS, + SHIKRA_SLAVE_WCSS, + SHIKRA_SLAVE_MEMNOC_SF, + SHIKRA_SNOC_CNOC_SLV, + SHIKRA_SLAVE_BOOTIMEM, + SHIKRA_SLAVE_OCIMEM, + SHIKRA_SLAVE_PIMEM, + SHIKRA_SLAVE_QDSS_STM, + SHIKRA_SLAVE_TCU, +}; + +static struct qcom_icc_node qhm_tic = { + .id = SHIKRA_MASTER_TIC, + .name = "qhm_tic", + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qhm_tic_links), + .links = qhm_tic_links, +}; + +static const u16 qnm_anoc_snoc_links[] = { + SHIKRA_SLAVE_MEMNOC_SF, +}; + +static struct qcom_icc_node qnm_anoc_snoc = { + .id = SHIKRA_MASTER_ANOC_SNOC, + .name = "qnm_anoc_snoc", + .buswidth = 16, + .mas_rpm_id = 110, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_anoc_snoc_links), + .links = qnm_anoc_snoc_links, +}; + +static const u16 qnm_memnoc_pcie_links[] = { + SHIKRA_SLAVE_PCIE2_0, +}; + +static struct qcom_icc_node qnm_memnoc_pcie = { + .id = SHIKRA_MASTER_MEMNOC_PCIE, + .name = "qnm_memnoc_pcie", + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_memnoc_pcie_links), + .links = qnm_memnoc_pcie_links, +}; + +static const u16 qnm_memnoc_snoc_links[] = { + SHIKRA_SLAVE_APPSS, + SHIKRA_SLAVE_MCUSS, + SHIKRA_SLAVE_WCSS, + SHIKRA_SNOC_CNOC_SLV, + SHIKRA_SLAVE_BOOTIMEM, + SHIKRA_SLAVE_OCIMEM, + SHIKRA_SLAVE_PIMEM, + SHIKRA_SLAVE_QDSS_STM, + SHIKRA_SLAVE_TCU, +}; + +static struct qcom_icc_node qnm_memnoc_snoc = { + .id = SHIKRA_MASTER_MEMNOC_SNOC, + .name = "qnm_memnoc_snoc", + .buswidth = 8, + .mas_rpm_id = 184, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_memnoc_snoc_links), + .links = qnm_memnoc_snoc_links, +}; + +static const u16 qxm_pimem_links[] = { + SHIKRA_SLAVE_MEMNOC_SF, + SHIKRA_SLAVE_OCIMEM, +}; + +static struct qcom_icc_node qxm_pimem = { + .id = SHIKRA_MASTER_PIMEM, + .name = "qxm_pimem", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 14, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qxm_pimem_links), + .links = qxm_pimem_links, +}; + +static const u16 xm_pcie2_0_links[] = { + SHIKRA_SLAVE_PCIE_MEMNOC, +}; + +static struct qcom_icc_node xm_pcie2_0 = { + .id = SHIKRA_MASTER_PCIE2_0, + .name = "xm_pcie2_0", + .buswidth = 8, + .qos.qos_port = 21, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = 186, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_pcie2_0_links), + .links = xm_pcie2_0_links, +}; + +static const u16 qhm_qdss_bam_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node qhm_qdss_bam = { + .id = SHIKRA_MASTER_QDSS_BAM, + .name = "qhm_qdss_bam", + .buswidth = 4, + .qos.ap_owned = true, + .qos.qos_port = 2, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qhm_qdss_bam_links), + .links = qhm_qdss_bam_links, +}; + +static const u16 qhm_qpic_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node qhm_qpic = { + .id = SHIKRA_MASTER_QPIC, + .name = "qhm_qpic", + .buswidth = 4, + .qos.ap_owned = true, + .qos.qos_port = 1, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qhm_qpic_links), + .links = qhm_qpic_links, +}; + +static const u16 qhm_qup0_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node qhm_qup0 = { + .id = SHIKRA_MASTER_QUP_0, + .name = "qhm_qup0", + .buswidth = 4, + .qos.qos_port = 0, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = 166, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qhm_qup0_links), + .links = qhm_qup0_links, +}; + +static const u16 qnm_cnoc_snoc_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node qnm_cnoc_snoc = { + .id = SHIKRA_CNOC_SNOC_MAS, + .name = "qnm_cnoc_snoc", + .buswidth = 4, + .qos.ap_owned = true, + .qos.qos_port = 7, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qnm_cnoc_snoc_links), + .links = qnm_cnoc_snoc_links, +}; + +static const u16 qxm_audio_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node qxm_audio = { + .id = SHIKRA_MASTER_AUDIO, + .name = "qxm_audio", + .buswidth = 8, + .qos.qos_port = 22, + .qos.urg_fwd_en = false, + .qos.areq_prio = 3, + .mas_rpm_id = 78, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(qxm_audio_links), + .links = qxm_audio_links, +}; + +static const u16 xm_emac_0_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_emac_0 = { + .id = SHIKRA_MASTER_EMAC_0, + .name = "xm_emac_0", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 19, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_emac_0_links), + .links = xm_emac_0_links, +}; + +static const u16 xm_emac_1_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_emac_1 = { + .id = SHIKRA_MASTER_EMAC_1, + .name = "xm_emac_1", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 20, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_emac_1_links), + .links = xm_emac_1_links, +}; + +static const u16 xm_qdss_etr_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_qdss_etr = { + .id = SHIKRA_MASTER_QDSS_ETR, + .name = "xm_qdss_etr", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 11, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_qdss_etr_links), + .links = xm_qdss_etr_links, +}; + +static const u16 xm_sdc1_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_sdc1 = { + .id = SHIKRA_MASTER_SDCC_1, + .name = "xm_sdc1", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 13, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_sdc1_links), + .links = xm_sdc1_links, +}; + +static const u16 xm_sdc2_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_sdc2 = { + .id = SHIKRA_MASTER_SDCC_2, + .name = "xm_sdc2", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 17, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_sdc2_links), + .links = xm_sdc2_links, +}; + +static const u16 xm_usb2_0_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_usb2_0 = { + .id = SHIKRA_MASTER_USB2_0, + .name = "xm_usb2_0", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 24, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_usb2_0_links), + .links = xm_usb2_0_links, +}; + +static const u16 xm_usb3_0_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node xm_usb3_0 = { + .id = SHIKRA_MASTER_USB3, + .name = "xm_usb3_0", + .buswidth = 8, + .qos.ap_owned = true, + .qos.qos_port = 18, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(xm_usb3_0_links), + .links = xm_usb3_0_links, +}; + +static const u16 crypto_c0_links[] = { + SHIKRA_SLAVE_ANOC_SNOC, +}; + +static struct qcom_icc_node crypto_c0 = { + .id = SHIKRA_MASTER_CRYPTO_CORE0, + .name = "crypto_c0", + .buswidth = 8, + .qos.qos_port = 16, + .qos.urg_fwd_en = false, + .qos.areq_prio = 2, + .mas_rpm_id = 23, + .slv_rpm_id = -1, + .num_links = ARRAY_SIZE(crypto_c0_links), + .links = crypto_c0_links, +}; + +/* Slave nodes */ +static struct qcom_icc_node qup0_core_slave = { + .id = SHIKRA_SLAVE_QUP_CORE_0, + .name = "qup0_core_slave", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = 264, +}; + +static struct qcom_icc_node qhs_ahb2phy_usb = { + .id = SHIKRA_SLAVE_AHB2PHY_USB, + .name = "qhs_ahb2phy_usb", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_apss_throttle_cfg = { + .id = SHIKRA_SLAVE_APSS_THROTTLE_CFG, + .name = "qhs_apss_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_audio = { + .id = SHIKRA_SLAVE_AUDIO, + .name = "qhs_audio", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_boot_rom = { + .id = SHIKRA_SLAVE_BOOT_ROM, + .name = "qhs_boot_rom", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_camera_nrt_throttle_cfg = { + .id = SHIKRA_SLAVE_CAMERA_NRT_THROTTLE_CFG, + .name = "qhs_camera_nrt_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_camera_ss_cfg = { + .id = SHIKRA_SLAVE_CAMERA_CFG, + .name = "qhs_camera_ss_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_cdsp_throttle_cfg = { + .id = SHIKRA_SLAVE_CDSP_THROTTLE_CFG, + .name = "qhs_cdsp_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_clk_ctl = { + .id = SHIKRA_SLAVE_CLK_CTL, + .name = "qhs_clk_ctl", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_compute_dsp_cfg = { + .id = SHIKRA_SLAVE_DSP_CFG, + .name = "qhs_compute_dsp_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_cpr_cx = { + .id = SHIKRA_SLAVE_RBCPR_CX_CFG, + .name = "qhs_cpr_cx", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_cpr_mx = { + .id = SHIKRA_SLAVE_RBCPR_MX_CFG, + .name = "qhs_cpr_mx", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_crypto0_cfg = { + .id = SHIKRA_SLAVE_CRYPTO_0_CFG, + .name = "qhs_crypto0_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_ddr_ss_cfg = { + .id = SHIKRA_SLAVE_DDR_SS_CFG, + .name = "qhs_ddr_ss_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_disp_ss_cfg = { + .id = SHIKRA_SLAVE_DISPLAY_CFG, + .name = "qhs_disp_ss_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_emac0_cfg = { + .id = SHIKRA_SLAVE_EMAC0_CFG, + .name = "qhs_emac0_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_emac1_cfg = { + .id = SHIKRA_SLAVE_EMAC1_CFG, + .name = "qhs_emac1_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_gpu_cfg = { + .id = SHIKRA_SLAVE_GPU_CFG, + .name = "qhs_gpu_cfg", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_gpu_throttle_cfg = { + .id = SHIKRA_SLAVE_GPU_THROTTLE_CFG, + .name = "qhs_gpu_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_hwkm = { + .id = SHIKRA_SLAVE_HWKM, + .name = "qhs_hwkm", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_imem_cfg = { + .id = SHIKRA_SLAVE_IMEM_CFG, + .name = "qhs_imem_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_mapss = { + .id = SHIKRA_SLAVE_MAPSS, + .name = "qhs_mapss", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_mdsp_mpu_cfg = { + .id = SHIKRA_SLAVE_MDSP_MPU_CFG, + .name = "qhs_mdsp_mpu_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_mesg_ram = { + .id = SHIKRA_SLAVE_MESSAGE_RAM, + .name = "qhs_mesg_ram", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_mss = { + .id = SHIKRA_SLAVE_MSS, + .name = "qhs_mss", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_pcie_cfg = { + .id = SHIKRA_SLAVE_PCIE_CFG, + .name = "qhs_pcie_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_pdm = { + .id = SHIKRA_SLAVE_PDM, + .name = "qhs_pdm", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_pimem_cfg = { + .id = SHIKRA_SLAVE_PIMEM_CFG, + .name = "qhs_pimem_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_pka_wrapper = { + .id = SHIKRA_SLAVE_PKA_WRAPPER_CFG, + .name = "qhs_pka_wrapper", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_pmic_arb = { + .id = SHIKRA_SLAVE_PMIC_ARB, + .name = "qhs_pmic_arb", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_qdss_cfg = { + .id = SHIKRA_SLAVE_QDSS_CFG, + .name = "qhs_qdss_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_qm_cfg = { + .id = SHIKRA_SLAVE_QM_CFG, + .name = "qhs_qm_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_qm_mpu_cfg = { + .id = SHIKRA_SLAVE_QM_MPU_CFG, + .name = "qhs_qm_mpu_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_qpic = { + .id = SHIKRA_SLAVE_QPIC, + .name = "qhs_qpic", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_qup0 = { + .id = SHIKRA_SLAVE_QUP_0, + .name = "qhs_qup0", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_rpm = { + .id = SHIKRA_SLAVE_RPM, + .name = "qhs_rpm", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_sdc1 = { + .id = SHIKRA_SLAVE_SDCC_1, + .name = "qhs_sdc1", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_sdc2 = { + .id = SHIKRA_SLAVE_SDCC_2, + .name = "qhs_sdc2", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_security = { + .id = SHIKRA_SLAVE_SECURITY, + .name = "qhs_security", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static const u16 qhs_snoc_cfg_links[] = { + SHIKRA_MASTER_SNOC_CFG, +}; + +static struct qcom_icc_node qhs_snoc_cfg = { + .id = SHIKRA_SLAVE_SNOC_CFG, + .name = "qhs_snoc_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = 1, + .links = qhs_snoc_cfg_links, +}; + +static struct qcom_icc_node qhs_snoc_sf_throttle_cfg = { + .id = SHIKRA_SNOC_SF_THROTTLE_CFG, + .name = "qhs_snoc_sf_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_tlmm = { + .id = SHIKRA_SLAVE_TLMM, + .name = "qhs_tlmm", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_tscss = { + .id = SHIKRA_SLAVE_TSCSS, + .name = "qhs_tscss", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_usb2 = { + .id = SHIKRA_SLAVE_USB2, + .name = "qhs_usb2", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_usb3 = { + .id = SHIKRA_SLAVE_USB3, + .name = "qhs_usb3", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_venus_cfg = { + .id = SHIKRA_SLAVE_VENUS_CFG, + .name = "qhs_venus_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_venus_throttle_cfg = { + .id = SHIKRA_SLAVE_VENUS_THROTTLE_CFG, + .name = "qhs_venus_throttle_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_vsense_ctrl_cfg = { + .id = SHIKRA_SLAVE_VSENSE_CTRL_CFG, + .name = "qhs_vsense_ctrl_cfg", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node srvc_cnoc = { + .id = SHIKRA_SLAVE_SERVICE_CNOC, + .name = "srvc_cnoc", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node ebi = { + .id = SHIKRA_SLAVE_EBI_CH0, + .name = "ebi", + .channels = 2, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = 0, +}; + +static const u16 qns_llcc_links[] = { + SHIKRA_MASTER_LLCC, +}; + +static struct qcom_icc_node qns_llcc = { + .id = SHIKRA_SLAVE_LLCC, + .name = "qns_llcc", + .channels = 2, + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = 312, + .num_links = 1, + .links = qns_llcc_links, +}; + +static const u16 qns_memnoc_snoc_links[] = { + SHIKRA_MASTER_MEMNOC_SNOC, +}; + +static struct qcom_icc_node qns_memnoc_snoc = { + .id = SHIKRA_SLAVE_MEMNOC_SNOC, + .name = "qns_memnoc_snoc", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = 314, + .num_links = 1, + .links = qns_memnoc_snoc_links, +}; + +static const u16 qns_pcie_links[] = { + SHIKRA_MASTER_MEMNOC_PCIE, +}; + +static struct qcom_icc_node qns_pcie = { + .id = SHIKRA_SLAVE_MEM_NOC_PCIE_SNOC, + .name = "qns_pcie", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = 1, + .links = qns_pcie_links, +}; + +static const u16 mmnrt_virt_slave_links[] = { + SHIKRA_MASTER_MMRT_VIRT, +}; + +static struct qcom_icc_node mmnrt_virt_slave = { + .id = SHIKRA_SLAVE_MMNRT_VIRT, + .name = "mmnrt_virt_slave", + .channels = 1, + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = 1, + .links = mmnrt_virt_slave_links, +}; + +static const u16 qns_mm_memnoc_links[] = { + SHIKRA_MASTER_MNOC_HF_MEM_NOC, +}; + +static struct qcom_icc_node qns_mm_memnoc = { + .id = SHIKRA_SLAVE_MM_MEMNOC, + .name = "qns_mm_memnoc", + .channels = 1, + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = -1, + .num_links = 1, + .links = qns_mm_memnoc_links, +}; + +static struct qcom_icc_node qhs_apss = { + .id = SHIKRA_SLAVE_APPSS, + .name = "qhs_apss", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qhs_mcuss = { + .id = SHIKRA_SLAVE_MCUSS, + .name = "qhs_mcuss", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = 319, +}; + +static struct qcom_icc_node qhs_wcss = { + .id = SHIKRA_SLAVE_WCSS, + .name = "qhs_wcss", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = 23, +}; + +static const u16 qns_memnoc_sf_links[] = { + SHIKRA_MASTER_SNOC_SF_MEM_NOC, +}; + +static struct qcom_icc_node qns_memnoc_sf = { + .id = SHIKRA_SLAVE_MEMNOC_SF, + .name = "qns_memnoc_sf", + .channels = 1, + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = 313, + .num_links = 1, + .links = qns_memnoc_sf_links, +}; + +static const u16 qns_snoc_cnoc_links[] = { + SHIKRA_SNOC_CNOC_MAS, +}; + +static struct qcom_icc_node qns_snoc_cnoc = { + .id = SHIKRA_SNOC_CNOC_SLV, + .name = "qns_snoc_cnoc", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = 25, + .num_links = 1, + .links = qns_snoc_cnoc_links, +}; + +static struct qcom_icc_node qxs_bootimem = { + .id = SHIKRA_SLAVE_BOOTIMEM, + .name = "qxs_bootimem", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node qxs_imem = { + .id = SHIKRA_SLAVE_OCIMEM, + .name = "qxs_imem", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = 26, +}; + +static struct qcom_icc_node qxs_pimem = { + .id = SHIKRA_SLAVE_PIMEM, + .name = "qxs_pimem", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node srvc_snoc = { + .id = SHIKRA_SLAVE_SERVICE_SNOC, + .name = "srvc_snoc", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node xs_pcie2_0 = { + .id = SHIKRA_SLAVE_PCIE2_0, + .name = "xs_pcie2_0", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static struct qcom_icc_node xs_qdss_stm = { + .id = SHIKRA_SLAVE_QDSS_STM, + .name = "xs_qdss_stm", + .channels = 1, + .buswidth = 4, + .mas_rpm_id = -1, + .slv_rpm_id = 30, +}; + +static struct qcom_icc_node xs_sys_tcu_cfg = { + .id = SHIKRA_SLAVE_TCU, + .name = "xs_sys_tcu_cfg", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = -1, +}; + +static const u16 qns_pcie_memnoc_links[] = { + SHIKRA_MASTER_ANOC_PCIE_MEM_NOC, +}; + +static struct qcom_icc_node qns_pcie_memnoc = { + .id = SHIKRA_SLAVE_PCIE_MEMNOC, + .name = "qns_pcie_memnoc", + .channels = 1, + .buswidth = 8, + .mas_rpm_id = -1, + .slv_rpm_id = 317, + .num_links = 1, + .links = qns_pcie_memnoc_links, +}; + +static const u16 qns_anoc_snoc_links[] = { + SHIKRA_MASTER_ANOC_SNOC, +}; + +static struct qcom_icc_node qns_anoc_snoc = { + .id = SHIKRA_SLAVE_ANOC_SNOC, + .name = "qns_anoc_snoc", + .channels = 1, + .buswidth = 16, + .mas_rpm_id = -1, + .slv_rpm_id = 141, + .num_links = 1, + .links = qns_anoc_snoc_links, +}; + +/* NoC descriptors */ +static struct qcom_icc_node * const shikra_clk_virt_nodes[] = { + [MASTER_QUP_CORE_0] = &qup0_core_master, + [SLAVE_QUP_CORE_0] = &qup0_core_slave, +}; + +static const struct qcom_icc_desc shikra_clk_virt = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_clk_virt_nodes, + .num_nodes = ARRAY_SIZE(shikra_clk_virt_nodes), + .bus_clk_desc = &qup_clk, + .keep_alive = true, +}; + +static struct qcom_icc_node * const shikra_config_noc_nodes[] = { + [SNOC_CNOC_MAS] = &qnm_snoc_cnoc, + [MASTER_QDSS_DAP] = &xm_dap, + [SLAVE_AHB2PHY_USB] = &qhs_ahb2phy_usb, + [SLAVE_APSS_THROTTLE_CFG] = &qhs_apss_throttle_cfg, + [SLAVE_AUDIO] = &qhs_audio, + [SLAVE_BOOT_ROM] = &qhs_boot_rom, + [SLAVE_CAMERA_NRT_THROTTLE_CFG] = &qhs_camera_nrt_throttle_cfg, + [SLAVE_CAMERA_CFG] = &qhs_camera_ss_cfg, + [SLAVE_CDSP_THROTTLE_CFG] = &qhs_cdsp_throttle_cfg, + [SLAVE_CLK_CTL] = &qhs_clk_ctl, + [SLAVE_DSP_CFG] = &qhs_compute_dsp_cfg, + [SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx, + [SLAVE_RBCPR_MX_CFG] = &qhs_cpr_mx, + [SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg, + [SLAVE_DDR_SS_CFG] = &qhs_ddr_ss_cfg, + [SLAVE_DISPLAY_CFG] = &qhs_disp_ss_cfg, + [SLAVE_EMAC0_CFG] = &qhs_emac0_cfg, + [SLAVE_EMAC1_CFG] = &qhs_emac1_cfg, + [SLAVE_GPU_CFG] = &qhs_gpu_cfg, + [SLAVE_GPU_THROTTLE_CFG] = &qhs_gpu_throttle_cfg, + [SLAVE_HWKM] = &qhs_hwkm, + [SLAVE_IMEM_CFG] = &qhs_imem_cfg, + [SLAVE_MAPSS] = &qhs_mapss, + [SLAVE_MDSP_MPU_CFG] = &qhs_mdsp_mpu_cfg, + [SLAVE_MESSAGE_RAM] = &qhs_mesg_ram, + [SLAVE_MSS] = &qhs_mss, + [SLAVE_PCIE_CFG] = &qhs_pcie_cfg, + [SLAVE_PDM] = &qhs_pdm, + [SLAVE_PIMEM_CFG] = &qhs_pimem_cfg, + [SLAVE_PKA_WRAPPER_CFG] = &qhs_pka_wrapper, + [SLAVE_PMIC_ARB] = &qhs_pmic_arb, + [SLAVE_QDSS_CFG] = &qhs_qdss_cfg, + [SLAVE_QM_CFG] = &qhs_qm_cfg, + [SLAVE_QM_MPU_CFG] = &qhs_qm_mpu_cfg, + [SLAVE_QPIC] = &qhs_qpic, + [SLAVE_QUP_0] = &qhs_qup0, + [SLAVE_RPM] = &qhs_rpm, + [SLAVE_SDCC_1] = &qhs_sdc1, + [SLAVE_SDCC_2] = &qhs_sdc2, + [SLAVE_SECURITY] = &qhs_security, + [SLAVE_SNOC_CFG] = &qhs_snoc_cfg, + [SNOC_SF_THROTTLE_CFG] = &qhs_snoc_sf_throttle_cfg, + [SLAVE_TLMM] = &qhs_tlmm, + [SLAVE_TSCSS] = &qhs_tscss, + [SLAVE_USB2] = &qhs_usb2, + [SLAVE_USB3] = &qhs_usb3, + [SLAVE_VENUS_CFG] = &qhs_venus_cfg, + [SLAVE_VENUS_THROTTLE_CFG] = &qhs_venus_throttle_cfg, + [SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg, + [SLAVE_SERVICE_CNOC] = &srvc_cnoc, +}; + +static const struct regmap_config shikra_config_noc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x8080, + .fast_io = true, +}; + +static const struct qcom_icc_desc shikra_config_noc = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_config_noc_nodes, + .num_nodes = ARRAY_SIZE(shikra_config_noc_nodes), + .bus_clk_desc = &bus_1_clk, + .keep_alive = true, +}; + +static struct qcom_icc_node * const shikra_mc_virt_nodes[] = { + [MASTER_LLCC] = &llcc_mc, + [SLAVE_EBI_CH0] = &ebi, +}; + +static const struct qcom_icc_desc shikra_mc_virt = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_mc_virt_nodes, + .num_nodes = ARRAY_SIZE(shikra_mc_virt_nodes), + .bus_clk_desc = &bimc_clk, + .keep_alive = true, + .ab_coeff = 152, +}; + +static struct qcom_icc_node * const shikra_mem_noc_core_nodes[] = { + [MASTER_GRAPHICS_3D] = &qnm_gpu, + [MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf, + [MASTER_ANOC_PCIE_MEM_NOC] = &qnm_pcie, + [MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf, + [MASTER_AMPSS_M0] = &xm_apps, + [MASTER_SYS_TCU] = &xm_tcu, + [SLAVE_LLCC] = &qns_llcc, + [SLAVE_MEMNOC_SNOC] = &qns_memnoc_snoc, + [SLAVE_MEM_NOC_PCIE_SNOC] = &qns_pcie, +}; + +static const struct regmap_config shikra_mem_noc_core_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x43080, + .fast_io = true, +}; + +static const struct qcom_icc_desc shikra_mem_noc_core = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_mem_noc_core_nodes, + .num_nodes = ARRAY_SIZE(shikra_mem_noc_core_nodes), + .bus_clk_desc = &mem_1_clk, + .regmap_cfg = &shikra_mem_noc_core_regmap_config, + .intf_clocks = memnoc_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(memnoc_intf_clocks), + .qos_offset = 0x28000, + .keep_alive = true, + .ab_coeff = 142, +}; + +static struct qcom_icc_node * const shikra_mmnrt_virt_nodes[] = { + [MASTER_CAMNOC_SF] = &qnm_camera_nrt, + [MASTER_VIDEO_P0] = &qxm_venus0, + [MASTER_VIDEO_PROC] = &qxm_venus_cpu, + [SLAVE_MMNRT_VIRT] = &mmnrt_virt_slave, +}; + +static const struct regmap_config shikra_sys_noc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x6a080, + .fast_io = true, +}; + +static const struct qcom_icc_desc shikra_mmnrt_virt = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_mmnrt_virt_nodes, + .num_nodes = ARRAY_SIZE(shikra_mmnrt_virt_nodes), + .bus_clk_desc = &mmaxi_0_clk, + .regmap_cfg = &shikra_sys_noc_regmap_config, + .qos_offset = 0x51000, + .keep_alive = true, + .ab_coeff = 142, +}; + +static struct qcom_icc_node * const shikra_mmrt_virt_nodes[] = { + [MASTER_CAMNOC_HF] = &qnm_camera_rt, + [MASTER_MDP_PORT0] = &qxm_mdp0, + [MASTER_MMRT_VIRT] = &mmrt_virt_master, + [SLAVE_MM_MEMNOC] = &qns_mm_memnoc, +}; + +static const struct qcom_icc_desc shikra_mmrt_virt = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_mmrt_virt_nodes, + .num_nodes = ARRAY_SIZE(shikra_mmrt_virt_nodes), + .bus_clk_desc = &mmaxi_1_clk, + .regmap_cfg = &shikra_sys_noc_regmap_config, + .qos_offset = 0x51000, + .keep_alive = true, + .ab_coeff = 142, +}; + +static struct qcom_icc_node * const shikra_sys_noc_nodes[] = { + [MASTER_SNOC_CFG] = &qhm_snoc_cfg, + [MASTER_TIC] = &qhm_tic, + [MASTER_ANOC_SNOC] = &qnm_anoc_snoc, + [MASTER_MEMNOC_PCIE] = &qnm_memnoc_pcie, + [MASTER_MEMNOC_SNOC] = &qnm_memnoc_snoc, + [MASTER_PIMEM] = &qxm_pimem, + [MASTER_PCIE2_0] = &xm_pcie2_0, + [MASTER_QDSS_BAM] = &qhm_qdss_bam, + [MASTER_QPIC] = &qhm_qpic, + [MASTER_QUP_0] = &qhm_qup0, + [CNOC_SNOC_MAS] = &qnm_cnoc_snoc, + [MASTER_AUDIO] = &qxm_audio, + [MASTER_EMAC_0] = &xm_emac_0, + [MASTER_EMAC_1] = &xm_emac_1, + [MASTER_QDSS_ETR] = &xm_qdss_etr, + [MASTER_SDCC_1] = &xm_sdc1, + [MASTER_SDCC_2] = &xm_sdc2, + [MASTER_USB2_0] = &xm_usb2_0, + [MASTER_USB3] = &xm_usb3_0, + [MASTER_CRYPTO_CORE0] = &crypto_c0, + [SLAVE_APPSS] = &qhs_apss, + [SLAVE_MCUSS] = &qhs_mcuss, + [SLAVE_WCSS] = &qhs_wcss, + [SLAVE_MEMNOC_SF] = &qns_memnoc_sf, + [SNOC_CNOC_SLV] = &qns_snoc_cnoc, + [SLAVE_BOOTIMEM] = &qxs_bootimem, + [SLAVE_OCIMEM] = &qxs_imem, + [SLAVE_PIMEM] = &qxs_pimem, + [SLAVE_SERVICE_SNOC] = &srvc_snoc, + [SLAVE_PCIE2_0] = &xs_pcie2_0, + [SLAVE_QDSS_STM] = &xs_qdss_stm, + [SLAVE_TCU] = &xs_sys_tcu_cfg, + [SLAVE_PCIE_MEMNOC] = &qns_pcie_memnoc, + [SLAVE_ANOC_SNOC] = &qns_anoc_snoc, +}; + +static const struct qcom_icc_desc shikra_sys_noc = { + .type = QCOM_ICC_QNOC, + .nodes = shikra_sys_noc_nodes, + .num_nodes = ARRAY_SIZE(shikra_sys_noc_nodes), + .bus_clk_desc = &bus_2_clk, + .regmap_cfg = &shikra_sys_noc_regmap_config, + .intf_clocks = sys_noc_intf_clocks, + .num_intf_clocks = ARRAY_SIZE(sys_noc_intf_clocks), + .qos_offset = 0x51000, + .keep_alive = true, +}; + +static const struct of_device_id shikra_qnoc_of_match[] = { + { .compatible = "qcom,shikra-clk-virt", + .data = &shikra_clk_virt }, + { .compatible = "qcom,shikra-config-noc", + .data = &shikra_config_noc }, + { .compatible = "qcom,shikra-mc-virt", + .data = &shikra_mc_virt }, + { .compatible = "qcom,shikra-mem-noc-core", + .data = &shikra_mem_noc_core }, + { .compatible = "qcom,shikra-mmnrt-virt", + .data = &shikra_mmnrt_virt }, + { .compatible = "qcom,shikra-mmrt-virt", + .data = &shikra_mmrt_virt }, + { .compatible = "qcom,shikra-sys-noc", + .data = &shikra_sys_noc }, + { }, +}; +MODULE_DEVICE_TABLE(of, shikra_qnoc_of_match); + +static struct platform_driver shikra_qnoc_driver = { + .probe = qnoc_probe, + .remove = qnoc_remove, + .driver = { + .name = "qnoc-shikra", + .of_match_table = shikra_qnoc_of_match, + .sync_state = icc_sync_state, + }, +}; + +static int __init qnoc_driver_init(void) +{ + return platform_driver_register(&shikra_qnoc_driver); +} +core_initcall(qnoc_driver_init); + +static void __exit qnoc_driver_exit(void) +{ + platform_driver_unregister(&shikra_qnoc_driver); +} +module_exit(qnoc_driver_exit); + +MODULE_DESCRIPTION("Qualcomm SHIKRA NoC driver"); +MODULE_LICENSE("GPL"); From f41ab11c727905ea92754495561f81bf98418ecf Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Wed, 1 Apr 2026 11:52:10 +0530 Subject: [PATCH 070/128] arm64: defconfig: Enable interconnect driver for Shikra Enable the shikra interconnect driver so that consumers are able to obtain their path handles properly. Signed-off-by: Raviteja Laggyshetty --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 76088593c3cc6..44fab7a63fe52 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1892,6 +1892,7 @@ CONFIG_INTERCONNECT_QCOM_SC8180X=y CONFIG_INTERCONNECT_QCOM_SC8280XP=y CONFIG_INTERCONNECT_QCOM_SDM845=y CONFIG_INTERCONNECT_QCOM_SDX75=y +CONFIG_INTERCONNECT_QCOM_SHIKRA=y CONFIG_INTERCONNECT_QCOM_SM6115=y CONFIG_INTERCONNECT_QCOM_SM6350=y CONFIG_INTERCONNECT_QCOM_MILOS=y From 65bc551344ba457e2da4b180c9f5258d9bae83d9 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 7 Apr 2026 11:00:02 +0530 Subject: [PATCH 071/128] dt-bindings: mfd: qcom,tcsr: Add compatible for Shikra Document the qcom,shikra-tcsr compatible. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml index 14ae3f00ef7e0..51d0dcab57064 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml @@ -33,6 +33,7 @@ properties: - qcom,sdx55-tcsr - qcom,sdx65-tcsr - qcom,sdx75-tcsr + - qcom,shikra-tcsr - qcom,sm4450-tcsr - qcom,sm6115-tcsr - qcom,sm8150-tcsr From 9976645c67ea70d3628d5b45c3c3482a20ced344 Mon Sep 17 00:00:00 2001 From: Monish Chunara Date: Tue, 7 Apr 2026 23:00:01 +0530 Subject: [PATCH 072/128] dt-bindings: mmc: sdhci-msm: Add compatible for shikra Document the qcom,shikra-sdhci compatible Signed-off-by: Monish Chunara --- Documentation/devicetree/bindings/mmc/sdhci-msm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml index 695a95e8f35d2..60dc6b0caa219 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml @@ -62,6 +62,7 @@ properties: - qcom,sdx55-sdhci - qcom,sdx65-sdhci - qcom,sdx75-sdhci + - qcom,shikra-sdhci - qcom,sm6115-sdhci - qcom,sm6125-sdhci - qcom,sm6350-sdhci From 54810373726d0c5386488ba0404a18d09d2f9dbc Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 10 Apr 2026 10:20:03 +0530 Subject: [PATCH 073/128] dt-bindings: cpufreq: qcom-hw: Document Shikra CPUFREQ Hardware The Qualcomm Shikra SoCs use RIMPS (RISC V based Integrated Manager for Power States) hardware for cpufreq scaling, which is functionally similar to EPSS, but supports only up to 12 frequency lookup table (LUT) entries. Signed-off-by: Imran Shaik --- .../devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml index 98eb36bff1727..fa54fb7ef5246 100644 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.yaml @@ -54,6 +54,12 @@ properties: - qcom,sm8650-cpufreq-epss - const: qcom,cpufreq-epss + - description: RIMPS CPUFREQ HW + items: + - enum: + - qcom,shikra-cpufreq-rimps + - const: qcom,cpufreq-rimps + reg: minItems: 1 items: @@ -144,6 +150,7 @@ allOf: - qcom,sc8280xp-cpufreq-epss - qcom,sdm670-cpufreq-hw - qcom,sdm845-cpufreq-hw + - qcom,shikra-cpufreq-rimps - qcom,sm4450-cpufreq-epss - qcom,sm6115-cpufreq-hw - qcom,sm6350-cpufreq-hw From a9eab59ec39a4f584ad8dcad96e312feb89c1fdc Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 23 Feb 2024 15:52:25 +0530 Subject: [PATCH 074/128] cpufreq: qcom-cpufreq-hw: Add RIMPS based cpufreq support for Shikra SoC The Qualcomm Shikra SoCs uses the RIMPS based hardware for cpufreq scaling. Introduce rimps_soc_data, which reuses the existing EPSS configurations, and accounts for the maximum LUT entries to 12 as per RIMPS hardware. Signed-off-by: Taniya Das --- drivers/cpufreq/qcom-cpufreq-hw.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index ea9a20d27b8fd..1fad60e3a627e 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -40,6 +41,7 @@ struct qcom_cpufreq_soc_data { u32 reg_intr_clr; u32 reg_current_vote; u32 reg_perf_state; + u32 lut_max_entries; u8 lut_row_size; }; @@ -156,7 +158,7 @@ static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy) soc_data = qcom_cpufreq.soc_data; index = readl_relaxed(data->base + soc_data->reg_perf_state); - index = min(index, LUT_MAX_ENTRIES - 1); + index = min(index, soc_data->lut_max_entries - 1); return policy->freq_table[index].frequency; } @@ -211,7 +213,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, struct qcom_cpufreq_data *drv_data = policy->driver_data; const struct qcom_cpufreq_soc_data *soc_data = qcom_cpufreq.soc_data; - table = kzalloc_objs(*table, LUT_MAX_ENTRIES + 1); + table = kzalloc_objs(*table, soc_data->lut_max_entries + 1); if (!table) return -ENOMEM; @@ -236,7 +238,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, icc_scaling_enabled = false; } - for (i = 0; i < LUT_MAX_ENTRIES; i++) { + for (i = 0; i < soc_data->lut_max_entries; i++) { data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut + i * soc_data->lut_row_size); src = FIELD_GET(LUT_SRC, data); @@ -405,6 +407,7 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = { .reg_current_vote = 0x704, .reg_perf_state = 0x920, .lut_row_size = 32, + .lut_max_entries = LUT_MAX_ENTRIES, }; static const struct qcom_cpufreq_soc_data epss_soc_data = { @@ -416,11 +419,25 @@ static const struct qcom_cpufreq_soc_data epss_soc_data = { .reg_intr_clr = 0x308, .reg_perf_state = 0x320, .lut_row_size = 4, + .lut_max_entries = LUT_MAX_ENTRIES, +}; + +static const struct qcom_cpufreq_soc_data rimps_soc_data = { + .reg_enable = 0x0, + .reg_domain_state = 0x20, + .reg_dcvs_ctrl = 0xb0, + .reg_freq_lut = 0x100, + .reg_volt_lut = 0x200, + .reg_intr_clr = 0x308, + .reg_perf_state = 0x320, + .lut_row_size = 4, + .lut_max_entries = 12, }; static const struct of_device_id qcom_cpufreq_hw_match[] = { { .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data }, { .compatible = "qcom,cpufreq-epss", .data = &epss_soc_data }, + { .compatible = "qcom,cpufreq-rimps", .data = &rimps_soc_data }, {} }; MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match); From 0b65824c15db43795a4e34647549f36af97560cf Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Tue, 14 Apr 2026 17:31:31 +0530 Subject: [PATCH 075/128] arm64: defconfig: Enable Pinctrl on Shikra EVK boards Enable the pinctrl driver on the Qualcomm Shikra EVK boards. Signed-off-by: Komal Bajaj --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 44fab7a63fe52..95494a99599d3 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -684,6 +684,7 @@ CONFIG_PINCTRL_SDM660=y CONFIG_PINCTRL_SDM670=y CONFIG_PINCTRL_SDM845=y CONFIG_PINCTRL_SDX75=y +CONFIG_PINCTRL_SHIKRA=y CONFIG_PINCTRL_SM4450=y CONFIG_PINCTRL_SM6115=y CONFIG_PINCTRL_SM6125=y From d8ececd04d1c05d9147cd90c1816412b741ff97b Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Thu, 9 Apr 2026 23:37:40 +0530 Subject: [PATCH 076/128] dt-bindings: thermal: qcom-tsens: Document the Shikra Temperature Sensor Document the Temperature Sensor (TSENS) on the Shikra SoC. Signed-off-by: Gaurav Kohli --- Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml index 7d34ba00e684f..a986fdccd52e8 100644 --- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml @@ -74,6 +74,7 @@ properties: - qcom,sdm630-tsens - qcom,sdm670-tsens - qcom,sdm845-tsens + - qcom,shikra-tsens - qcom,sm6115-tsens - qcom,sm6350-tsens - qcom,sm6375-tsens From 8ad47c91269fa92fc156a1e72b3946b3e1f26a0d Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 16 Apr 2026 16:22:49 +0530 Subject: [PATCH 077/128] dt-bindings: clock: qcom: Add Shikra Display clock controller Add device tree bindings for the Display clock controller on the Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- .../bindings/clock/qcom,shikra-dispcc.yaml | 62 +++++++++++++++++++ .../dt-bindings/clock/qcom,shikra-dispcc.h | 39 ++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,shikra-dispcc.yaml create mode 100644 include/dt-bindings/clock/qcom,shikra-dispcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-dispcc.yaml new file mode 100644 index 0000000000000..dbaecdd3e0b4b --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,shikra-dispcc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,shikra-dispcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Display Clock & Reset Controller for Qualcomm Shikra SoC + +maintainers: + - Imran Shaik + +description: | + Display clock control module provides the clocks, resets and power + domains on Qualcomm Shikra SoC platform. + + See also: + - include/dt-bindings/clock/qcom,shikra-dispcc.h + +properties: + compatible: + enum: + - qcom,shikra-dispcc + + clocks: + items: + - description: Board XO source + - description: Board sleep clock + - description: GPLL0 DISP DIV clock from GCC + - description: Byte clock from DSI PHY0 + - description: Pixel clock from DSI PHY0 + - description: Byte clock from DSI PHY1 + - description: Pixel clock from DSI PHY1 + +required: + - compatible + - clocks + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + clock-controller@5f00000 { + compatible = "qcom,shikra-dispcc"; + reg = <0x5f00000 0x20000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>, + <&dsi0_phy 0>, + <&dsi0_phy 1>, + <&dsi1_phy 0>, + <&dsi1_phy 1>; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,shikra-dispcc.h b/include/dt-bindings/clock/qcom,shikra-dispcc.h new file mode 100644 index 0000000000000..088a7c692ad5d --- /dev/null +++ b/include/dt-bindings/clock/qcom,shikra-dispcc.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SHIKRA_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SHIKRA_H + +/* DISP_CC clocks */ +#define DISP_CC_PLL0 0 +#define DISP_CC_MDSS_AHB_CLK 1 +#define DISP_CC_MDSS_AHB_CLK_SRC 2 +#define DISP_CC_MDSS_BYTE0_CLK 3 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 4 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 5 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 6 +#define DISP_CC_MDSS_ESC0_CLK 7 +#define DISP_CC_MDSS_ESC0_CLK_SRC 8 +#define DISP_CC_MDSS_MDP_CLK 9 +#define DISP_CC_MDSS_MDP_CLK_SRC 10 +#define DISP_CC_MDSS_MDP_LUT_CLK 11 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 12 +#define DISP_CC_MDSS_PCLK0_CLK 13 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 14 +#define DISP_CC_MDSS_VSYNC_CLK 15 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 16 +#define DISP_CC_SLEEP_CLK 17 +#define DISP_CC_SLEEP_CLK_SRC 18 +#define DISP_CC_XO_CLK 19 +#define DISP_CC_XO_CLK_SRC 20 + +/* DISP_CC power domains */ +#define DISP_CC_MDSS_CORE_GDSC 0 + +/* DISP_CC resets */ +#define DISP_CC_MDSS_CORE_BCR 0 +#define DISP_CC_MDSS_RSCC_BCR 1 + +#endif From 5f8274b1be316c4ce6598f5aeffc7b01cca87ef5 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 16 Apr 2026 12:04:44 +0530 Subject: [PATCH 078/128] dt-bindings: clock: qcom: Add Shikra GPU clock controller Add device tree bindings for the GPU clock controller on the Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- .../bindings/clock/qcom,sm6115-gpucc.yaml | 6 ++- include/dt-bindings/clock/qcom,shikra-gpucc.h | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,shikra-gpucc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6115-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6115-gpucc.yaml index 104ba10ca5737..1f6b5cec4642a 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm6115-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm6115-gpucc.yaml @@ -8,16 +8,20 @@ title: Qualcomm Graphics Clock & Reset Controller on SM6115 maintainers: - Konrad Dybcio + - Imran Shaik description: | Qualcomm graphics clock control module provides clocks, resets and power domains on Qualcomm SoCs. - See also: include/dt-bindings/clock/qcom,sm6115-gpucc.h + See also: + include/dt-bindings/clock/qcom,shikra-gpucc.h + include/dt-bindings/clock/qcom,sm6115-gpucc.h properties: compatible: enum: + - qcom,shikra-gpucc - qcom,sm6115-gpucc clocks: diff --git a/include/dt-bindings/clock/qcom,shikra-gpucc.h b/include/dt-bindings/clock/qcom,shikra-gpucc.h new file mode 100644 index 0000000000000..60714f6cc6cd2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,shikra-gpucc.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SHIKRA_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SHIKRA_H + +/* GPU_CC clocks */ +#define GPU_CC_PLL0 0 +#define GPU_CC_AHB_CLK 1 +#define GPU_CC_CRC_AHB_CLK 2 +#define GPU_CC_CX_GFX3D_CLK 3 +#define GPU_CC_CX_GFX3D_SLV_CLK 4 +#define GPU_CC_CX_GMU_CLK 5 +#define GPU_CC_CX_SNOC_DVM_CLK 6 +#define GPU_CC_CXO_AON_CLK 7 +#define GPU_CC_CXO_CLK 8 +#define GPU_CC_GMU_CLK_SRC 9 +#define GPU_CC_GPU_SMMU_VOTE_CLK 10 +#define GPU_CC_GX_CXO_CLK 11 +#define GPU_CC_GX_GFX3D_CLK 12 +#define GPU_CC_GX_GFX3D_CLK_SRC 13 +#define GPU_CC_SLEEP_CLK 14 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +/* GPU_CC resets */ +#define GPU_CC_CX_BCR 0 +#define GPU_CC_GFX3D_AON_BCR 1 +#define GPU_CC_GMU_BCR 2 +#define GPU_CC_GX_BCR 3 +#define GPU_CC_XO_BCR 4 + +#endif From cc03e796a7813d484d6c1032e0754c2215dcba12 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 16 Apr 2026 21:38:06 +0530 Subject: [PATCH 079/128] clk: qcom: Add support for Display Clock Controller on Shikra Add a driver for the Display clock controller on Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- drivers/clk/qcom/Kconfig | 10 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/dispcc-shikra.c | 565 +++++++++++++++++++++++++++++++ 3 files changed, 576 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-shikra.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a2c7751b091a4..80b0b72870680 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -155,6 +155,16 @@ config CLK_NORD_GCC SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination of GCC, SE_GCC, NE_GCC and NW_GCC. +config CLK_SHIKRA_DISPCC + tristate "Shikra Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_SHIKRA_GCC + help + Support for the display clock controller on Qualcomm Technologies, Inc + Shikra devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config CLK_SHIKRA_GCC tristate "Shikra Global Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 08a2cf68cb9cb..ec4e79614348a 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o +obj-$(CONFIG_CLK_SHIKRA_DISPCC) += dispcc-shikra.o obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o diff --git a/drivers/clk/qcom/dispcc-shikra.c b/drivers/clk/qcom/dispcc-shikra.c new file mode 100644 index 0000000000000..f4ae20f190465 --- /dev/null +++ b/drivers/clk/qcom/dispcc-shikra.c @@ -0,0 +1,565 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_GPLL0, + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, +}; + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_MAIN, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_DSICLK, + P_GPLL0_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco spark_vco[] = { + { 500000000, 1000000000, 2 }, +}; + +/* 768.0 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0x28, + .alpha = 0x0, + .alpha_en_mask = BIT(24), + .vco_val = BIT(21), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .config_ctl_val = 0x4001055b, + .test_ctl_hi1_val = 0x1, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .config = &disp_cc_pll0_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_GPLL0 }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .index = DT_GPLL0 }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x2154, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x20a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x20c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x2074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x205c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x208c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { + F(32764, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_sleep_clk_src = { + .cmd_rcgr = 0x6050, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_sleep_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_sleep_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_xo_clk_src = { + .cmd_rcgr = 0x6034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_xo_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x20bc, + .shift = 0, + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x2044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x2020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x2024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x2008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x2010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x2010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0x4004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x2018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x3000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_shikra_clocks[] = { + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, + [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, +}; + +static struct gdsc *disp_cc_shikra_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, +}; + +static const struct qcom_reset_map disp_cc_shikra_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x2000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0x4000 }, +}; + +static struct clk_alpha_pll *disp_cc_shikra_plls[] = { + &disp_cc_pll0, +}; + +static u32 disp_cc_shikra_critical_cbcrs[] = { + 0x6068, /* DISP_CC_SLEEP_CLK */ + 0x604c, /* DISP_CC_XO_CLK */ +}; + +static const struct regmap_config disp_cc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10000, + .fast_io = true, +}; + +static struct qcom_cc_driver_data disp_cc_shikra_driver_data = { + .alpha_plls = disp_cc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_shikra_plls), + .clk_cbcrs = disp_cc_shikra_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_shikra_critical_cbcrs), +}; + +static const struct qcom_cc_desc disp_cc_shikra_desc = { + .config = &disp_cc_shikra_regmap_config, + .clks = disp_cc_shikra_clocks, + .num_clks = ARRAY_SIZE(disp_cc_shikra_clocks), + .resets = disp_cc_shikra_resets, + .num_resets = ARRAY_SIZE(disp_cc_shikra_resets), + .gdscs = disp_cc_shikra_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_shikra_gdscs), + .driver_data = &disp_cc_shikra_driver_data, +}; + +static const struct of_device_id disp_cc_shikra_match_table[] = { + { .compatible = "qcom,shikra-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_shikra_match_table); + +static int disp_cc_shikra_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_shikra_desc); +} + +static struct platform_driver disp_cc_shikra_driver = { + .probe = disp_cc_shikra_probe, + .driver = { + .name = "dispcc-shikra", + .of_match_table = disp_cc_shikra_match_table, + }, +}; + +module_platform_driver(disp_cc_shikra_driver); + +MODULE_DESCRIPTION("QTI DISPCC Shikra Driver"); +MODULE_LICENSE("GPL"); From f977be22c5df7144de2aebf21071415e55f16bc4 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 16 Apr 2026 11:45:15 +0530 Subject: [PATCH 080/128] clk: qcom: Add support for GPU Clock Controller on Shikra Add a driver for the GPU clock controller on Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-shikra.c | 408 ++++++++++++++++++++++++++++++++ 3 files changed, 418 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-shikra.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 80b0b72870680..f665e5d542a6e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -174,6 +174,15 @@ config CLK_SHIKRA_GCC Say Y if you want to use multimedia devices or peripheral devices such as Camera, Video, UART, SPI, I2C, USB, SD/eMMC etc. +config CLK_SHIKRA_GPUCC + tristate "Shikra Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_SHIKRA_GCC + help + Support for the graphics clock controller on Shikra devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index ec4e79614348a..12eaa5b02e45c 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o obj-$(CONFIG_CLK_SHIKRA_DISPCC) += dispcc-shikra.o obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o +obj-$(CONFIG_CLK_SHIKRA_GPUCC) += gpucc-shikra.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o diff --git a/drivers/clk/qcom/gpucc-shikra.c b/drivers/clk/qcom/gpucc-shikra.c new file mode 100644 index 0000000000000..19a938a14d68d --- /dev/null +++ b/drivers/clk/qcom/gpucc-shikra.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_2X_DIV_CLK_SRC, + P_GPU_CC_PLL0_OUT_AUX, + P_GPU_CC_PLL0_OUT_AUX2, + P_GPU_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco huayra_vco[] = { + { 600000000, 3300000000, 0 }, + { 600000000, 2200000000, 1 }, +}; + +/* 710.4 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x25, + .cal_l = 0x4e, + .alpha = 0x0, + .config_ctl_val = 0x200d4828, + .config_ctl_hi_val = 0x6, + .config_ctl_hi1_val = 0x00000000, + .test_ctl_val = 0x1c000000, + .test_ctl_hi_val = 0x00004000, + .test_ctl_hi1_val = 0x00000000, + .user_ctl_val = 0xf, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = huayra_vco, + .num_vco = ARRAY_SIZE(huayra_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_huayra_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_2X_DIV_CLK_SRC, 1 }, + { P_GPU_CC_PLL0_OUT_AUX2, 2 }, + { P_GPU_CC_PLL0_OUT_AUX, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { + F(355200000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0), + F(537600000, P_GPU_CC_PLL0_OUT_AUX, 2, 0, 0), + F(672000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(844800000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(921600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1017600000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + F(1142400000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { + .cmd_rcgr = 0x101c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_gfx3d_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x107c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x107c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_crc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gfx3d_clk = { + .halt_reg = 0x10a4, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gfx3d_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = { + .halt_reg = 0x10a8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gfx3d_slv_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x1098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x108c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_snoc_dvm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x109c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x109c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gpu_smmu_vote_clk = { + .halt_reg = 0x5000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gfx3d_clk = { + .halt_reg = 0x1054, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_gfx3d_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x1090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x106c, + .gds_hw_ctrl = 0x1540, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gpu_cc_gx_gdsc = { + .gdscr = 0x100c, + .clamp_io_ctrl = 0x1508, + .resets = (unsigned int []){ GPU_CC_GX_BCR }, + .reset_count = 1, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gpu_cc_gx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | SW_RESET | CLAMP_IO | AON_RESET, +}; + +static struct clk_regmap *gpu_cc_shikra_clocks[] = { + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, + [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GPU_SMMU_VOTE_CLK] = &gpu_cc_gpu_smmu_vote_clk.clkr, + [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr, + [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, +}; + +static struct gdsc *gpu_cc_shikra_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, + [GPU_CC_GX_GDSC] = &gpu_cc_gx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_shikra_resets[] = { + [GPU_CC_CX_BCR] = { 0x1068 }, + [GPU_CC_GFX3D_AON_BCR] = { 0x10a0 }, + [GPU_CC_GMU_BCR] = { 0x111c }, + [GPU_CC_GX_BCR] = { 0x1008 }, + [GPU_CC_XO_BCR] = { 0x1000 }, +}; + +static struct clk_alpha_pll *gpu_cc_shikra_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_shikra_critical_cbcrs[] = { + 0x1078, /* GPU_CC_AHB_CLK */ + 0x1004, /* GPU_CC_CXO_AON_CLK */ + 0x1060, /* GPU_CC_GX_CXO_CLK */ +}; + +static const struct regmap_config gpu_cc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x7008, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gpu_cc_shikra_driver_data = { + .alpha_plls = gpu_cc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_shikra_plls), + .clk_cbcrs = gpu_cc_shikra_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_shikra_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_shikra_desc = { + .config = &gpu_cc_shikra_regmap_config, + .clks = gpu_cc_shikra_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_shikra_clocks), + .resets = gpu_cc_shikra_resets, + .num_resets = ARRAY_SIZE(gpu_cc_shikra_resets), + .gdscs = gpu_cc_shikra_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_shikra_gdscs), + .driver_data = &gpu_cc_shikra_driver_data, +}; + +static const struct of_device_id gpu_cc_shikra_match_table[] = { + { .compatible = "qcom,shikra-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_shikra_match_table); + +static int gpu_cc_shikra_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_shikra_desc); +} + +static struct platform_driver gpu_cc_shikra_driver = { + .probe = gpu_cc_shikra_probe, + .driver = { + .name = "gpucc-shikra", + .of_match_table = gpu_cc_shikra_match_table, + }, +}; + +module_platform_driver(gpu_cc_shikra_driver); + +MODULE_DESCRIPTION("QTI GPUCC Shikra Driver"); +MODULE_LICENSE("GPL"); From a8f9b0ac5e5adaefa3d2c11deed4d012acabb507 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 16 Apr 2026 13:31:00 +0530 Subject: [PATCH 081/128] arm64: defconfig: Enable DISPCC and GPUCC on Shikra EVK boards Enable the DISPCC and GPUCC drivers on the Qualcomm Shikra EVK boards. Signed-off-by: Imran Shaik --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 95494a99599d3..cf020d9139dcf 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1459,7 +1459,9 @@ CONFIG_CLK_IMX8QXP=y CONFIG_CLK_IMX8ULP=y CONFIG_CLK_IMX93=y CONFIG_CLK_IMX95_BLK_CTL=y +CONFIG_CLK_SHIKRA_DISPCC=y CONFIG_CLK_SHIKRA_GCC=y +CONFIG_CLK_SHIKRA_GPUCC=y CONFIG_TI_SCI_CLK=y CONFIG_COMMON_CLK_MT8192_AUDSYS=y CONFIG_COMMON_CLK_MT8192_CAMSYS=y From 049c32f28ba81d7545f2b873712e6cb0a82eaccf Mon Sep 17 00:00:00 2001 From: Sneh Mankad Date: Wed, 15 Apr 2026 14:48:27 +0530 Subject: [PATCH 082/128] pinctrl: qcom: Add GPIO-MPM map for shikra Map the wakeup capable GPIOs to respective MPM pins for shikra. Signed-off-by: Sneh Mankad --- drivers/pinctrl/qcom/pinctrl-shikra.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-shikra.c b/drivers/pinctrl/qcom/pinctrl-shikra.c index 1acd7a78ecba2..e021b07e83bd9 100644 --- a/drivers/pinctrl/qcom/pinctrl-shikra.c +++ b/drivers/pinctrl/qcom/pinctrl-shikra.c @@ -1216,6 +1216,21 @@ static const struct msm_pingroup shikra_groups[] = { [168] = SDC_QDSD_PINGROUP(sdc2_data, 0x1AA000, 9, 0), }; +static const struct msm_gpio_wakeirq_map shikra_mpm_map[] = { + {1, 9}, {2, 31}, {5, 49}, {6, 53}, {9, 72}, {10, 10}, + {12, 22}, {14, 26}, {17, 29}, {18, 24}, {20, 32}, {22, 33}, + {25, 34}, {27, 35}, {28, 36}, {29, 37}, {30, 38}, {31, 39}, + {32, 40}, {33, 41}, {38, 42}, {40, 43}, {43, 44}, {44, 45}, + {45, 46}, {46, 47}, {47, 48}, {48, 60}, {50, 50}, {51, 51}, + {52, 61}, {53, 62}, {57, 52}, {58, 63}, {60, 54}, {63, 64}, + {73, 55}, {74, 56}, {75, 57}, {77, 3}, {80, 4}, {84, 5}, + {85, 67}, {86, 69}, {88, 70}, {89, 71}, {90, 73}, {91, 74}, + {92, 75}, {93, 76}, {94, 77}, {95, 78}, {97, 79}, {99, 80}, + {100, 11}, {101, 13}, {102, 14}, {103, 15}, {106, 16}, {108, 17}, + {112, 18}, {116, 19}, {117, 20}, {119, 21}, {120, 23}, {136, 25}, + {159, 27}, {161, 28}, +}; + static const struct msm_pinctrl_soc_data shikra_tlmm = { .pins = shikra_pins, .npins = ARRAY_SIZE(shikra_pins), @@ -1224,6 +1239,8 @@ static const struct msm_pinctrl_soc_data shikra_tlmm = { .groups = shikra_groups, .ngroups = ARRAY_SIZE(shikra_groups), .ngpios = 166, + .wakeirq_map = shikra_mpm_map, + .nwakeirq_map = ARRAY_SIZE(shikra_mpm_map), .egpio_func = 11, }; From bfd73186712f4242c75676cf0ce3296786cf0e46 Mon Sep 17 00:00:00 2001 From: Raviteja Laggyshetty Date: Wed, 22 Apr 2026 16:34:16 +0530 Subject: [PATCH 083/128] interconnect: qcom: shikra: program QoS mode for ICC masters Set `qos_mode` on Shikra interconnect master nodes and mark ap-owned masters with `ap_owned` where missing. This enables correct QoS register programming (fixed or bypass mode) for the defined QoS ports. Signed-off-by: Raviteja Laggyshetty --- drivers/interconnect/qcom/shikra.c | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/interconnect/qcom/shikra.c b/drivers/interconnect/qcom/shikra.c index 30a9a5b10db86..5bf796100904f 100644 --- a/drivers/interconnect/qcom/shikra.c +++ b/drivers/interconnect/qcom/shikra.c @@ -300,6 +300,7 @@ static struct qcom_icc_node qnm_gpu = { .qos.ap_owned = true, .qos.qos_port = 6, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 0, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -320,6 +321,7 @@ static struct qcom_icc_node qnm_mnoc_hf = { .qos.ap_owned = true, .qos.qos_port = 7, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -336,8 +338,10 @@ static struct qcom_icc_node qnm_pcie = { .id = SHIKRA_MASTER_ANOC_PCIE_MEM_NOC, .name = "qnm_pcie", .buswidth = 8, + .qos.ap_owned = true, .qos.qos_port = 4, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = 185, .slv_rpm_id = -1, @@ -355,8 +359,10 @@ static struct qcom_icc_node qnm_snoc_sf = { .id = SHIKRA_MASTER_SNOC_SF_MEM_NOC, .name = "qnm_snoc_sf", .buswidth = 16, + .qos.ap_owned = true, .qos.qos_port = 3, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = 76, .slv_rpm_id = -1, @@ -374,8 +380,10 @@ static struct qcom_icc_node xm_apps = { .id = SHIKRA_MASTER_AMPSS_M0, .name = "xm_apps", .buswidth = 16, + .qos.ap_owned = true, .qos.qos_port = 5, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 0, .mas_rpm_id = 0, .slv_rpm_id = -1, @@ -395,6 +403,7 @@ static struct qcom_icc_node xm_tcu = { .qos.ap_owned = true, .qos.qos_port = 2, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 6, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -413,6 +422,7 @@ static struct qcom_icc_node qnm_camera_nrt = { .qos.ap_owned = true, .qos.qos_port = 3, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -431,6 +441,7 @@ static struct qcom_icc_node qxm_venus0 = { .qos.ap_owned = true, .qos.qos_port = 8, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -449,6 +460,7 @@ static struct qcom_icc_node qxm_venus_cpu = { .qos.ap_owned = true, .qos.qos_port = 12, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 4, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -467,6 +479,7 @@ static struct qcom_icc_node qnm_camera_rt = { .qos.ap_owned = true, .qos.qos_port = 9, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -485,6 +498,7 @@ static struct qcom_icc_node qxm_mdp0 = { .qos.ap_owned = true, .qos.qos_port = 4, .qos.urg_fwd_en = true, + .qos.qos_mode = NOC_QOS_MODE_BYPASS, .qos.areq_prio = 0, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -605,6 +619,7 @@ static struct qcom_icc_node qxm_pimem = { .qos.ap_owned = true, .qos.qos_port = 14, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -620,8 +635,10 @@ static struct qcom_icc_node xm_pcie2_0 = { .id = SHIKRA_MASTER_PCIE2_0, .name = "xm_pcie2_0", .buswidth = 8, + .qos.ap_owned = true, .qos.qos_port = 21, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 186, .slv_rpm_id = -1, @@ -640,6 +657,7 @@ static struct qcom_icc_node qhm_qdss_bam = { .qos.ap_owned = true, .qos.qos_port = 2, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -658,6 +676,7 @@ static struct qcom_icc_node qhm_qpic = { .qos.ap_owned = true, .qos.qos_port = 1, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -673,8 +692,10 @@ static struct qcom_icc_node qhm_qup0 = { .id = SHIKRA_MASTER_QUP_0, .name = "qhm_qup0", .buswidth = 4, + .qos.ap_owned = true, .qos.qos_port = 0, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 166, .slv_rpm_id = -1, @@ -693,6 +714,7 @@ static struct qcom_icc_node qnm_cnoc_snoc = { .qos.ap_owned = true, .qos.qos_port = 7, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -708,8 +730,10 @@ static struct qcom_icc_node qxm_audio = { .id = SHIKRA_MASTER_AUDIO, .name = "qxm_audio", .buswidth = 8, + .qos.ap_owned = true, .qos.qos_port = 22, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 3, .mas_rpm_id = 78, .slv_rpm_id = -1, @@ -728,6 +752,7 @@ static struct qcom_icc_node xm_emac_0 = { .qos.ap_owned = true, .qos.qos_port = 19, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -746,6 +771,7 @@ static struct qcom_icc_node xm_emac_1 = { .qos.ap_owned = true, .qos.qos_port = 20, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -764,6 +790,7 @@ static struct qcom_icc_node xm_qdss_etr = { .qos.ap_owned = true, .qos.qos_port = 11, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -782,6 +809,7 @@ static struct qcom_icc_node xm_sdc1 = { .qos.ap_owned = true, .qos.qos_port = 13, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -800,6 +828,7 @@ static struct qcom_icc_node xm_sdc2 = { .qos.ap_owned = true, .qos.qos_port = 17, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -818,6 +847,7 @@ static struct qcom_icc_node xm_usb2_0 = { .qos.ap_owned = true, .qos.qos_port = 24, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -836,6 +866,7 @@ static struct qcom_icc_node xm_usb3_0 = { .qos.ap_owned = true, .qos.qos_port = 18, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = -1, .slv_rpm_id = -1, @@ -851,8 +882,10 @@ static struct qcom_icc_node crypto_c0 = { .id = SHIKRA_MASTER_CRYPTO_CORE0, .name = "crypto_c0", .buswidth = 8, + .qos.ap_owned = true, .qos.qos_port = 16, .qos.urg_fwd_en = false, + .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.areq_prio = 2, .mas_rpm_id = 23, .slv_rpm_id = -1, From d9b91090fc568028ced20e33cb8d514882ffb91b Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Fri, 24 Apr 2026 16:18:11 +0530 Subject: [PATCH 084/128] dt-bindings: cache: qcom,llcc: Document Qualcomm Shikra LLCC Document the Last Level Cache Controller on Shikra SoC. Signed-off-by: Komal Bajaj --- Documentation/devicetree/bindings/cache/qcom,llcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml index 995d578157810..730556184a591 100644 --- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml +++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml @@ -35,6 +35,7 @@ properties: - qcom,sc8280xp-llcc - qcom,sdm670-llcc - qcom,sdm845-llcc + - qcom,shikra-llcc - qcom,sm6350-llcc - qcom,sm7150-llcc - qcom,sm8150-llcc @@ -206,6 +207,7 @@ allOf: enum: - qcom,sc7280-llcc - qcom,sdm670-llcc + - qcom,shikra-llcc then: properties: reg: From 373936195553e4a9262982bf6a70346ea3407d35 Mon Sep 17 00:00:00 2001 From: Tony Truong Date: Thu, 23 Apr 2026 16:25:41 +0530 Subject: [PATCH 085/128] FROMLIST: soc: qcom: smem: Switch partitions to xarray The partitions array is currently statically sized and uses the remote host ID as an index. Future protocol improvements to allow for more than two hosts in a partition will require hostIDs to be bitwise significant integers. This will result in large, sparse host IDs that generally exceed the current static limit. Switch to using xarray to efficiently handle these sparse indices and allow for dynamic growth. Signed-off-by: Tony Truong Tested-by: Shawn Guo # On Nord Tested-by: Konrad Dybcio # Glymur CRD Reviewed-by: Konrad Dybcio Signed-off-by: Pranav Mahesh Phansalkar Link: https://lore.kernel.org/r/20260423-smem-v3-1-582befff289a@oss.qualcomm.com --- drivers/soc/qcom/smem.c | 56 ++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index d5c94b47f431f..afb21a778fe7b 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -85,9 +85,6 @@ /* Processor/host identifier for the global partition */ #define SMEM_GLOBAL_HOST 0xfffe -/* Max number of processors/hosts in a system */ -#define SMEM_HOST_COUNT 25 - /** * struct smem_proc_comm - proc_comm communication struct (legacy) * @command: current command to be executed @@ -282,7 +279,7 @@ struct qcom_smem { struct platform_device *socinfo; struct smem_ptable *ptable; struct smem_partition global_partition; - struct smem_partition partitions[SMEM_HOST_COUNT]; + struct xarray partitions; unsigned num_regions; struct smem_region regions[] __counted_by(num_regions); @@ -382,7 +379,7 @@ static struct qcom_smem *__smem = INIT_ERR_PTR(-EPROBE_DEFER); int qcom_smem_bust_hwspin_lock_by_host(unsigned int host) { /* This function is for remote procs, so ignore SMEM_HOST_APPS */ - if (host == SMEM_HOST_APPS || host >= SMEM_HOST_COUNT) + if (host == SMEM_HOST_APPS || !xa_load(&__smem->partitions, host)) return -EINVAL; return hwspin_lock_bust(__smem->hwlock, SMEM_HOST_ID_TO_HWSPINLOCK_ID(host)); @@ -530,8 +527,8 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size) if (ret) return ret; - if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) { - part = &__smem->partitions[host]; + part = xa_load(&__smem->partitions, host); + if (part) { ret = qcom_smem_alloc_private(__smem, part, item, size); } else if (__smem->global_partition.virt_base) { part = &__smem->global_partition; @@ -697,8 +694,8 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size) if (item >= __smem->item_count) return ERR_PTR(-EINVAL); - if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) { - part = &__smem->partitions[host]; + part = xa_load(&__smem->partitions, host); + if (part) { ptr = qcom_smem_get_private(__smem, part, item, size); } else if (__smem->global_partition.virt_base) { part = &__smem->global_partition; @@ -730,8 +727,8 @@ int qcom_smem_get_free_space(unsigned host) if (IS_ERR(__smem)) return PTR_ERR(__smem); - if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) { - part = &__smem->partitions[host]; + part = xa_load(&__smem->partitions, host); + if (part) { phdr = part->virt_base; ret = le32_to_cpu(phdr->offset_free_cached) - le32_to_cpu(phdr->offset_free_uncached); @@ -774,12 +771,11 @@ phys_addr_t qcom_smem_virt_to_phys(void *p) { struct smem_partition *part; struct smem_region *area; + unsigned long index; u64 offset; u32 i; - for (i = 0; i < SMEM_HOST_COUNT; i++) { - part = &__smem->partitions[i]; - + xa_for_each(&__smem->partitions, index, part) { if (addr_in_range(part->virt_base, part->size, p)) { offset = p - part->virt_base; @@ -1016,16 +1012,20 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) { struct smem_partition_header *header; + struct smem_partition *part; struct smem_ptable_entry *entry; struct smem_ptable *ptable; u16 remote_host; u16 host0, host1; + int ret; int i; ptable = qcom_smem_get_ptable(smem); if (IS_ERR(ptable)) return PTR_ERR(ptable); + xa_init(&smem->partitions); + for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) { entry = &ptable->entry[i]; if (!le32_to_cpu(entry->offset)) @@ -1042,12 +1042,7 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) else continue; - if (remote_host >= SMEM_HOST_COUNT) { - dev_err(smem->dev, "bad host %u\n", remote_host); - return -EINVAL; - } - - if (smem->partitions[remote_host].virt_base) { + if (xa_load(&smem->partitions, remote_host)) { dev_err(smem->dev, "duplicate host %u\n", remote_host); return -EINVAL; } @@ -1056,11 +1051,20 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) if (!header) return -EINVAL; - smem->partitions[remote_host].virt_base = (void __iomem *)header; - smem->partitions[remote_host].phys_base = smem->regions[0].aux_base + - le32_to_cpu(entry->offset); - smem->partitions[remote_host].size = le32_to_cpu(entry->size); - smem->partitions[remote_host].cacheline = le32_to_cpu(entry->cacheline); + part = devm_kzalloc(smem->dev, sizeof(struct smem_partition), GFP_KERNEL); + if (!part) + return -ENOMEM; + + part->virt_base = (void __iomem *)header; + part->phys_base = smem->regions[0].aux_base + le32_to_cpu(entry->offset); + part->size = le32_to_cpu(entry->size); + part->cacheline = le32_to_cpu(entry->cacheline); + + ret = xa_insert(&smem->partitions, remote_host, part, GFP_KERNEL); + if (ret) { + dev_err(smem->dev, "fail to insert host %u\n", remote_host); + return ret; + } } return 0; @@ -1229,7 +1233,6 @@ static int qcom_smem_probe(struct platform_device *pdev) return -EINVAL; } - BUILD_BUG_ON(SMEM_HOST_APPS >= SMEM_HOST_COUNT); ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS); if (ret < 0 && ret != -ENOENT) return ret; @@ -1249,6 +1252,7 @@ static void qcom_smem_remove(struct platform_device *pdev) { platform_device_unregister(__smem->socinfo); + xa_destroy(&__smem->partitions); /* Set to -EPROBE_DEFER to signal unprobed state */ __smem = ERR_PTR(-EPROBE_DEFER); } From cbc9c348528193cd2c445e75ed2429d83c50e7b5 Mon Sep 17 00:00:00 2001 From: Sneh Mankad Date: Thu, 30 Apr 2026 14:50:07 +0530 Subject: [PATCH 086/128] FROMLIST: pinctrl: qcom: Unconditionally mark gpio as wakeup enable The wakeup enable bit needs to be set irrespective of the SoC using PDC or MPM as wakeup capable irqchip to allow the GPIO interrupts to be forwarded to parent irqchip. This is set only for PDC irqchip using additional check skip_wake_irqs making it impossible for MPM irqchip to detect the GPIO interrupt during SoC low power mode since for MPM irqchip the skip_wake_irqs is always false. Remove skip_wake_irqs condition when setting wakeup enable bit to allow forwarding GPIO interrupts for SoCs using MPM irqchip too. Fixes: 76b446f5b86e ("pinctrl: qcom: handle intr_target_reg wakeup_present/enable bits") Signed-off-by: Sneh Mankad Reviewed-by: Maulik Shah Link: https://lore.kernel.org/r/20260430-enable_wakeup_capable_gpios-v2-1-8c26ac795318@oss.qualcomm.com --- drivers/pinctrl/qcom/pinctrl-msm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 45b3a2763eb85..6a24f9b5e4a97 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -1242,12 +1242,12 @@ static int msm_gpio_irq_reqres(struct irq_data *d) /* * If the wakeup_enable bit is present and marked as available for the * requested GPIO, it should be enabled when the GPIO is marked as - * wake irq in order to allow the interrupt event to be transfered to - * the PDC HW. + * wake irq in order to allow the interrupt event to be transferred to + * the PDC/MPM HW. * While the name implies only the wakeup event, it's also required for * the interrupt event. */ - if (test_bit(d->hwirq, pctrl->skip_wake_irqs) && g->intr_wakeup_present_bit) { + if (g->intr_wakeup_present_bit) { u32 intr_cfg; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -1275,7 +1275,7 @@ static void msm_gpio_irq_relres(struct irq_data *d) unsigned long flags; /* Disable the wakeup_enable bit if it has been set in msm_gpio_irq_reqres() */ - if (test_bit(d->hwirq, pctrl->skip_wake_irqs) && g->intr_wakeup_present_bit) { + if (g->intr_wakeup_present_bit) { u32 intr_cfg; raw_spin_lock_irqsave(&pctrl->lock, flags); From 310e46fea2aacf0508e0458d0c6b96d8a35fa1f1 Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Tue, 21 Apr 2026 02:07:25 +0530 Subject: [PATCH 087/128] remoteproc: qcom: pas: Add Shikra remoteproc support Add DSP and lpaicp Peripheral Authentication Service support for the Shikra platform. Signed-off-by: Bibek Kumar Patro --- drivers/remoteproc/qcom_q6v5_pas.c | 191 ++++++++++++++++++----------- 1 file changed, 121 insertions(+), 70 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index da27d1d3c9da6..c12f4dd086621 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1457,6 +1457,55 @@ static const struct qcom_pas_data sc7280_wpss_resource = { .ssctl_id = 0x19, }; +static const struct qcom_pas_data shikra_cdsp_resource = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mbn", + .pas_id = 18, + .minidump_id = 7, + .auto_boot = false, + .proxy_pd_names = (char *[]){ + "cx", + NULL + }, + .load_state = "cdsp", + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, + .smem_host_id = 5, + .region_assign_vmid = QCOM_SCM_VMID_CDSP, +}; + +static const struct qcom_pas_data shikra_lpaicp_resource = { + .crash_reason_smem = 682, + .firmware_name = "lpaicp.mbn", + .dtb_firmware_name = "lpaicp_dtb.mbn", + .pas_id = 0x56, + .dtb_pas_id = 0x57, + /* placeholder for lpaicp subsystem dump collection id to be added */ + .minidump_id = 0, + .auto_boot = true, + .ssr_name = "lpaicp", + .sysmon_name = "lpaicp", +}; + +static const struct qcom_pas_data shikra_mpss_resource = { + .crash_reason_smem = 421, + .firmware_name = "qdsp6sw.mbn", + .pas_id = 4, + .minidump_id = 3, + .auto_boot = false, + .decrypt_shutdown = true, + .proxy_pd_names = (char *[]){ + "cx", + NULL + }, + .load_state = "modem", + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, +}; + static const struct qcom_pas_data sm8650_cdsp_resource = { .crash_reason_smem = 601, .firmware_name = "cdsp.mdt", @@ -1531,79 +1580,81 @@ static const struct qcom_pas_data sm8750_mpss_resource = { }; static const struct of_device_id qcom_pas_of_match[] = { - { .compatible = "qcom,eliza-adsp-pas", .data = &sm8550_adsp_resource }, - { .compatible = "qcom,milos-adsp-pas", .data = &sm8550_adsp_resource }, - { .compatible = "qcom,milos-cdsp-pas", .data = &milos_cdsp_resource }, - { .compatible = "qcom,milos-mpss-pas", .data = &sm8450_mpss_resource }, - { .compatible = "qcom,milos-wpss-pas", .data = &sc7280_wpss_resource }, - { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource }, - { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource }, - { .compatible = "qcom,msm8974-adsp-pil", .data = &msm8996_adsp_resource }, - { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource }, - { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init }, - { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource }, - { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init }, + { .compatible = "qcom,milos-adsp-pas", .data = &sm8550_adsp_resource}, + { .compatible = "qcom,milos-cdsp-pas", .data = &milos_cdsp_resource}, + { .compatible = "qcom,milos-mpss-pas", .data = &sm8450_mpss_resource}, + { .compatible = "qcom,milos-wpss-pas", .data = &sc7280_wpss_resource}, + { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource}, + { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, + { .compatible = "qcom,msm8974-adsp-pil", .data = &msm8996_adsp_resource}, + { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource}, + { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init}, + { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource}, + { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init}, { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, - { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource }, - { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource }, - { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource }, - { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource }, - { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource }, - { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource }, - { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource }, - { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init }, - { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource }, - { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource }, - { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init }, - { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource }, - { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource }, - { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource }, - { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource }, - { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource }, - { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource }, - { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource }, - { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init }, - { .compatible = "qcom,sdm660-cdsp-pas", .data = &cdsp_resource_init }, - { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init }, - { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init }, - { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init }, - { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource }, - { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource }, - { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init }, - { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init }, - { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource }, - { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource }, - { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource }, - { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init }, - { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource }, - { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource }, - { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource }, - { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource }, - { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource }, - { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init }, - { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init }, - { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource }, - { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource }, - { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init }, - { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource }, - { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource }, - { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init }, - { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init }, - { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource }, - { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource }, - { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init }, - { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource }, - { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource }, - { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource }, - { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource }, - { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource }, - { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource }, - { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource }, - { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource }, - { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource }, - { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource }, + { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource}, + { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource}, + { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, + { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, + { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, + { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource}, + { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource}, + { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource}, + { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource}, + { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, + { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, + { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, + { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource}, + { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource}, + { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, + { .compatible = "qcom,sdm660-cdsp-pas", .data = &cdsp_resource_init}, + { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init}, + { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init}, + { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init}, + { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, + { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource}, + { .compatible = "qcom,shikra-cdsp-pas", .data = &shikra_cdsp_resource }, + { .compatible = "qcom,shikra-lpaicp-pas", .data = &shikra_lpaicp_resource }, + { .compatible = "qcom,shikra-mpss-pas", .data = &shikra_mpss_resource }, + { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init}, + { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init}, + { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource}, + { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource}, + { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource}, + { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource}, + { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource}, + { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource}, + { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource}, + { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource}, + { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init}, + { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource}, + { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init}, + { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource}, + { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource}, + { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init}, + { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource}, + { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource}, + { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init}, + { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource}, + { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource}, + { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource}, + { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource}, + { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, + { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, + { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, + { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource}, + { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource}, + { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource}, { }, }; MODULE_DEVICE_TABLE(of, qcom_pas_of_match); From 527e287025beab1ce61f54346fd2926639d7174f Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Mon, 20 Apr 2026 14:28:10 +0530 Subject: [PATCH 088/128] dt-bindings: remoteproc: qcom: Add Shikra PAS binding Add devicetree binding documentation for the Qualcomm Shikra SoC Peripheral Authentication Service (PAS) remoteproc nodes. Signed-off-by: Bibek Kumar Patro --- .../bindings/remoteproc/qcom,shikra-pas.yaml | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml new file mode 100644 index 0000000000000..f4ec101a35894 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml @@ -0,0 +1,141 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/remoteproc/qcom,shikra-pas.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Shikra SoC Peripheral Authentication Service + +maintainers: + - Bibek Kumar Patro + - Komal Bajaj + +description: + Qualcomm Shikra SoC Peripheral Authentication Service loads and boots firmware + on the Qualcomm DSP Hexagon cores. + +properties: + compatible: + enum: + - qcom,shikra-cdsp-pas + - qcom,shikra-lpaicp-pas + - qcom,shikra-mpss-pas + + reg: + maxItems: 1 + + clocks: + items: + - description: XO clock + + clock-names: + items: + - const: xo + + memory-region: + minItems: 1 + maxItems: 2 + + smd-edge: false + + firmware-name: + minItems: 1 + items: + - description: Firmware name of the Hexagon core + - description: Firmware name of the Hexagon Devicetree + +required: + - compatible + - reg + - memory-region + +allOf: + - $ref: /schemas/remoteproc/qcom,pas-common.yaml# + + - if: + properties: + compatible: + enum: + - qcom,shikra-cdsp-pas + - qcom,shikra-mpss-pas + then: + properties: + interrupts: + minItems: 6 + interrupt-names: + minItems: 6 + memory-region: + maxItems: 1 + firmware-name: + maxItems: 1 + power-domains: + items: + - description: CX power domain + power-domain-names: + items: + - const: cx + + - if: + properties: + compatible: + enum: + - qcom,shikra-lpaicp-pas + then: + properties: + interrupts: + maxItems: 5 + interrupt-names: + maxItems: 5 + memory-region: + minItems: 2 + firmware-name: + minItems: 2 + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + #include + #include + #include + + remoteproc@b300000 { + compatible = "qcom,shikra-cdsp-pas"; + reg = <0x0b300000 0x100000>; + + interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack", "shutdown-ack"; + + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "xo"; + + interconnects = <&mem_noc MASTER_AMPSS_M0 RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, + <&system_noc MASTER_CRYPTO_CORE0 RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>; + + power-domains = <&rpmpd RPMHPD_CX>; + power-domain-names = "cx"; + + memory-region = <&cdsp_mem>; + + qcom,smem-states = <&cdsp_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + glink-edge { + interrupts = ; + mboxes = <&apcs_glb 4>; + qcom,remote-pid = <5>; + label = "cdsp"; + }; + }; From e3fe14f5aa88bd1c4df778c3563c71802bd3986a Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Tue, 5 May 2026 16:22:30 +0530 Subject: [PATCH 089/128] dt-bindings: clock: qcom: Add GCC_QUSB2PHY_SEC_BCR support for Shikra Add GCC_QUSB2PHY_SEC_BCR reset support for Shikra platform. Signed-off-by: Imran Shaik --- include/dt-bindings/clock/qcom,shikra-gcc.h | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/include/dt-bindings/clock/qcom,shikra-gcc.h b/include/dt-bindings/clock/qcom,shikra-gcc.h index 77c6159755ce9..2e88a9cd9f535 100644 --- a/include/dt-bindings/clock/qcom,shikra-gcc.h +++ b/include/dt-bindings/clock/qcom,shikra-gcc.h @@ -243,16 +243,17 @@ #define GCC_PDM_BCR 9 #define GCC_QUPV3_WRAPPER_0_BCR 10 #define GCC_QUSB2PHY_PRIM_BCR 11 -#define GCC_SDCC1_BCR 12 -#define GCC_SDCC2_BCR 13 -#define GCC_TSCSS_BCR 14 -#define GCC_USB20_BCR 15 -#define GCC_USB30_PRIM_BCR 16 -#define GCC_USB3PHY_PHY_PRIM_SP0_BCR 17 -#define GCC_USB3_PHY_PRIM_SP0_BCR 18 -#define GCC_USB_PHY_CFG_AHB2PHY_BCR 19 -#define GCC_VCODEC0_BCR 20 -#define GCC_VENUS_BCR 21 -#define GCC_VIDEO_INTERFACE_BCR 22 +#define GCC_QUSB2PHY_SEC_BCR 12 +#define GCC_SDCC1_BCR 13 +#define GCC_SDCC2_BCR 14 +#define GCC_TSCSS_BCR 15 +#define GCC_USB20_BCR 16 +#define GCC_USB30_PRIM_BCR 17 +#define GCC_USB3PHY_PHY_PRIM_SP0_BCR 18 +#define GCC_USB3_PHY_PRIM_SP0_BCR 19 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 20 +#define GCC_VCODEC0_BCR 21 +#define GCC_VENUS_BCR 22 +#define GCC_VIDEO_INTERFACE_BCR 23 #endif From c786641163b7a58d9666eecd16aec8e0b1961198 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Tue, 5 May 2026 16:24:13 +0530 Subject: [PATCH 090/128] clk: qcom: gcc-shikra: Update GCC driver for Shikra Add GCC_QUSB2PHY_SEC_BCR reset support for Shikra. While at it, drop the flags which are not required for the fixed parent clocks. Signed-off-by: Imran Shaik --- drivers/clk/qcom/gcc-shikra.c | 114 +++++++++------------------------- 1 file changed, 29 insertions(+), 85 deletions(-) diff --git a/drivers/clk/qcom/gcc-shikra.c b/drivers/clk/qcom/gcc-shikra.c index 3ca5ed7cd48a1..8834618354882 100644 --- a/drivers/clk/qcom/gcc-shikra.c +++ b/drivers/clk/qcom/gcc-shikra.c @@ -68,9 +68,12 @@ static const struct pll_vco brammo_vco[] = { { 500000000, 1250000000, 0 }, }; +static const struct pll_vco default_vco[] = { + { 500000000, 1000000000, 2 }, +}; + static const struct pll_vco spark_vco[] = { { 750000000, 1500000000, 1 }, - { 500000000, 1000000000, 2 }, }; static struct clk_alpha_pll gpll0 = { @@ -112,23 +115,6 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { }, }; -static struct clk_alpha_pll gpll1 = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], - .clkr = { - .enable_reg = 0x79000, - .enable_mask = BIT(1), - .hw.init = &(const struct clk_init_data) { - .name = "gpll1", - .parent_data = &(const struct clk_parent_data) { - .index = DT_BI_TCXO, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_ops, - }, - }, -}; - /* 1152.0 MHz Configuration */ static const struct alpha_pll_config gpll10_config = { .l = 0x3c, @@ -176,9 +162,10 @@ static const struct alpha_pll_config gpll11_config = { static struct clk_alpha_pll gpll11 = { .offset = 0xb000, .config = &gpll11_config, - .vco_table = spark_vco, - .num_vco = ARRAY_SIZE(spark_vco), + .vco_table = default_vco, + .num_vco = ARRAY_SIZE(default_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(11), @@ -380,9 +367,10 @@ static const struct alpha_pll_config gpll8_config = { static struct clk_alpha_pll gpll8 = { .offset = 0x8000, .config = &gpll8_config, - .vco_table = spark_vco, - .num_vco = ARRAY_SIZE(spark_vco), + .vco_table = default_vco, + .num_vco = ARRAY_SIZE(default_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(8), @@ -464,9 +452,9 @@ static struct clk_alpha_pll_postdiv gpll9_out_main = { .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main), .width = 2, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO_EVO], - .clkr.hw.init = &(const struct clk_init_data){ + .clkr.hw.init = &(const struct clk_init_data) { .name = "gpll9_out_main", - .parent_hws = (const struct clk_hw*[]){ + .parent_hws = (const struct clk_hw*[]) { &gpll9.clkr.hw, }, .num_parents = 1, @@ -529,7 +517,7 @@ static const struct clk_parent_data gcc_parent_data_3[] = { { .hw = &gpll0.clkr.hw }, { .hw = &gpll9.clkr.hw }, { .hw = &gpll10.clkr.hw }, - { .hw = &gpll9.clkr.hw }, + { .hw = &gpll9_out_main.clkr.hw }, { .hw = &gpll3_out_main.clkr.hw }, }; @@ -874,7 +862,6 @@ static struct clk_rcg2 gcc_camss_axi_clk_src = { .name = "gcc_camss_axi_clk_src", .parent_data = gcc_parent_data_5, .num_parents = ARRAY_SIZE(gcc_parent_data_5), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -896,7 +883,6 @@ static struct clk_rcg2 gcc_camss_cci_clk_src = { .name = "gcc_camss_cci_clk_src", .parent_data = gcc_parent_data_14, .num_parents = ARRAY_SIZE(gcc_parent_data_14), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -920,7 +906,6 @@ static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = { .name = "gcc_camss_csi0phytimer_clk_src", .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -936,7 +921,6 @@ static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = { .name = "gcc_camss_csi1phytimer_clk_src", .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1030,7 +1014,6 @@ static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = { .name = "gcc_camss_ope_ahb_clk_src", .parent_data = gcc_parent_data_7, .num_parents = ARRAY_SIZE(gcc_parent_data_7), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1117,7 +1100,6 @@ static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = { .name = "gcc_camss_tfe_0_csid_clk_src", .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1133,7 +1115,6 @@ static struct clk_rcg2 gcc_camss_tfe_1_clk_src = { .name = "gcc_camss_tfe_1_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1149,7 +1130,6 @@ static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = { .name = "gcc_camss_tfe_1_csid_clk_src", .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1173,7 +1153,6 @@ static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = { .name = "gcc_camss_tfe_cphy_rx_clk_src", .parent_data = gcc_parent_data_15, .num_parents = ARRAY_SIZE(gcc_parent_data_15), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1196,7 +1175,6 @@ static struct clk_rcg2 gcc_camss_top_ahb_clk_src = { .name = "gcc_camss_top_ahb_clk_src", .parent_data = gcc_parent_data_5, .num_parents = ARRAY_SIZE(gcc_parent_data_5), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1221,7 +1199,6 @@ static struct clk_rcg2 gcc_emac0_axi_clk_src = { .name = "gcc_emac0_axi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1242,7 +1219,6 @@ static struct clk_rcg2 gcc_emac0_phy_aux_clk_src = { .name = "gcc_emac0_phy_aux_clk_src", .parent_data = gcc_parent_data_10, .num_parents = ARRAY_SIZE(gcc_parent_data_10), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1263,7 +1239,6 @@ static struct clk_rcg2 gcc_emac0_ptp_clk_src = { .name = "gcc_emac0_ptp_clk_src", .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1286,7 +1261,6 @@ static struct clk_rcg2 gcc_emac0_rgmii_clk_src = { .name = "gcc_emac0_rgmii_clk_src", .parent_data = gcc_parent_data_12, .num_parents = ARRAY_SIZE(gcc_parent_data_12), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1302,7 +1276,6 @@ static struct clk_rcg2 gcc_emac1_axi_clk_src = { .name = "gcc_emac1_axi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1318,7 +1291,6 @@ static struct clk_rcg2 gcc_emac1_phy_aux_clk_src = { .name = "gcc_emac1_phy_aux_clk_src", .parent_data = gcc_parent_data_10, .num_parents = ARRAY_SIZE(gcc_parent_data_10), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1334,7 +1306,6 @@ static struct clk_rcg2 gcc_emac1_ptp_clk_src = { .name = "gcc_emac1_ptp_clk_src", .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1350,7 +1321,6 @@ static struct clk_rcg2 gcc_emac1_rgmii_clk_src = { .name = "gcc_emac1_rgmii_clk_src", .parent_data = gcc_parent_data_12, .num_parents = ARRAY_SIZE(gcc_parent_data_12), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1374,7 +1344,6 @@ static struct clk_rcg2 gcc_gp1_clk_src = { .name = "gcc_gp1_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1390,7 +1359,6 @@ static struct clk_rcg2 gcc_gp2_clk_src = { .name = "gcc_gp2_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1406,7 +1374,6 @@ static struct clk_rcg2 gcc_gp3_clk_src = { .name = "gcc_gp3_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1422,7 +1389,6 @@ static struct clk_rcg2 gcc_pcie_aux_clk_src = { .name = "gcc_pcie_aux_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1438,7 +1404,6 @@ static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = { .name = "gcc_pcie_aux_phy_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1459,7 +1424,6 @@ static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = { .name = "gcc_pcie_rchng_phy_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1481,7 +1445,6 @@ static struct clk_rcg2 gcc_pdm2_clk_src = { .name = "gcc_pdm2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1510,7 +1473,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1528,7 +1490,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1546,7 +1507,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1564,7 +1524,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1582,7 +1541,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1600,7 +1558,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1618,7 +1575,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1636,7 +1592,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1654,7 +1609,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s8_clk_src_init = { .name = "gcc_qupv3_wrap0_s8_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1672,7 +1626,6 @@ static struct clk_init_data gcc_qupv3_wrap0_s9_clk_src_init = { .name = "gcc_qupv3_wrap0_s9_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -1709,7 +1662,6 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1734,7 +1686,6 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1760,7 +1711,6 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_21, .num_parents = ARRAY_SIZE(gcc_parent_data_21), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1776,7 +1726,6 @@ static struct clk_rcg2 gcc_tscss_clk_src = { .name = "gcc_tscss_clk_src", .parent_data = gcc_parent_data_22, .num_parents = ARRAY_SIZE(gcc_parent_data_22), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1798,7 +1747,6 @@ static struct clk_rcg2 gcc_usb20_master_clk_src = { .name = "gcc_usb20_master_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1814,7 +1762,6 @@ static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = { .name = "gcc_usb20_mock_utmi_clk_src", .parent_data = gcc_parent_data_13, .num_parents = ARRAY_SIZE(gcc_parent_data_13), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1838,7 +1785,6 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { .name = "gcc_usb30_prim_master_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1854,7 +1800,6 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .name = "gcc_usb30_prim_mock_utmi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1870,7 +1815,6 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { .name = "gcc_usb3_prim_phy_aux_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, }; @@ -1899,6 +1843,20 @@ static struct clk_rcg2 gcc_video_venus_clk_src = { }, }; +static struct clk_regmap_div gcc_disp_gpll0_clk_src = { + .reg = 0x17058, + .shift = 0, + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = { .reg = 0xb0038, .shift = 0, @@ -2487,20 +2445,6 @@ static struct clk_branch gcc_ddrss_memnoc_pcie_sf_clk = { }, }; -static struct clk_regmap_div gcc_disp_gpll0_clk_src = { - .reg = 0x17058, - .shift = 0, - .width = 2, - .clkr.hw.init = &(struct clk_init_data) { - .name = "gcc_disp_gpll0_clk_src", - .parent_hws = (const struct clk_hw*[]){ - &gpll0.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_regmap_div_ops, - }, -}; - static struct clk_branch gcc_disp_gpll0_div_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -4334,7 +4278,6 @@ static struct clk_regmap *gcc_shikra_clocks[] = { [GCC_VIDEO_VENUS_CTL_CLK] = &gcc_video_venus_ctl_clk.clkr, [GPLL0] = &gpll0.clkr, [GPLL0_OUT_AUX2] = &gpll0_out_aux2.clkr, - [GPLL1] = &gpll1.clkr, [GPLL10] = &gpll10.clkr, [GPLL11] = &gpll11.clkr, [GPLL12] = &gpll12.clkr, @@ -4376,6 +4319,7 @@ static const struct qcom_reset_map gcc_shikra_resets[] = { [GCC_PDM_BCR] = { 0x20000 }, [GCC_QUPV3_WRAPPER_0_BCR] = { 0x1f000 }, [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 }, [GCC_SDCC1_BCR] = { 0x38000 }, [GCC_SDCC2_BCR] = { 0x1e000 }, [GCC_TSCSS_BCR] = { 0xac000 }, @@ -4480,5 +4424,5 @@ static void __exit gcc_shikra_exit(void) } module_exit(gcc_shikra_exit); -MODULE_DESCRIPTION("QTI GCC SHIKRA Driver"); +MODULE_DESCRIPTION("QTI GCC Shikra Driver"); MODULE_LICENSE("GPL"); From 7d82c0719756d380a87761fe4c190b0001c6ca02 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Tue, 5 May 2026 16:31:00 +0530 Subject: [PATCH 091/128] clk: qcom: gpucc-shikra: Drop unused DT_BI_TCXO_AO index Remove the unused enum entry to keep the binding indices aligned with device tree. Signed-off-by: Imran Shaik --- drivers/clk/qcom/gpucc-shikra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/qcom/gpucc-shikra.c b/drivers/clk/qcom/gpucc-shikra.c index 19a938a14d68d..4ad4fc0b6703a 100644 --- a/drivers/clk/qcom/gpucc-shikra.c +++ b/drivers/clk/qcom/gpucc-shikra.c @@ -24,7 +24,6 @@ enum { DT_BI_TCXO, - DT_BI_TCXO_AO, DT_GPLL0_OUT_MAIN, DT_GPLL0_OUT_MAIN_DIV, }; From 116cd1ac6dd212043dac826243540b7439c1cfe6 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 8 May 2026 10:42:17 +0530 Subject: [PATCH 092/128] dt-bindings: clock: qcom: shikra-gcc: Add power-domains property Document the power-domains property in order to propagate the votes on GDSC to CX raill. Signed-off-by: Imran Shaik --- .../bindings/clock/qcom,shikra-gcc.yaml | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml index 39cf7383df8bc..da6eebfa84c22 100644 --- a/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,shikra-gcc.yaml @@ -4,15 +4,15 @@ $id: http://devicetree.org/schemas/clock/qcom,shikra-gcc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Global Clock & Reset Controller on Shikra +title: Global Clock & Reset Controller on Qualcomm Shikra SoC maintainers: - Imran Shaik - Taniya Das description: | - Qualcomm global clock control module provides the clocks, resets and power - domains on Shikra. + Global clock control module provides the clocks, resets and power + domains on Qualcomm Shikra SoC platform. See also: include/dt-bindings/clock/qcom,shikra-gcc.h @@ -31,9 +31,14 @@ properties: - description: PCIE Pipe clock source - description: USB3 phy wrapper pipe clock source + power-domains: + items: + - description: CX domain + required: - compatible - clocks + - power-domains - '#power-domain-cells' allOf: @@ -44,20 +49,22 @@ unevaluatedProperties: false examples: - | #include + #include clock-controller@1400000 { compatible = "qcom,shikra-gcc"; reg = <0x01400000 0x1f0000>; clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, - <&sleep_clk>, - <&emac0_sgmiiphy_rclk>, - <&emac0_sgmiiphy_tclk>, - <&emac1_sgmiiphy_rclk>, - <&emac1_sgmiiphy_tclk>, - <&pcie_pipe_clk>, - <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; + <&sleep_clk>, + <&emac0_sgmiiphy_rclk>, + <&emac0_sgmiiphy_tclk>, + <&emac1_sgmiiphy_rclk>, + <&emac1_sgmiiphy_tclk>, + <&pcie_pipe_clk>, + <&usb3_phy_wrapper_gcc_usb30_pipe_clk>; + power-domains = <&rpmpd RPMPD_VDDCX>; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; }; ... From 0ae26ead9a5dd6281aa25b399d903f02b8a1932c Mon Sep 17 00:00:00 2001 From: Sneh Mankad Date: Fri, 27 Mar 2026 18:14:37 +0530 Subject: [PATCH 093/128] dt-bindings: mailbox: qcom: Modify Shikra APCS compatible Mention compatible for the Qualcomm Shikra APCS block in the same block as sdm845-apss-shared since they share the same data. Signed-off-by: Sneh Mankad --- .../devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml index bc1dc44fc2de8..1b4ef0688ca79 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml @@ -49,6 +49,7 @@ properties: - qcom,qcs615-apss-shared - qcom,sc7180-apss-shared - qcom,sc8180x-apss-shared + - qcom,shikra-apss-shared - qcom,sm7150-apss-shared - qcom,sm8150-apss-shared - const: qcom,sdm845-apss-shared @@ -65,7 +66,6 @@ properties: - qcom,msm8996-apcs-hmss-global - qcom,qcm2290-apcs-hmss-global - qcom,sdm845-apss-shared - - qcom,shikra-apcs-hmss-global reg: maxItems: 1 @@ -239,7 +239,6 @@ allOf: - qcom,msm8996-apcs-hmss-global - qcom,qcm2290-apcs-hmss-global - qcom,sdm845-apss-shared - - qcom,shikra-apcs-hmss-global then: properties: clocks: false From c7d8100749c6e861041c8b37ff314be46be923eb Mon Sep 17 00:00:00 2001 From: Anandu Krishnan E Date: Tue, 12 May 2026 13:54:49 +0530 Subject: [PATCH 094/128] misc: fastrpc: Introduce cache maintenance operations Introduce cache maintenance operations for remote arguments in fastrpc driver for non-dma coherent targets. Upstream-Status: Pending Signed-off-by: Abhinav Parihar Signed-off-by: Anandu Krishnan E --- drivers/misc/fastrpc.c | 103 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1080f9acf70a3..bd30d816b24ee 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -187,6 +187,7 @@ struct fastrpc_buf_overlap { u64 mstart; u64 mend; u64 offset; + bool do_cmo; }; struct fastrpc_buf { @@ -255,6 +256,7 @@ struct fastrpc_session_ctx { int sid; bool used; bool valid; + bool coherent; }; struct fastrpc_soc_data { @@ -330,6 +332,18 @@ static inline u64 fastrpc_sid_offset(struct fastrpc_channel_ctx *cctx, return (u64)sctx->sid << cctx->soc_data->sid_pos; } +/* + * Align buffer size to kernel page granularity for dma-buf cache maintenance. + */ +static inline uint64_t buf_page_size(uint64_t size) +{ + int cache_align = dma_get_cache_alignment(); + uint64_t sz = ALIGN(size, cache_align); + + return max_t(uint64_t, sz, (uint64_t)cache_align); +} + + static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; @@ -558,7 +572,9 @@ static int olaps_cmp(const void *a, const void *b) static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx) { u64 max_end = 0; + int max_raix = -1; int i; + int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); for (i = 0; i < ctx->nbufs; ++i) { ctx->olaps[i].start = ctx->args[i].ptr; @@ -578,6 +594,9 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx) if (ctx->olaps[i].end > max_end) { max_end = ctx->olaps[i].end; } else { + if ((max_raix < inbufs && ctx->olaps[i].raix + 1 > inbufs) || + (ctx->olaps[i].raix < inbufs && max_raix + 1 > inbufs)) + ctx->olaps[i].do_cmo = true; ctx->olaps[i].mend = 0; ctx->olaps[i].mstart = 0; } @@ -587,6 +606,7 @@ static void fastrpc_get_buff_overlaps(struct fastrpc_invoke_ctx *ctx) ctx->olaps[i].mstart = ctx->olaps[i].start; ctx->olaps[i].offset = 0; max_end = ctx->olaps[i].end; + max_raix = ctx->olaps[i].raix; } } } @@ -806,7 +826,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, err = PTR_ERR(map->attach); goto attach_err; } - + if (!sess->coherent) table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); if (IS_ERR(table)) { err = PTR_ERR(table); @@ -973,6 +993,70 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx) return 0; } +static int fastrpc_flush_args(struct fastrpc_invoke_ctx *ctx, + union fastrpc_remote_arg *rpra) +{ + int oix, inbufs, outbufs; + struct device *dev = ctx->fl->sctx->dev; + + inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); + outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc); + for (oix = 0; oix < inbufs+outbufs; ++oix) { + int i = ctx->olaps[oix].raix; + struct fastrpc_map *map = ctx->maps[i]; + + if (i+1 > inbufs) + continue; + if (!map) + continue; + if (rpra[i].buf.len && ctx->olaps[oix].mstart) { + if (map->buf) { + if ((buf_page_size(ctx->olaps[oix].mend - + ctx->olaps[oix].mstart)) == map->size ) { + dma_buf_begin_cpu_access(map->buf, DMA_TO_DEVICE); + dma_buf_end_cpu_access(map->buf, DMA_TO_DEVICE); + } + } + } + } + return 0; +} + +static int fastrpc_inv_args(struct fastrpc_invoke_ctx *ctx) +{ + int i, inbufs, outbufs; + uint32_t sc = ctx->sc; + union fastrpc_remote_arg *rpra = ctx->rpra; + struct device *dev = ctx->fl->sctx->dev; + + inbufs = REMOTE_SCALARS_INBUFS(sc); + outbufs = REMOTE_SCALARS_OUTBUFS(sc); + for (i = 0; i < inbufs+outbufs; ++i) { + int over = ctx->olaps[i].raix; + struct fastrpc_map *map = ctx->maps[over]; + + if (over + 1 <= inbufs) + continue; + if (!rpra[over].buf.len) + continue; + if (!map) + continue; + if (((uintptr_t)rpra & PAGE_MASK) == + ((uintptr_t)rpra[over].buf.pv & PAGE_MASK)) + continue; + if (ctx->olaps[i].mstart) { + if (map->buf) { + if (((buf_page_size(ctx->olaps[i].mend - + ctx->olaps[i].mstart)) == map->size)) { + dma_buf_begin_cpu_access(map->buf, DMA_FROM_DEVICE); + dma_buf_end_cpu_access(map->buf, DMA_TO_DEVICE); + } + } + } + } + return 0; +} + static struct fastrpc_invoke_buf *fastrpc_invoke_buf_start(union fastrpc_remote_arg *pra, int len) { return (struct fastrpc_invoke_buf *)(&pra[len]); @@ -1093,6 +1177,12 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) } } + if (!ctx->fl->sctx->coherent) { + err = fastrpc_flush_args(ctx, rpra); + if (err) + goto bail; + } + for (i = ctx->nbufs; i < ctx->nscalars; ++i) { list[i].num = ctx->args[i].length ? 1 : 0; list[i].pgidx = i; @@ -1220,6 +1310,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (err) goto bail; + if (!fl->sctx->coherent) { + err = fastrpc_inv_args(ctx); + if (err) + goto bail; + } /* make sure that all CPU memory writes are seen by DSP */ dma_wmb(); /* Send invoke buffer to remote dsp */ @@ -1239,6 +1334,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, /* make sure that all memory writes by DSP are seen by CPU */ dma_rmb(); + if (!fl->sctx->coherent) { + err = fastrpc_inv_args(ctx); + if (err) + goto bail; + } /* populate all the output buffers with results */ err = fastrpc_put_args(ctx, kernel); if (err) @@ -2217,6 +2317,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev) sess->used = false; sess->valid = true; sess->dev = dev; + sess->coherent = of_property_read_bool(dev->of_node, "dma-coherent"); dev_set_drvdata(dev, sess); if (cctx->domain_id == CDSP_DOMAIN_ID) From c3b3cbe560d7424b604cc37f25222bbda727aafd Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 9 Apr 2026 16:11:55 +0530 Subject: [PATCH 095/128] dt-bindings: media: qcom,qcm2290-venus: document shikra Iris compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the Iris video accelerator used on Shikra platforms by adding the qcom,shikra-iris compatible. Although QCM2290 and Shikra share the same video hardware and overall integration, their SMMU programming differs. QCM2290 exposes separate Stream IDs for the video hardware and the Xtensa path, requiring two explicit IOMMU entries, whereas Shikra uses a masked SMR to collapse equivalent Stream IDs into a single mapping. Due to QCM2290’s SID layout and Xtensa isolation requirements, such SMR masking is not applicable on QCM2290 platforms. Since Shikra uses the same video hardware as QCM2290 and shares the same programming model and capabilities, it is added as a fallback compatible to qcom,qcm2290-venus, with conditional handling to allow either one or two IOMMU entries. Signed-off-by: Dikshita Agarwal --- .../bindings/media/qcom,qcm2290-venus.yaml | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml index 7e6dc410c2d2b..10713164c2d80 100644 --- a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml +++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml @@ -15,10 +15,27 @@ description: allOf: - $ref: qcom,venus-common.yaml# + - if: + properties: + compatible: + contains: + const: qcom,shikra-iris + then: + properties: + iommus: + maxItems: 1 + else: + properties: + iommus: + maxItems: 2 properties: compatible: - const: qcom,qcm2290-venus + oneOf: + - items: + - const: qcom,shikra-iris + - const: qcom,qcm2290-venus + - const: qcom,qcm2290-venus power-domains: maxItems: 3 @@ -41,9 +58,6 @@ properties: - const: vcodec0_core - const: vcodec0_bus - iommus: - maxItems: 2 - interconnects: maxItems: 2 From e606a118cd6132960cfb7e2fce33dfa449ba1482 Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Tue, 12 May 2026 17:00:31 +0530 Subject: [PATCH 096/128] iommu/arm-smmu: Add ACTLR settings for missing MDSS devices for new Shikra platform Shikra being a new platform has a different target specific compatible for mdss device. Add ACTLR configuration for corresponding compatible to apply the required QoS settings. Signed-off-by: Bibek Kumar Patro --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index edd41b5a3b6ac..a668666fd367b 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -53,6 +53,8 @@ static const struct of_device_id qcom_smmu_actlr_client_of_match[] = { .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sc8280xp-mdss", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, + { .compatible = "qcom,shikra-mdss", + .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sm6115-mdss", .data = (const void *) (PREFETCH_SHALLOW | CPRE | CMTLB) }, { .compatible = "qcom,sm6125-mdss", From 89c98e36bd908e503021067fcd0388b3e44a15b5 Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Tue, 5 May 2026 20:12:30 +0530 Subject: [PATCH 097/128] dt-bindings: display: msm: qcm2290: Add Shikra MDSS Shikra SoC uses the same MDSS/DPU/DSI hardware as QCM2290 (DPU 6.5), sharing the same register layout, DSI controller and 14nm DSI PHY. Add qcom,shikra-mdss to the qcm2290-mdss binding compatible enum rather than introducing a separate binding file. Register qcom,shikra-dsi-ctrl in dsi-controller-main.yaml alongside qcom,qcm2290-dsi-ctrl, and update the qcm2290-mdss patternProperties to accept both SoC-specific DPU and DSI controller compatibles. Signed-off-by: Mahadevan P --- .../display/msm/dsi-controller-main.yaml | 1 + .../display/msm/qcom,qcm2290-dpu.yaml | 4 ++- .../display/msm/qcom,qcm2290-mdss.yaml | 34 +++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index a24fcb9144181..2db9d72777e04 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -32,6 +32,7 @@ properties: - qcom,sdm660-dsi-ctrl - qcom,sdm670-dsi-ctrl - qcom,sdm845-dsi-ctrl + - qcom,shikra-dsi-ctrl - qcom,sm6115-dsi-ctrl - qcom,sm6125-dsi-ctrl - qcom,sm6150-dsi-ctrl diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml index be6cd8adb3b67..cc1f227ade2d3 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml @@ -13,7 +13,9 @@ $ref: /schemas/display/msm/dpu-common.yaml# properties: compatible: - const: qcom,qcm2290-dpu + enum: + - qcom,qcm2290-dpu + - qcom,shikra-dpu reg: items: diff --git a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml index bb09ecd1a5b4f..8271cb71bab8f 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml @@ -4,21 +4,35 @@ $id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm QCM220 Display MDSS +title: Qualcomm QCM2290 and Shikra Display MDSS maintainers: - Loic Poulain + - Mahadevan P description: Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS - are mentioned for QCM2290 target. + are mentioned for QCM2290 and Shikra targets. Shikra uses the same MDSS/DPU/DSI + hardware as QCM2290 (DPU 6.5) and shares the same register layout. $ref: /schemas/display/msm/mdss-common.yaml# +select: + properties: + compatible: + contains: + enum: + - qcom,qcm2290-mdss + - qcom,shikra-mdss + required: + - compatible + properties: compatible: - const: qcom,qcm2290-mdss + enum: + - qcom,qcm2290-mdss + - qcom,shikra-mdss clocks: items: @@ -52,7 +66,9 @@ patternProperties: properties: compatible: - const: qcom,qcm2290-dpu + enum: + - qcom,qcm2290-dpu + - qcom,shikra-dpu "^dsi@[0-9a-f]+$": type: object @@ -60,9 +76,13 @@ patternProperties: properties: compatible: - items: - - const: qcom,qcm2290-dsi-ctrl - - const: qcom,mdss-dsi-ctrl + oneOf: + - items: + - const: qcom,qcm2290-dsi-ctrl + - const: qcom,mdss-dsi-ctrl + - items: + - const: qcom,shikra-dsi-ctrl + - const: qcom,mdss-dsi-ctrl "^phy@[0-9a-f]+$": type: object From ba489cbcba7a852d2eb7016a8672757e257c49b0 Mon Sep 17 00:00:00 2001 From: Arpit Saini Date: Tue, 12 May 2026 16:57:57 +0530 Subject: [PATCH 098/128] dt-bindings: display: panel: Add DLC0697 DSI panel binding Add Device Tree binding documentation for the DLC DLC0697 1080x1920 video-mode MIPI DSI panel. Add a MAINTAINERS entry covering the binding and the panel driver. Signed-off-by: Arpit Saini Signed-off-by: Mahadevan P --- .../bindings/display/panel/dlc,dlc0697.yaml | 66 +++++++++++++++++++ MAINTAINERS | 7 ++ 2 files changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/dlc,dlc0697.yaml diff --git a/Documentation/devicetree/bindings/display/panel/dlc,dlc0697.yaml b/Documentation/devicetree/bindings/display/panel/dlc,dlc0697.yaml new file mode 100644 index 0000000000000..8ae72a8265e61 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/dlc,dlc0697.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/dlc,dlc0697.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: DLC DLC0697 1080x1920 video-mode DSI panel + +maintainers: + - Arpit Saini + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: dlc,dlc0697 + + reg: + maxItems: 1 + description: DSI virtual channel + + reset-gpios: true + + enable-gpios: true + + vddio-supply: + description: I/O voltage supply (1.8V) + + bias-supply: + description: LCD bias supply (3.3V), typically a GPIO-controlled fixed regulator + + port: true + +required: + - compatible + - reg + - reset-gpios + - vddio-supply + - port + +additionalProperties: false + +examples: + - | + #include + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "dlc,dlc0697"; + reg = <0>; + + reset-gpios = <&tlmm 41 GPIO_ACTIVE_LOW>; + vddio-supply = <&vreg_l15>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 882214b0e7db5..0034082e3c82d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7928,6 +7928,13 @@ S: Maintained F: Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml F: drivers/gpu/drm/bridge/chipone-icn6211.c +DRM DRIVER FOR DLC DLC0697 DSI PANEL +M: Arpit Saini +S: Maintained +T: git https://gitlab.freedesktop.org/drm/misc/kernel.git +F: Documentation/devicetree/bindings/display/panel/dlc,dlc0697.yaml +F: drivers/gpu/drm/panel/panel-dlc0697.c + DRM DRIVER FOR EBBG FT8719 PANEL M: Joel Selvaraj S: Maintained From 9f37c5afe0cefd8eac0ed581c10ff9a833d78d7b Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Tue, 5 May 2026 19:57:34 +0530 Subject: [PATCH 099/128] drm/msm/mdss: Add Shikra support Add Mobile Display Subsystem (MDSS) support for the Shikra platform. Shikra uses the same MDSS and DPU 6.5 hardware as QCM2290, so it reuses the same AHB clock rate configuration (data_76k8) and DPU catalog. Register qcom,shikra-dpu in the DPU KMS match table pointing to dpu_qcm2290_cfg. Signed-off-by: Mahadevan P --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 + drivers/gpu/drm/msm/msm_mdss.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 35f7af4743d7e..a229df7bb1f94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1495,6 +1495,7 @@ static const struct of_device_id dpu_dt_match[] = { { .compatible = "qcom,sdm660-mdp5", .data = &dpu_sdm660_cfg, }, { .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, }, { .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, }, + { .compatible = "qcom,shikra-dpu", .data = &dpu_qcm2290_cfg, }, { .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, }, { .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, }, { .compatible = "qcom,sc8180x-dpu", .data = &dpu_sc8180x_cfg, }, diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 90c3fa0681a06..58d14cadcad1a 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -578,6 +578,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sar2130p-mdss", .data = &data_74k }, { .compatible = "qcom,sdm670-mdss", .data = &data_76k8 }, { .compatible = "qcom,sdm845-mdss", .data = &data_76k8 }, + { .compatible = "qcom,shikra-mdss", .data = &data_76k8 }, { .compatible = "qcom,sc7180-mdss", .data = &data_76k8 }, { .compatible = "qcom,sc7280-mdss", .data = &data_74k }, { .compatible = "qcom,sc8180x-mdss", .data = &data_76k8 }, From c58c64e5438d7cc7325a12bda02ee7c1289ea0b8 Mon Sep 17 00:00:00 2001 From: Arpit Saini Date: Tue, 12 May 2026 17:01:53 +0530 Subject: [PATCH 100/128] drm/panel: Add driver for DLC0697 FHD video-mode DSI panel Add a DRM panel driver for the DLC0697 1080x1920@60Hz MIPI DSI panel. The driver implements the panel init/exit sequence, power and reset handling, a fixed display mode, and DCS backlight control. The panel operates in video burst mode with four data lanes using RGB888 pixel format. Backlight enable GPIO is toggled directly in enable/disable; backlight brightness is managed via the DRM backlight framework using the 16-bit DCS brightness API. Signed-off-by: Arpit Saini Signed-off-by: Mahadevan P --- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-dlc0697.c | 339 ++++++++++++++++++++++++++ 3 files changed, 351 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-dlc0697.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index d6863b28ddc55..fda9f2f4c259c 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -105,6 +105,17 @@ config DRM_PANEL_BOE_TV101WUM_LL2 Say Y here if you want to support for BOE TV101WUM-LL2 WUXGA PANEL DSI Video Mode panel +config DRM_PANEL_DLC0697 + tristate "DLC0697 1080x1920 video mode DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the DLC DLC0697 + 1080x1920 60Hz MIPI-DSI video mode panel found on Qualcomm + Shikra (QCM2290-based) EVK boards. The panel supports hardware + backlight control via the MIPI DCS brightness command. + config DRM_PANEL_EBBG_FT8719 tristate "EBBG FT8719 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index a4291dc3905be..3eb4035877999 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a. obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_LL2) += panel-boe-tv101wum-ll2.o obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o +obj-$(CONFIG_DRM_PANEL_DLC0697) += panel-dlc0697.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_EDP) += panel-edp.o diff --git a/drivers/gpu/drm/panel/panel-dlc0697.c b/drivers/gpu/drm/panel/panel-dlc0697.c new file mode 100644 index 0000000000000..f0ef07cb0160f --- /dev/null +++ b/drivers/gpu/drm/panel/panel-dlc0697.c @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + +/* + * DRM panel driver for DLC0697 1080x1920 60Hz video-mode DSI panel + * + * Derived from downstream Qualcomm panel DT data. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct dlc0697 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; + struct gpio_desc *enable_gpio; + + struct pinctrl *pinctrl; + struct pinctrl_state *state_active; + struct pinctrl_state *state_suspend; +}; + +static const struct regulator_bulk_data dlc0697_supplies[] = { + { .supply = "vddio" }, + { .supply = "bias" }, +}; + +static inline struct dlc0697 *to_dlc0697(struct drm_panel *panel) +{ + return container_of(panel, struct dlc0697, panel); +} + +static const struct drm_display_mode dlc0697_mode = { + .clock = 131911, + + .hdisplay = 1080, + .hsync_start = 1080 + 18, + .hsync_end = 1080 + 18 + 2, + .htotal = 1080 + 18 + 2 + 16, + + .vdisplay = 1920, + .vsync_start = 1920 + 26, + .vsync_end = 1920 + 26 + 4, + .vtotal = 1920 + 26 + 4 + 20, + + .width_mm = 0, + .height_mm = 0, +}; + +static void dlc0697_reset(struct dlc0697 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); +} + +static int dlc0697_on(struct dlc0697 *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_soft_reset_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0x78, 0x07, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x09, 0x99); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x24); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x3f, 0xff); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + if (dsi_ctx.accum_err) + dev_err(&ctx->dsi->dev, "panel on sequence failed: %d\n", dsi_ctx.accum_err); + + return dsi_ctx.accum_err; +} + +static int dlc0697_off(struct dlc0697 *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + if (dsi_ctx.accum_err) + dev_err(&ctx->dsi->dev, "panel off sequence failed: %d\n", dsi_ctx.accum_err); + + return dsi_ctx.accum_err; +} + +static int dlc0697_enable(struct drm_panel *panel) +{ + struct dlc0697 *ctx = to_dlc0697(panel); + + if (ctx->enable_gpio) + gpiod_set_value_cansleep(ctx->enable_gpio, 1); + + return 0; +} + +static int dlc0697_disable(struct drm_panel *panel) +{ + struct dlc0697 *ctx = to_dlc0697(panel); + + if (ctx->enable_gpio) + gpiod_set_value_cansleep(ctx->enable_gpio, 0); + + return 0; +} + +static int dlc0697_prepare(struct drm_panel *panel) +{ + struct dlc0697 *ctx = to_dlc0697(panel); + int ret; + + if (ctx->pinctrl && ctx->state_active) { + ret = pinctrl_select_state(ctx->pinctrl, ctx->state_active); + if (ret < 0) + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(dlc0697_supplies), ctx->supplies); + if (ret < 0) { + dev_err(ctx->panel.dev, "failed to enable regulators: %d\n", ret); + return ret; + } + + /* qcom,supply-post-on-sleep = <20> */ + msleep(20); + + dlc0697_reset(ctx); + + ret = dlc0697_on(ctx); + if (ret < 0) + goto err; + + return 0; + +err: + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + if (ctx->pinctrl && ctx->state_suspend) + pinctrl_select_state(ctx->pinctrl, ctx->state_suspend); + + regulator_bulk_disable(ARRAY_SIZE(dlc0697_supplies), ctx->supplies); + + return ret; +} + +static int dlc0697_unprepare(struct drm_panel *panel) +{ + struct dlc0697 *ctx = to_dlc0697(panel); + + dlc0697_off(ctx); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + if (ctx->pinctrl && ctx->state_suspend) + pinctrl_select_state(ctx->pinctrl, ctx->state_suspend); + + regulator_bulk_disable(ARRAY_SIZE(dlc0697_supplies), ctx->supplies); + + return 0; +} + +static int dlc0697_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &dlc0697_mode); +} + +static const struct drm_panel_funcs dlc0697_panel_funcs = { + .prepare = dlc0697_prepare, + .unprepare = dlc0697_unprepare, + .enable = dlc0697_enable, + .disable = dlc0697_disable, + .get_modes = dlc0697_get_modes, +}; + +static int dlc0697_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + return 0; +} + +static const struct backlight_ops dlc0697_bl_ops = { + .update_status = dlc0697_bl_update_status, +}; + +static struct backlight_device *dlc0697_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 4095, + .max_brightness = 4095, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &dlc0697_bl_ops, &props); +} + +static int dlc0697_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct dlc0697 *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct dlc0697, panel, + &dlc0697_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(dlc0697_supplies), + dlc0697_supplies, &ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get regulators\n"); + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "failed to get reset gpio\n"); + + ctx->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(ctx->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->enable_gpio), + "failed to get enable gpio\n"); + + ctx->pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(ctx->pinctrl)) { + if (PTR_ERR(ctx->pinctrl) == -ENODEV) { + ctx->pinctrl = NULL; + } else { + return dev_err_probe(dev, PTR_ERR(ctx->pinctrl), + "failed to get pinctrl\n"); + } + } + + if (ctx->pinctrl) { + ctx->state_active = pinctrl_lookup_state(ctx->pinctrl, "default"); + if (IS_ERR(ctx->state_active)) + ctx->state_active = NULL; + + ctx->state_suspend = pinctrl_lookup_state(ctx->pinctrl, "sleep"); + if (IS_ERR(ctx->state_suspend)) + ctx->state_suspend = NULL; + } + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; + + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = dlc0697_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "failed to attach dsi\n"); + } + + return 0; +} + +static void dlc0697_remove(struct mipi_dsi_device *dsi) +{ + drm_panel_remove(mipi_dsi_get_drvdata(dsi)); +} + +static const struct of_device_id dlc0697_of_match[] = { + { .compatible = "dlc,dlc0697" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dlc0697_of_match); + +static struct mipi_dsi_driver dlc0697_driver = { + .probe = dlc0697_probe, + .remove = dlc0697_remove, + .driver = { + .name = "panel-dlc0697", + .of_match_table = dlc0697_of_match, + }, +}; +module_mipi_dsi_driver(dlc0697_driver); + +MODULE_AUTHOR("Arpit Saini "); +MODULE_DESCRIPTION("DLC0697 1080x1920 video mode DSI panel"); +MODULE_LICENSE("GPL"); From 65d343878c5e222a3680767851708893ecfd1e82 Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Wed, 6 May 2026 10:17:26 +0530 Subject: [PATCH 101/128] arm64: defconfig: Enable DLC0697 DSI panel driver Enable the DLC0697 1080x1920 video-mode DSI panel driver as a module, used on the Shikra CQM EVK board. Signed-off-by: Mahadevan P --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index cf020d9139dcf..82cb75aa37033 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -993,6 +993,7 @@ CONFIG_DRM_TEGRA=m CONFIG_DRM_STM=m CONFIG_DRM_STM_LVDS=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +CONFIG_DRM_PANEL_DLC0697=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_SUMMIT=m From 96a38f617c1f4707073c77b3a1c747aa9fff0545 Mon Sep 17 00:00:00 2001 From: Mahadevan P Date: Mon, 11 May 2026 15:58:52 +0530 Subject: [PATCH 102/128] soc: qcom: ubwc: Add Shikra UBWC config Add UBWC configuration for the Shikra platform. Shikra has no UBWC support and no highest_bank_bit setting, so use no_ubwc_data. Signed-off-by: Mahadevan P --- drivers/soc/qcom/ubwc_config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 3fe47d8f0f638..01dca97e26714 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -278,6 +278,7 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,sdm660", .data = &msm8937_data }, { .compatible = "qcom,sdm670", .data = &sdm670_data, }, { .compatible = "qcom,sdm845", .data = &sdm845_data, }, + { .compatible = "qcom,shikra", .data = &no_ubwc_data, }, { .compatible = "qcom,sm4250", .data = &sm6115_data, }, { .compatible = "qcom,sm6115", .data = &sm6115_data, }, { .compatible = "qcom,sm6125", .data = &sm6125_data, }, From 4dae440b358bd921f650d90340289ba330fffda9 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 9 Apr 2026 14:52:06 +0530 Subject: [PATCH 103/128] ASoC: dt-bindings: Add schema for qcom,wsa885x-i2c Add a devicetree binding schema for Qualcomm WSA885X smart speaker amplifier on I2C. Document the device compatible, supplies, GPIOs, DAI cell count and initialization table property used by the driver. Keep a single init table property (wsa885x-init-table) as currently supported. Signed-off-by: Prasad Kumpatla --- .../bindings/sound/qcom,wsa885x-i2c.yaml | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml new file mode 100644 index 0000000000000..6bc742b0aacf8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,wsa885x-i2c.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,wsa885x-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm WSA885X I2C smart speaker amplifier + +maintainers: + - Srinivas Kandagatla + +allOf: + - $ref: dai-common.yaml# + +description: | + WSA885X is a Qualcomm smart speaker amplifier codec. + This binding describes the I2C control interface and + board-level resources required by the codec. + +properties: + compatible: + const: qcom,wsa885x-i2c + + reg: + maxItems: 1 + + '#sound-dai-cells': + const: 0 + + powerdown-gpios: + description: GPIO spec for the codec shutdown/powerdown pin. + maxItems: 1 + + interrupt-gpios: + description: GPIO spec for the codec interrupt pin. + maxItems: 1 + + vdd-io-supply: + description: 1.8V I/O supply. + + vdd-1p8-supply: + description: 1.8V analog/digital core supply. + + qcom,battery_config: + description: Battery topology configuration. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2] + + wsa885x-init-table: + description: Register/value initialization table as pairs. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 512 + +required: + - compatible + - reg + - '#sound-dai-cells' + - vdd-io-supply + - vdd-1p8-supply + - wsa885x-init-table + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + speaker-codec@c { + compatible = "qcom,wsa885x-i2c"; + reg = <0x0c>; + #sound-dai-cells = <0>; + + qcom,battery_config = <1>; + + powerdown-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + interrupt-gpios = <&tlmm 13 GPIO_ACTIVE_HIGH>; + + vdd-io-supply = <&vreg_l15a_1p8>; + vdd-1p8-supply = <&vreg_l10a_1p8>; + + wsa885x-init-table = < + 0x800d 0x1c + 0x8090 0x1f + >; + }; + }; + +... From e2a212affd7eb967ec8e53b8304e987881e8db09 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Thu, 9 Apr 2026 16:22:47 +0530 Subject: [PATCH 104/128] ASoC: codecs: add Qualcomm WSA885X I2C codec driver Add a new ASoC codec driver for Qualcomm WSA885X over I2C. Signed-off-by: Prasad Kumpatla --- sound/soc/codecs/Kconfig | 9 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wsa885x-i2c.c | 1359 ++++++++++++++++++++++++++++++++ 3 files changed, 1370 insertions(+) create mode 100644 sound/soc/codecs/wsa885x-i2c.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index cf94a1c756e09..c9925fbbeb681 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -363,6 +363,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WSA881X imply SND_SOC_WSA883X imply SND_SOC_WSA884X + imply SND_SOC_WSA885X_I2C imply SND_SOC_ZL38060 help Normally ASoC codec drivers are only built if a machine driver which @@ -2735,6 +2736,14 @@ config SND_SOC_WSA884X This enables support for Qualcomm WSA8840/WSA8845/WSA8845H Class-D Smart Speaker Amplifier. +config SND_SOC_WSA885X_I2C + tristate "WSA885X I2C Codec" + depends on I2C + select REGMAP_I2C + help + This enables support for Qualcomm WSA885X Smart Speaker + Amplifier over I2C. + config SND_SOC_ZL38060 tristate "Microsemi ZL38060 Connected Home Audio Processor" depends on SPI_MASTER diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 172861d17cfd0..a9e82f4019bde 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -422,6 +422,7 @@ snd-soc-wm-hubs-y := wm_hubs.o snd-soc-wsa881x-y := wsa881x.o snd-soc-wsa883x-y := wsa883x.o snd-soc-wsa884x-y := wsa884x.o +snd-soc-wsa885x-i2c-y := wsa885x-i2c.o snd-soc-zl38060-y := zl38060.o # Amp snd-soc-max9877-y := max9877.o @@ -868,6 +869,7 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o obj-$(CONFIG_SND_SOC_WSA883X) += snd-soc-wsa883x.o obj-$(CONFIG_SND_SOC_WSA884X) += snd-soc-wsa884x.o +obj-$(CONFIG_SND_SOC_WSA885X_I2C) += snd-soc-wsa885x-i2c.o obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o # Amp diff --git a/sound/soc/codecs/wsa885x-i2c.c b/sound/soc/codecs/wsa885x-i2c.c new file mode 100644 index 0000000000000..2ace3a0956b25 --- /dev/null +++ b/sound/soc/codecs/wsa885x-i2c.c @@ -0,0 +1,1359 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/* WSA885X I2C codec driver */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Driver Constants */ +#define CLK_RATE_FIXED 73728000 +#define SUPPLIES_NUM 2 +#define SLAVE_ADDR 0x00c +#define NUM_REGS 0x03 + +/* Interrupt Registers */ +#define WSA885X_INTR_STATUS0 0x8584 /* Base address of the status register */ +#define WSA885X_INTR_MASK0 0x8581 /* Base address of the mask register */ +#define WSA885X_INTR_CLEAR0 0x8587 /* Base address of the acknowledge register */ +#define WSA885X_INTR_LEVEL0 0x858A /* Base address of the acknowledge register */ + +/* Power and PA FSM Control Registers */ +#define WSA885X_POWER_FSM_CTL0 0x8423 +#define WSA885X_PA0_FSM_CTL0 0x842A +#define WSA885X_PA1_FSM_CTL0 0x8434 + +/* Digital Control GPIO and Interrupt Registers */ +#define DIG_CTRL1_PIN_CT 0x8510 +#define DIG_CTRL1_SPMI_PAD_GPIO2_CTL 0x8518 +#define DIG_CTRL1_INTR_MODE 0x8580 + +/* Control Registers - Audio Processing */ +#define SMP_AMP_CTRL_STEREO_STEREO_SMP_AMP_CTRL_I2S 0x0000 +#define SMP_AMP_CTRL_STEREO_CMT_GRP_MASK 0x0004 +#define SMP_AMP_CTRL_STEREO_IT21_CLUSERINDEX 0x0140 +#define SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID 0x0208 +#define SMP_AMP_CTRL_STEREO_CS21_SAMPLERATEINDEX 0x0240 +#define SMP_AMP_CTRL_STEREO_PPU21_POSTURENUMBER 0x0340 +#define SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X0 0x4405 +#define SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X1 0x4406 +#define SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_LSB 0x4409 +#define SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_MSB 0x6409 +#define SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_LSB 0x440a +#define SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_MSB 0x640a +#define SMP_AMP_CTRL_STEREO_PDE23_REQ_PS 0x0a04 +#define SMP_AMP_CTRL_STEREO_PDE23_ACT_PS 0x0a40 +#define SMP_AMP_CTRL_STEREO_OT23_USAGE 0x0b10 +#define SMP_AMP_CTRL_STEREO_CS24_SAMPLERATEINDEX 0x0e40 + +/* Analog Top Registers - Power and Clock Control */ +#define ANA_TOP_PON_CKSK_CTL_0 0x800d +#define ANA_TOP_BG_TVP_UVLO1_PROG 0x8024 +#define ANA_TOP_BG_TVP_UVLO2_PROG 0x8025 +#define ANA_TOP_BG_TVP_OVRD_CTL 0x8034 + +/* Analog PLL Registers */ +#define ANA_PLL_DIV_CTL_0 0x8090 +#define ANA_PLL_DIV_CTL_1 0x8091 +#define ANA_TOP_PLL_VCO_CTL 0x8092 +#define ANA_TOP_PLL_LOOPFILT_0 0x8093 +#define ANA_TOP_PLL_OVRD_CTL 0x8098 +#define ANA_TOP_PLL_STATUS_0 0x809a +#define ANA_TOP_PLL_STATUS_1 0x809b + +/* Analog Boost Control Registers */ +#define ANA_TOP_BOOST_STB_CTRL2 0x805b +#define ANA_TOP_BOOST_STB_CTRL3 0x805c +#define ANA_TOP_BOOST_BYP_CTRL2 0x805e +#define ANA_TOP_BOOST_BYP_CTRL3 0x805f +#define ANA_TOP_BOOST_MISC 0x8063 +#define ANA_TOP_BOOST_PWRSTAGE_CTRL2 0x8065 +#define ANA_TOP_BOOST_PWRSTAGE_CTRL4 0x8067 + +/* Analog IV Sense ADC Registers */ +#define ANA_TOP_IVSENSE_ADC_MODE_CTL2 0x80ca +#define ANA_TOP_IVSENSE_ADC_MODE_CTL3 0x80cb +#define ANA_TOP_IVSENSE_ADC_REF_CTL 0x80cc +#define ANA_TOP_IVSENSE_ADC_CDAC_CAL_CTL2 0x80d0 + +/* Analog Speaker Power Stage Registers */ +#define ANA_TOP_SPK_TOP_PWRSTG_CH1_CTRL3 0x8108 +#define ANA_TOP_SPK_TOP_PWRSTG_CH1_TUNE3 0x810b +#define ANA_TOP_SPK_TOP_PWRSTG_CH2_CTRL3 0x810e +#define ANA_TOP_SPK_TOP_PWRSTG_CH2_TUNE3 0x8111 +#define ANA_TOP_SPK_TOP_SPARE3 0x813c +#define SPK_TOP_LF_CH1_CTRL11 0x811c +#define SPK_TOP_LF_CH1_TUNE1 0x811d +#define SPK_TOP_LF_CH2_TUNE1 0x8129 +#define SPK_TOP_LF_CH1_CTRL9 0x811a +#define SPK_TOP_LF_CH2_CTRL9 0x8126 +#define SPK_TOP_LF_CH2_CTRL11 0x8128 +#define SPK_TOP_COMMON_CTRL2 0x8102 +#define SPK_TOP_COMMON_TUNE1 0x8103 +#define IVSENSE_VSNS_ISNS_CTL_CH1 0x80ba +#define DIG_CTRL0_CDC_CLK_CTL 0x841c +#define PON_CKSK_CTL_0 0x800d +#define DIG_CTRL0_TOP_CLK_CFG 0x8418 +#define DIG_CTRL0_SDCA_COMMIT 0x8419 +#define DIG_CTRL0_CLK_SOURCE_ENABLE 0x841a +#define DIG_CTRL0_SYS_CLK_SEL 0x841b +#define DIG_CTRL0_CDC_CLK_CTL 0x841c +#define DIG_CTRL0_PA_FSM_CTL 0x8420 +#define DIG_CTRL0_POWER_FSM_CTL0 0x8423 +#define DIG_CTRL0_POWER_FSM_CTL1 0x8424 +#define DIG_CTRL0_PA0_FSM_CTL1 0x842b +#define DIG_CTRL0_PA1_FSM_CTL1 0x8435 +#define DIG_CTRL0_VBAT_THRM_FLT_CTL 0x8458 +#define DIG_CTRL0_CDC_RXTX_FSCNT_CTL 0x8470 +#define DIG_CTRL0_GAIN_RAMP0_CTL1 0x84b4 +#define DIG_CTRL0_GAIN_RAMP1_CTL1 0x84b7 + +/* Digital Control 1 Registers - I2S/TDM Interface */ +#define DIG_CTRL1_I2S_CTL0 0x85A0 +#define DIG_CTRL1_I2S_CFG0_TDM_TX 0x85A2 +#define DIG_CTRL1_I2S_CFG1_TDM_TX 0x85A3 +#define DIG_CTRL1_I2S_TDM_CTL0 0x85A7 +#define DIG_CTRL1_I2S_TDM_CTL1 0x85A9 +#define DIG_CTRL1_I2S_TDM_CH_RX 0x85AA +#define DIG_CTRL1_I2S_TDM_CH_TX 0x85AB +#define DIG_CTRL1_I2S_RESET_CTL 0x85AE + +/* CDC RX Path Registers - Audio Data Path */ +#define CDC_RX0_RX_PATH_CFG0 0x8601 +#define CDC_RX0_RX_PATH_CFG1 0x8602 +#define CDC_RX0_RX_PATH_CTL 0x8606 +#define RX0_RX_PATH_DSMDEM_CTL 0x8613 +#define CDC_RX1_RX_PATH_CFG0 0x8621 +#define CDC_RX1_RX_PATH_CFG1 0x8622 +#define CDC_RX1_RX_PATH_CTL 0x8626 +#define RX1_RX_PATH_DSMDEM_CTL 0x8633 + +/* CDC Compander Registers - Dynamic Range Control */ +#define CDC_COMPANDER0_CTL0 0x8640 +#define CDC_COMPANDER0_CTL7 0x8647 +#define CDC_COMPANDER1_CTL0 0x8660 +#define CDC_COMPANDER1_CTL7 0x8667 + +/* CDC Speaker Protection Registers - IV Sense */ +#define CDC_VSENSE0_SPKR_PROT_PATH_CTL 0x86A1 +#define CDC_VSENSE1_SPKR_PROT_PATH_CTL 0x86B1 +#define CDC_ISENSE0_SPKR_PROT_PATH_CTL 0x86A9 +#define CDC_ISENSE1_SPKR_PROT_PATH_CTL 0x86B9 + +/* CDC Class-H Registers - Headroom Control */ +#define CDC_CLSH_V1P8_BP_CTL1 0x86CD +#define CDC_CLSH_V1P8_BP_CTL0 0x86CC +#define CDC_CLSH_CLSH_SIG_DP_CTL0 0x86C7 +#define CDC_CLSH_CLSH_V_HD_PA 0x86C3 +#define CDC_CLSH_V1P8_BP_CTL2 0x86CE + +/* RX Sample Rate Index Values - Audio Playback Path */ +#define WSA885X_RX_RATE_8000HZ 0x00 /* 8 kHz sample rate */ +#define WSA885X_RX_RATE_16000HZ 0x01 /* 16 kHz sample rate */ +#define WSA885X_RX_RATE_32000HZ 0x02 /* 32 kHz sample rate */ +#define WSA885X_RX_RATE_44100HZ 0x03 /* 44.1 kHz sample rate */ +#define WSA885X_RX_RATE_48000HZ 0x04 /* 48 kHz sample rate */ +#define WSA885X_RX_RATE_96000HZ 0x05 /* 96 kHz sample rate */ +#define WSA885X_RX_RATE_192000HZ 0x06 /* 192 kHz sample rate */ +#define WSA885X_RX_RATE_384000HZ 0x07 /* 384 kHz sample rate */ + +/* VI Sample Rate Index Values - Voltage/Current Sensing Path */ +#define WSA885X_VI_RATE_8000HZ 0x00 /* 8 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_16000HZ 0x01 /* 16 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_44100HZ 0x02 /* 44.1 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_48000HZ 0x03 /* 48 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_96000HZ 0x04 /* 96 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_22050HZ 0x05 /* 22.05 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_24000HZ 0x06 /* 24 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_192000HZ 0x07 /* 192 kHz sample rate for VI sensing */ +#define WSA885X_VI_RATE_384000HZ 0x08 /* 384 kHz sample rate for VI sensing */ + +/* Channel Configuration Masks */ +#define WSA885X_CHANNEL_STEREO 0x03 /* Both left and right channels (0b11) */ +#define WSA885X_CHANNEL_MONO_LEFT 0x01 /* Left channel only (0b01) */ +#define WSA885X_CHANNEL_MONO_RIGHT 0x02 /* Right channel only (0b10) */ + +/* PLL Status Register Bits */ +#define WSA885X_PLL_LOCK_BIT 0x01 /* PLL lock status bit (bit 0) */ + +/* FU21 volume support */ +#define FU21_VOL_STEPS 124 +static const DECLARE_TLV_DB_SCALE(fu21_digital_gain, -8400, 100, 0); + +static const char *const supply_name[] = { + "vdd-io", + "vdd-1p8", +}; + +enum { + batt_1s = 1, + batt_2s, +}; + +enum { + WSA885X_IRQ_INT_SAF2WAR = 0, + WSA885X_IRQ_INT_WAR2SAF, + WSA885X_IRQ_INT_DISABLE, + WSA885X_IRQ_INT_PA0_OCP, + WSA885X_IRQ_INT_PA1_OCP, + WSA885X_IRQ_INT_CLIP0, + WSA885X_IRQ_INT_CLIP1, + WSA885X_IRQ_INT_CLK_WD, + WSA885X_IRQ_INT_INTR_GPIO1_PIN, + WSA885X_IRQ_INT_INTR_GPIO2_PIN, + WSA885X_IRQ_INT_UVLO, + WSA885X_IRQ_INT_BOP, + WSA885X_IRQ_INT_PA0_FSM_ERR, + WSA885X_IRQ_INT_PA1_FSM_ERR, + WSA885X_IRQ_INT_MAIN_FSM_ERR, + WSA885X_IRQ_INT_PCM_DATA0_WD, + WSA885X_IRQ_INT_PCM_DATA1_WD, + WSA885X_IRQ_INT_PCM_DATA0_DC, + WSA885X_IRQ_INT_PCM_DATA1_DC, + WSA885X_IRQ_INT_PLL_UNLOCKED, + WSA885X_IRQ_INT_PROT_MODE_CHANGE, + WSA885X_IRQ_INT_PB_CLOCK_VALID, + WSA885X_IRQ_INT_SENSE_CLOCK_VALID, + WSA885X_IRQ_MAX, +}; + +static const char *wsa885x_irq_names[WSA885X_IRQ_MAX] = { + "WSA885X_IRQ_INT_SAF2WAR", + "WSA885X_IRQ_INT_WAR2SAF", + "WSA885X_IRQ_INT_DISABLE", + "WSA885X_IRQ_INT_PA0_OCP", + "WSA885X_IRQ_INT_PA1_OCP", + "WSA885X_IRQ_INT_CLIP0", + "WSA885X_IRQ_INT_CLIP1", + "WSA885X_IRQ_INT_CLK_WD", + "WSA885X_IRQ_INT_INTR_GPIO1_PIN", + "WSA885X_IRQ_INT_INTR_GPIO2_PIN", + "WSA885X_IRQ_INT_UVLO", + "WSA885X_IRQ_INT_BOP", + "WSA885X_IRQ_INT_PA0_FSM_ERR", + "WSA885X_IRQ_INT_PA1_FSM_ERR", + "WSA885X_IRQ_INT_MAIN_FSM_ERR", + "WSA885X_IRQ_INT_PCM_DATA0_WD", + "WSA885X_IRQ_INT_PCM_DATA1_WD", + "WSA885X_IRQ_INT_PCM_DATA0_DC", + "WSA885X_IRQ_INT_PCM_DATA1_DC", + "WSA885X_IRQ_INT_PLL_UNLOCKED", + "WSA885X_IRQ_INT_PROT_MODE_CHANGE", + "WSA885X_IRQ_INT_PB_CLOCK_VALID", + "WSA885X_IRQ_INT_SENSE_CLOCK_VALID"}; + +struct wsa885x_i2c_priv { + struct i2c_client *client; + struct regmap *regmap; + struct device *dev; + struct snd_soc_component *component; + struct regulator_bulk_data supplies[SUPPLIES_NUM]; + struct gpio_desc *sd_n; + uint32_t sample_rate; + uint32_t *init_table; + uint32_t init_table_size; + uint32_t usage_mode; + uint32_t rx_slot_mask; + struct gpio_desc *intr_pin; + atomic_t open_count; + uint32_t batt_conf; + int stereo_voldB; /* in dB, -84..+40, encoded as signed 8-bit in MSB register */ +}; + +static const struct regmap_range_cfg regmap_ranges[] = { + { + .range_min = 0, + .range_max = 0x88ff, + .selector_reg = 0x0, + .selector_mask = 0xFF, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x100, + }, +}; + +static const struct reg_default codec_reg_defaults[] = { + {SMP_AMP_CTRL_STEREO_STEREO_SMP_AMP_CTRL_I2S, 0x00}, + {SMP_AMP_CTRL_STEREO_IT21_CLUSERINDEX, 0x01}, + {SMP_AMP_CTRL_STEREO_CMT_GRP_MASK, 0x00}, + {SMP_AMP_CTRL_STEREO_OT23_USAGE, 0x00}, + {SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID, 0x00}, + {SMP_AMP_CTRL_STEREO_CS21_SAMPLERATEINDEX, 0x04}, + {SMP_AMP_CTRL_STEREO_PPU21_POSTURENUMBER, 0x01}, + {SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X0, 0x01}, + {SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X1, 0x01}, + {SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_MSB, 0xac}, + {SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_LSB, 0x00}, + {SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_MSB, 0xac}, + {SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_LSB, 0x00}, + {SMP_AMP_CTRL_STEREO_PDE23_REQ_PS, 0x03}, + {SMP_AMP_CTRL_STEREO_PDE23_ACT_PS, 0x03}, + {SMP_AMP_CTRL_STEREO_OT23_USAGE, 0x00}, + {SMP_AMP_CTRL_STEREO_CS24_SAMPLERATEINDEX, 0x03}, + {SMP_AMP_CTRL_STEREO_CS24_SAMPLERATEINDEX, 0x03}, + {ANA_TOP_PON_CKSK_CTL_0, 0x00}, + {ANA_TOP_BG_TVP_UVLO1_PROG, 0x19}, + {ANA_TOP_BG_TVP_UVLO2_PROG, 0x22}, + {ANA_PLL_DIV_CTL_0, 0x0c}, + {ANA_PLL_DIV_CTL_1, 0x50}, + {ANA_TOP_PLL_VCO_CTL, 0x00}, + {ANA_TOP_PLL_LOOPFILT_0, 0xb4}, + {ANA_TOP_PLL_OVRD_CTL, 0x00}, + {ANA_TOP_BG_TVP_OVRD_CTL, 0x00}, + {ANA_TOP_BOOST_STB_CTRL2, 0x03}, + {ANA_TOP_BOOST_STB_CTRL3, 0x3c}, + {ANA_TOP_BOOST_BYP_CTRL2, 0xc5}, + {ANA_TOP_BOOST_BYP_CTRL3, 0x13}, + {ANA_TOP_BOOST_MISC, 0x79}, + {ANA_TOP_SPK_TOP_SPARE3, 0x00}, + {SPK_TOP_COMMON_CTRL2, 0x08}, + {SPK_TOP_LF_CH1_CTRL11, 0x09}, + {SPK_TOP_LF_CH1_TUNE1, 0x00}, + {SPK_TOP_LF_CH2_TUNE1, 0x00}, + {SPK_TOP_LF_CH1_CTRL9, 0x00}, + {SPK_TOP_LF_CH2_CTRL9, 0x00}, + {SPK_TOP_LF_CH2_CTRL11, 0x09}, + {SPK_TOP_COMMON_TUNE1, 0x08}, + {SPK_TOP_COMMON_TUNE1, 0x03}, + {IVSENSE_VSNS_ISNS_CTL_CH1, 0x00}, + {DIG_CTRL0_CDC_CLK_CTL, 0x0e}, + {PON_CKSK_CTL_0, 0x00}, + {ANA_TOP_BOOST_PWRSTAGE_CTRL2, 0x40}, + {ANA_TOP_BOOST_PWRSTAGE_CTRL4, 0xff}, + {ANA_TOP_PLL_STATUS_0, 0x00}, + {ANA_TOP_PLL_STATUS_1, 0x00}, + {ANA_TOP_IVSENSE_ADC_MODE_CTL2, 0x84}, + {ANA_TOP_IVSENSE_ADC_MODE_CTL3, 0x02}, + {ANA_TOP_IVSENSE_ADC_REF_CTL, 0x00}, + {ANA_TOP_IVSENSE_ADC_CDAC_CAL_CTL2, 0xe0}, + {ANA_TOP_SPK_TOP_PWRSTG_CH1_CTRL3, 0xa4}, + {ANA_TOP_SPK_TOP_PWRSTG_CH1_TUNE3, 0xc9}, + {ANA_TOP_SPK_TOP_PWRSTG_CH2_CTRL3, 0xa4}, + {ANA_TOP_SPK_TOP_PWRSTG_CH2_TUNE3, 0xc5}, + {ANA_TOP_SPK_TOP_PWRSTG_CH2_TUNE3, 0xc9}, + {DIG_CTRL0_TOP_CLK_CFG, 0x00}, + {DIG_CTRL0_SDCA_COMMIT, 0x00}, + {DIG_CTRL0_CLK_SOURCE_ENABLE, 0x00}, + {DIG_CTRL0_SYS_CLK_SEL, 0x00}, + {DIG_CTRL0_CDC_CLK_CTL, 0x0e}, + {DIG_CTRL0_PA_FSM_CTL, 0x00}, + {DIG_CTRL0_POWER_FSM_CTL0, 0x05}, + {DIG_CTRL0_POWER_FSM_CTL1, 0x00}, + {DIG_CTRL0_PA0_FSM_CTL1, 0x45}, + {DIG_CTRL0_PA1_FSM_CTL1, 0x45}, + {DIG_CTRL0_VBAT_THRM_FLT_CTL, 0x7f}, + {DIG_CTRL0_CDC_RXTX_FSCNT_CTL, 0x00}, + {DIG_CTRL0_GAIN_RAMP0_CTL1, 0x01}, + {DIG_CTRL0_GAIN_RAMP1_CTL1, 0x01}, + {DIG_CTRL1_I2S_CTL0, 0x06}, + {DIG_CTRL1_I2S_CFG0_TDM_TX, 0x00}, + {DIG_CTRL1_I2S_CFG1_TDM_TX, 0x00}, + {DIG_CTRL1_I2S_TDM_CTL0, 0x00}, + {DIG_CTRL1_I2S_TDM_CTL1, 0x05}, + {DIG_CTRL1_I2S_TDM_CH_TX, 0x00}, + {DIG_CTRL1_I2S_RESET_CTL, 0x00}, + {DIG_CTRL1_I2S_TDM_CH_RX, 0x08}, + {CDC_RX0_RX_PATH_CFG0, 0x89}, + {CDC_RX0_RX_PATH_CFG1, 0x64}, + {CDC_RX0_RX_PATH_CTL, 0x24}, + {RX0_RX_PATH_DSMDEM_CTL, 0x01}, + {CDC_RX1_RX_PATH_CFG0, 0x89}, + {CDC_RX1_RX_PATH_CFG1, 0x64}, + {CDC_RX1_RX_PATH_CTL, 0x04}, + {RX1_RX_PATH_DSMDEM_CTL, 0x01}, + {CDC_COMPANDER0_CTL0, 0x01}, + {CDC_COMPANDER0_CTL7, 0x2a}, + {CDC_COMPANDER1_CTL0, 0x01}, + {CDC_COMPANDER1_CTL7, 0x2a}, + {CDC_VSENSE0_SPKR_PROT_PATH_CTL, 0x14}, + {CDC_VSENSE1_SPKR_PROT_PATH_CTL, 0x14}, + {CDC_ISENSE0_SPKR_PROT_PATH_CTL, 0x14}, + {CDC_ISENSE1_SPKR_PROT_PATH_CTL, 0x14}, + {CDC_CLSH_V1P8_BP_CTL1, 0x50}, + {CDC_CLSH_V1P8_BP_CTL0, 0x6c}, + {CDC_CLSH_CLSH_SIG_DP_CTL0, 0x0d}, + {CDC_CLSH_CLSH_V_HD_PA, 0x03}, + {CDC_CLSH_V1P8_BP_CTL2, 0x05}, +}; + +static int wsa885x_gpio_set(struct wsa885x_i2c_priv *wsa885x, bool val) +{ + int ret = 0; + + if (val) + ret = gpiod_direction_output(wsa885x->sd_n, 1); + else + ret = gpiod_direction_output(wsa885x->sd_n, 0); + + if (ret < 0) { + dev_err_ratelimited(wsa885x->dev, "%s: failed to set GPIO: %d\n", __func__, + ret); + } + return ret; +} + +static void reg_update_sequence(struct regmap *regmap) +{ + regmap_write(regmap, DIG_CTRL1_I2S_TDM_CTL1, 0x15); + regmap_write(regmap, DIG_CTRL1_I2S_TDM_CTL1, 0x11); + + /* Configure TDM control register 0 */ + regmap_write(regmap, DIG_CTRL1_I2S_TDM_CTL0, 0x04); + regmap_update_bits(regmap, DIG_CTRL1_I2S_TDM_CTL0, 0x01, 0x01); + + /* Configure TDM transmit channel settings */ + regmap_write(regmap, DIG_CTRL1_I2S_TDM_CH_TX, 0x01); + regmap_update_bits(regmap, DIG_CTRL1_I2S_TDM_CH_TX, 0x02, 0x02); +} + +static int wait_for_pll_lock(struct wsa885x_i2c_priv *wsa885x) +{ + unsigned int status; + int cnt = 0; + int ret = 0; + + do { + usleep_range(1000, 1100); + ret = regmap_read(wsa885x->regmap, ANA_TOP_PLL_STATUS_0, &status); + + /* Check if PLL is locked (bit 0 set) */ + if (ret == 0 && (status & WSA885X_PLL_LOCK_BIT)) { + dev_dbg(wsa885x->component->dev, "PLL locked successfully after %d ms\n", + cnt + 1); + return 0; + } + } while (++cnt < 20); /* Maximum 20ms timeout */ + + /* PLL lock timeout */ + dev_warn(wsa885x->component->dev, "PLL lock timeout after 20ms, status=0x%x\n", status); + return -ETIMEDOUT; +} + +static void wsa885x_2s_conf(struct wsa885x_i2c_priv *wsa885x) +{ + regmap_write(wsa885x->regmap, SPK_TOP_COMMON_TUNE1, 0x03); + regmap_write(wsa885x->regmap, SPK_TOP_LF_CH1_CTRL11, 0x0d); + regmap_write(wsa885x->regmap, SPK_TOP_LF_CH2_CTRL11, 0x0d); + regmap_write(wsa885x->regmap, CDC_CLSH_V1P8_BP_CTL1, 0x71); + regmap_write(wsa885x->regmap, CDC_CLSH_V1P8_BP_CTL0, 0xAA); +} + +static int wait_for_pde_state(struct wsa885x_i2c_priv *wsa885x, + int ps, int reg) +{ + int act_ps, cnt = 0, clock_valid; + int rc = 0; + + /* Poll for power state transition with timeout */ + do { + usleep_range(1000, 1500); + + /* Read actual power state from PDE register */ + rc = regmap_read(wsa885x->regmap, + SMP_AMP_CTRL_STEREO_PDE23_ACT_PS, + &act_ps); + + /* Check if desired power state is reached */ + if (rc == 0 && act_ps == ps) + return 0; + } while (++cnt < 5); + + /* Read clock validity status for debugging */ + regmap_read(wsa885x->regmap, + SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID, + &clock_valid); + + dev_err(wsa885x->component->dev, + "PDE power state %d request failed, actual_ps %d, clock_valid:%d\n", + ps, act_ps, clock_valid); + + return -ETIMEDOUT; +} + +static int codec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct wsa885x_i2c_priv *wsa885x = snd_soc_component_get_drvdata(component); + uint8_t value, cs21_sample_rate_idx, cs24_sample_rate_idx; + int open_count = 0; + + dev_dbg(wsa885x->dev, "%s: HW Params called with sampling rate as %d\n", __func__, + params_rate(params)); + + /* Check if multiple streams are open - only configure on first stream */ + open_count = atomic_read(&wsa885x->open_count); + if (open_count > 1) + return 0; + + /* Extract sample rate from ALSA parameters */ + wsa885x->sample_rate = params_rate(params); + + /* Map sample rate to codec-specific rate indices */ + switch (wsa885x->sample_rate) { + case 8000: + value = 0x00; + cs21_sample_rate_idx = WSA885X_RX_RATE_8000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_8000HZ; + break; + case 16000: + value = 0x01; + cs21_sample_rate_idx = WSA885X_RX_RATE_16000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_16000HZ; + break; + case 32000: + value = 0x02; + cs21_sample_rate_idx = WSA885X_RX_RATE_32000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_48000HZ; + break; + case 44100: + value = 0x03; + cs21_sample_rate_idx = WSA885X_RX_RATE_44100HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_44100HZ; + break; + case 48000: + value = 0x03; + cs21_sample_rate_idx = WSA885X_RX_RATE_48000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_48000HZ; + break; + case 88200: + case 96000: + value = 0x04; + cs21_sample_rate_idx = WSA885X_RX_RATE_96000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_96000HZ; + break; + case 176400: + case 192000: + value = 0x05; + cs21_sample_rate_idx = WSA885X_RX_RATE_192000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_192000HZ; + break; + case 352800: + case 384000: + value = 0x06; + cs21_sample_rate_idx = WSA885X_RX_RATE_384000HZ; + cs24_sample_rate_idx = WSA885X_VI_RATE_384000HZ; + break; + default: + dev_err(component->dev, "sampling rate %d is not supported\n", + params_rate(params)); + return -EINVAL; + } + + /* Configure I2S control register with sample rate (bits 1:4) and enable bit */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CTL0, 0x1f, + (value << 1) + 1); + + /* Reset I2S interface */ + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_RESET_CTL, 0x00); + + /* Set RX (playback) sample rate index */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_CS21_SAMPLERATEINDEX, + cs21_sample_rate_idx); + + /* Set VI (voltage/current sensing) sample rate index */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_CS24_SAMPLERATEINDEX, + cs24_sample_rate_idx); + + /* Program FU21 volume with current dB value (MSB) and zero LSB, then commit */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_MSB, wsa885x->stereo_voldB); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_LSB, 0x00); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_MSB, wsa885x->stereo_voldB); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_LSB, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL0_SDCA_COMMIT, 0x01); + + return 0; +} + +static int codec_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_slot_mask, + unsigned int rx_slot_mask, int slots, + int slot_width) +{ + struct snd_soc_component *component = dai->component; + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + + dev_dbg(wsa885x->dev, "%s: TDM num_slots configured as %d\n", __func__, slots); + + /* Increment open count atomically - only configure on first call */ + if (atomic_inc_return(&wsa885x->open_count) > 1) + return 0; + + /* Reset I2S interface before configuration */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_RESET_CTL, 0x01, 0x01); + + /* Configure TDM slots based on channel mask */ + if (wsa885x->rx_slot_mask == WSA885X_CHANNEL_STEREO) { + /* Stereo configuration - both channels active */ + /* Configure slot0 for I-sense channel 0 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x01, 0x01); + /* Configure slot1 for I-sense channel 1 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x20, 0x20); + /* Configure slot3 for current protection sense 0 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG1_TDM_TX, + 0x05, 0x05); + /* Configure slot4 for current protection sense 1 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG1_TDM_TX, + 0x60, 0x60); + /* Apply TDM control sequence */ + reg_update_sequence(wsa885x->regmap); + /* Enable transmit channels */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CH_TX, + 0x04, 0x04); + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CH_TX, + 0x08, 0x08); + } else if (wsa885x->rx_slot_mask == WSA885X_CHANNEL_MONO_LEFT) { + /* Mono left channel configuration */ + /* Configure slot0 for I-sense channel 0 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x01, 0x01); + /* Configure slot1 for current protection sense 0 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x50, 0x50); + reg_update_sequence(wsa885x->regmap); + } else if (wsa885x->rx_slot_mask == WSA885X_CHANNEL_MONO_RIGHT) { + /* Mono right channel configuration */ + /* Configure slot0 for I-sense channel 1 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x02, 0x02); + /* Configure slot1 for current protection sense 1 */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, + 0x60, 0x60); + reg_update_sequence(wsa885x->regmap); + } + + /* Enable I2S control */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_CTL0, 0x01, 0x01); + + /* Release I2S reset */ + regmap_update_bits(wsa885x->regmap, DIG_CTRL1_I2S_RESET_CTL, 0x01, 0x00); + + return 0; +} + +static int codec_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_component *component = dai->component; + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + uint8_t pll_div; + int i, open_count = 0, ret = 0; + + dev_dbg(wsa885x->dev, "%s: Freq: %d\n", __func__, freq); + + /* Check if multiple streams are open - only configure on first stream */ + open_count = atomic_read(&wsa885x->open_count); + if (open_count > 1) + return 0; + + /* Calculate PLL divider: Fixed rate / target frequency */ + pll_div = CLK_RATE_FIXED / freq; + + /* Configure analog bias and thermal/voltage protection override */ + regmap_write(wsa885x->regmap, ANA_TOP_BG_TVP_OVRD_CTL, 0x03); + + /* Select internal system clock source */ + regmap_write(wsa885x->regmap, DIG_CTRL0_SYS_CLK_SEL, 0x04); + + /* Configure PLL loop filter for stability */ + regmap_write(wsa885x->regmap, ANA_TOP_PLL_LOOPFILT_0, 0xB4); + + /* Configure VCO (Voltage Controlled Oscillator) */ + regmap_write(wsa885x->regmap, ANA_TOP_PLL_VCO_CTL, 0x00); + + /* Disable PLL override mode */ + regmap_write(wsa885x->regmap, ANA_TOP_PLL_OVRD_CTL, 0x00); + + /* Set calculated PLL divider */ + regmap_write(wsa885x->regmap, ANA_PLL_DIV_CTL_0, pll_div); + + /* Enable PLL clock source */ + regmap_write(wsa885x->regmap, DIG_CTRL0_CLK_SOURCE_ENABLE, 0x02); + + /* Wait for PLL to lock with intelligent polling */ + ret = wait_for_pll_lock(wsa885x); + if (ret) { + dev_err(wsa885x->component->dev, "PLL lock failed, aborting sysclk configuration\n"); + return ret; + } + + /* Switch to PLL as system clock source */ + regmap_write(wsa885x->regmap, DIG_CTRL0_SYS_CLK_SEL, 0x00); + + /* Enable power FSM control */ + regmap_write(wsa885x->regmap, DIG_CTRL0_POWER_FSM_CTL1, 0x01); + + /* Apply codec-specific initialization table from device tree */ + for (i = 0; i < wsa885x->init_table_size / 2; i++) { + if (wsa885x->batt_conf == batt_2s && wsa885x->init_table[2 * i] == + SPK_TOP_LF_CH1_CTRL11) + wsa885x_2s_conf(wsa885x); + else if (wsa885x->batt_conf == batt_2s && + wsa885x->init_table[2 * i] == SPK_TOP_COMMON_TUNE1) + regmap_write(wsa885x->regmap, SPK_TOP_COMMON_TUNE1, 0x26); + else + regmap_write(wsa885x->regmap, wsa885x->init_table[2 * i], + wsa885x->init_table[2 * i + 1]); + } + return 0; +} + +static int codec_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct wsa885x_i2c_priv *wsa885x = snd_soc_dai_get_drvdata(dai); + int ret = 0, ps0 = 0, ps3 = 3, open_count = 0; + + dev_dbg(wsa885x->dev, "%s: Stream is %s\n", __func__, mute ? "muted" : "unmuted"); + + if (mute) { + open_count = atomic_dec_return(&wsa885x->open_count); + if (open_count > 0) + return 0; + regmap_write(wsa885x->regmap, DIG_CTRL0_PA_FSM_CTL, 0x00); + /* Request power state 3 (low power/standby mode) */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_PDE23_REQ_PS, 0x03); + ret = wait_for_pde_state(wsa885x, ps3, SMP_AMP_CTRL_STEREO_PDE23_ACT_PS); + if (!ret) { + dev_dbg(wsa885x->component->dev, + "Successfully transitioned to power state %d\n", ps3); + } + } else { + open_count = atomic_read(&wsa885x->open_count); + if (open_count > 1) + return 0; + /* Disable power amplifier FSM before configuration */ + regmap_write(wsa885x->regmap, DIG_CTRL0_PA_FSM_CTL, 0x00); + + /* Configure usage mode for thermal/speaker protection */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_OT23_USAGE, + wsa885x->usage_mode); + + /* Set cluster index for audio processing */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_IT21_CLUSERINDEX, 0x01); + + /* Set posture number for speaker configuration */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_PPU21_POSTURENUMBER, 0x01); + + /* Apply requested volume */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_MSB, wsa885x->stereo_voldB); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X0_LSB, 0x00); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_MSB, wsa885x->stereo_voldB); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_CH_VOL_CH2X1_LSB, 0x00); + + regmap_write(wsa885x->regmap, DIG_CTRL0_SDCA_COMMIT, 0x01); + + /* Request power state 0 (active mode) */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_PDE23_REQ_PS, 0x00); + ret = wait_for_pde_state(wsa885x, ps0, SMP_AMP_CTRL_STEREO_PDE23_ACT_PS); + if (!ret) { + dev_dbg(wsa885x->component->dev, + "Successfully transitioned to power state %d\n", ps0); + } else { + dev_err(wsa885x->component->dev, "PS0 request failed\n"); + goto exit; + } + + /* Configure power amplifier based on channel configuration */ + if (wsa885x->rx_slot_mask == 0b11) { + /* Stereo mode - enable both PA channels */ + regmap_write(wsa885x->regmap, DIG_CTRL0_PA_FSM_CTL, 0x03); + } else if (wsa885x->rx_slot_mask == 0b01) { + /* Mono left channel */ + regmap_write(wsa885x->regmap, DIG_CTRL0_PA_FSM_CTL, 0x01); + } else if (wsa885x->rx_slot_mask == 0b10) { + /* Mono right channel */ + regmap_write(wsa885x->regmap, DIG_CTRL0_PA_FSM_CTL, 0b10); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CH_RX, 0b01); + } + + /* Unmute both channels */ + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X0, 0x00); + regmap_write(wsa885x->regmap, SMP_AMP_CTRL_STEREO_FU21_MUTE_CH2X1, 0x00); + + /* Commit all changes */ + regmap_write(wsa885x->regmap, DIG_CTRL0_SDCA_COMMIT, 0x01); + } +exit: + return ret; +} + +static int codec_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + int open_count = 0; + + dev_dbg(wsa885x->dev, "%s: HW Free, resetting I2S registers\n", __func__); + + open_count = atomic_read(&wsa885x->open_count); + if (open_count > 0) + return 0; + + /* Reset I2S register in any case */ + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_RESET_CTL, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_CFG0_TDM_TX, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_CFG1_TDM_TX, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CTL1, 0x05); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CTL0, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CH_TX, 0x00); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_CTL0, 0x06); + regmap_write(wsa885x->regmap, DIG_CTRL1_I2S_TDM_CH_RX, 0x08); + + /* Reset Clock */ + regmap_write(wsa885x->regmap, DIG_CTRL0_CLK_SOURCE_ENABLE, 0x00); + regmap_write(wsa885x->regmap, ANA_TOP_BG_TVP_OVRD_CTL, 0x00); + + return 0; +} + +static const struct snd_soc_dai_ops wsa885x_i2c_dai_ops = { + .hw_params = codec_hw_params, + .set_tdm_slot = codec_set_tdm_slot, + .set_sysclk = codec_set_sysclk, + .mute_stream = codec_mute_stream, + .hw_free = codec_hw_free, +}; + +static struct snd_soc_dai_driver wsa885x_i2c_dai[] = { + { + .name = "wsa885x_dai_drv", + .playback = { + .stream_name = "WSA885X I2C TDM Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &wsa885x_i2c_dai_ops, + }, +}; + +static void wsa885x_gpio_powerdown(void *data) +{ + gpiod_direction_output(data, 1); +} + +static bool wsa885x_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ANA_TOP_PLL_STATUS_0: + case ANA_TOP_PLL_STATUS_1: + case SMP_AMP_CTRL_STEREO_PDE23_ACT_PS: + case SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID: + case WSA885X_INTR_STATUS0: + case WSA885X_INTR_STATUS0 + 1: + case WSA885X_INTR_STATUS0 + 2: + case WSA885X_INTR_CLEAR0: + case WSA885X_INTR_CLEAR0 + 1: + case WSA885X_INTR_CLEAR0 + 2: + return true; + default: + return false; + } +} + +static bool wsa885x_readable_register(struct device *dev, unsigned int reg) +{ + if (reg >= 0 && reg <= 0x88ff) + return true; + return false; +} + +static bool wsa885x_writeable_register(struct device *dev, unsigned int reg) +{ + if (reg >= 0 && reg <= 0x88ff) { + /* Read-only status registers */ + if (reg == ANA_TOP_PLL_STATUS_0 || + reg == WSA885X_INTR_STATUS0 || + reg == WSA885X_INTR_STATUS0 + 1 || + reg == WSA885X_INTR_STATUS0 + 2 || + reg == SMP_AMP_CTRL_STEREO_PDE23_ACT_PS || + reg == SMP_AMP_CTRL_STEREO_CS21_CLOCK_VALID) + return false; + return true; + } + return false; +} + +static const struct regmap_config regmap_cfg = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x88FF, + .ranges = regmap_ranges, + .num_ranges = ARRAY_SIZE(regmap_ranges), + .reg_defaults = codec_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(codec_reg_defaults), + .volatile_reg = wsa885x_volatile_register, + .writeable_reg = wsa885x_writeable_register, + .readable_reg = wsa885x_readable_register, + .cache_type = REGCACHE_MAPLE, + .use_single_read = true, + .use_single_write = true, +}; + +static int wsa885x_component_probe(struct snd_soc_component *component) +{ + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + wsa885x->component = component; + snd_soc_component_init_regmap(component, wsa885x->regmap); + /* Enable interrupts */ + regmap_write(wsa885x->regmap, DIG_CTRL1_SPMI_PAD_GPIO2_CTL, 0x2e); + regmap_write(wsa885x->regmap, DIG_CTRL1_INTR_MODE, 0x01); + regmap_write(wsa885x->regmap, DIG_CTRL1_PIN_CT, 0x04); + regmap_write(wsa885x->regmap, WSA885X_INTR_MASK0, 0x00); + regmap_write(wsa885x->regmap, WSA885X_INTR_MASK0 + 1, 0x00); + regmap_write(wsa885x->regmap, WSA885X_INTR_MASK0 + 2, 0xf8); + + return 0; +} + +static void wsa885x_component_remove(struct snd_soc_component *component) +{ + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + + if (!wsa885x) + return; + + snd_soc_component_exit_regmap(component); +} + +static void wsa885x_regulator_disable(void *data) +{ + regulator_bulk_disable(SUPPLIES_NUM, data); +} + +static int wsa885x_stereo_gain_offset_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + + /* UI range 0..124 maps to dB = value - 84; return slider value */ + ucontrol->value.integer.value[0] = wsa885x->stereo_voldB + 84; + return 0; +} + +static int wsa885x_stereo_gain_offset_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x = + snd_soc_component_get_drvdata(component); + long val = ucontrol->value.integer.value[0]; + + if (val < 0 || val > FU21_VOL_STEPS) { + dev_err(component->dev, "%s: Invalid range, Val: %ld\n", __func__, val); + return -EINVAL; + } + wsa885x->stereo_voldB = (int)val - 84; + dev_dbg(component->dev, "%s: Volume dB: %d\n", __func__, wsa885x->stereo_voldB); + return 0; +} + +static int wsa885x_i2c_usage_modes_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x_i2c = + snd_soc_component_get_drvdata(component); + + if (!wsa885x_i2c) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa885x_i2c->usage_mode; + + return 0; +} + +static int wsa885x_i2c_usage_modes_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x_i2c = + snd_soc_component_get_drvdata(component); + + if (!wsa885x_i2c) + return -EINVAL; + + wsa885x_i2c->usage_mode = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s: Usage mode:%d\n", __func__, + wsa885x_i2c->usage_mode); + + return 0; +} + +static int wsa885x_i2c_rx_slot_mask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x_i2c = + snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = wsa885x_i2c->rx_slot_mask; + + return 0; +} + +static int wsa885x_i2c_rx_slot_mask_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct wsa885x_i2c_priv *wsa885x_i2c = + snd_soc_component_get_drvdata(component); + + wsa885x_i2c->rx_slot_mask = ucontrol->value.enumerated.item[0]; + + dev_dbg(component->dev, "%s: Rx channel:%d select\n", __func__, + wsa885x_i2c->rx_slot_mask); + return 0; +} + +static const struct snd_kcontrol_new wsa885x_snd_controls[] = { + SOC_SINGLE_EXT("OT23 Usage Mode", SND_SOC_NOPM, 0, 8, 0, + wsa885x_i2c_usage_modes_get, + wsa885x_i2c_usage_modes_put), + + SOC_SINGLE_EXT_TLV("SA1 FU21 Stereo Gain Offset dB", SND_SOC_NOPM, + 0, FU21_VOL_STEPS, 0, + wsa885x_stereo_gain_offset_get, + wsa885x_stereo_gain_offset_put, + fu21_digital_gain), + + SOC_SINGLE_EXT("Rx Slot Mask", SND_SOC_NOPM, 0, 4, 0, + wsa885x_i2c_rx_slot_mask_get, + wsa885x_i2c_rx_slot_mask_put), +}; + +static const struct snd_soc_component_driver wsa885x_i2c_component = { + .name = "wsa885x-i2c", + .probe = wsa885x_component_probe, + .remove = wsa885x_component_remove, + .controls = wsa885x_snd_controls, + .num_controls = ARRAY_SIZE(wsa885x_snd_controls), + .dapm_widgets = NULL, + .num_dapm_widgets = 0, + .dapm_routes = NULL, + .num_dapm_routes = 0, +}; + +static irqreturn_t handle_wsa885x_i2c_irq(int irq, void *data) +{ + struct wsa885x_i2c_priv *wsa885x = data; + + /* Handle the interrupt based on the IRQ number */ + switch (irq) { + case WSA885X_IRQ_INT_SAF2WAR: + case WSA885X_IRQ_INT_WAR2SAF: + case WSA885X_IRQ_INT_PA0_OCP: + case WSA885X_IRQ_INT_PA1_OCP: + case WSA885X_IRQ_INT_CLIP0: + case WSA885X_IRQ_INT_CLIP1: + case WSA885X_IRQ_INT_CLK_WD: + case WSA885X_IRQ_INT_BOP: + case WSA885X_IRQ_INT_UVLO: + case WSA885X_IRQ_INT_PCM_DATA0_DC: + case WSA885X_IRQ_INT_PCM_DATA1_DC: + case WSA885X_IRQ_INT_PLL_UNLOCKED: + case WSA885X_IRQ_INT_PROT_MODE_CHANGE: + case WSA885X_IRQ_INT_PB_CLOCK_VALID: + case WSA885X_IRQ_INT_SENSE_CLOCK_VALID: + break; + case WSA885X_IRQ_INT_PCM_DATA0_WD: + case WSA885X_IRQ_INT_PCM_DATA1_WD: + if (!wsa885x) + return IRQ_NONE; + if (irq == WSA885X_IRQ_INT_PCM_DATA0_WD) { + regmap_update_bits(wsa885x->regmap, 0x84A0, + 0x04, 0x00); + regmap_update_bits(wsa885x->regmap, 0x84A0, + 0x04, 0x01); + } else { + regmap_update_bits(wsa885x->regmap, 0x84A4, + 0x04, 0x00); + regmap_update_bits(wsa885x->regmap, 0x84A4, + 0x04, 0x01); + } + break; + case WSA885X_IRQ_INT_PA0_FSM_ERR: + case WSA885X_IRQ_INT_PA1_FSM_ERR: + case WSA885X_IRQ_INT_MAIN_FSM_ERR: + if (!wsa885x) + return IRQ_NONE; + + if (irq == WSA885X_IRQ_INT_MAIN_FSM_ERR) { + regmap_update_bits(wsa885x->regmap, WSA885X_POWER_FSM_CTL0, + 0x08, 0x00); + regmap_update_bits(wsa885x->regmap, WSA885X_POWER_FSM_CTL0, + 0x08, 0x08); + regmap_update_bits(wsa885x->regmap, WSA885X_POWER_FSM_CTL0, + 0x08, 0x00); + } else if (irq == WSA885X_IRQ_INT_PA0_FSM_ERR) { + regmap_update_bits(wsa885x->regmap, WSA885X_PA0_FSM_CTL0, + 0x04, 0x00); + regmap_update_bits(wsa885x->regmap, WSA885X_PA0_FSM_CTL0, + 0x04, 0x04); + regmap_update_bits(wsa885x->regmap, WSA885X_PA0_FSM_CTL0, + 0x04, 0x00); + } else if (irq == WSA885X_IRQ_INT_PA1_FSM_ERR) { + regmap_update_bits(wsa885x->regmap, WSA885X_PA1_FSM_CTL0, + 0x04, 0x00); + regmap_update_bits(wsa885x->regmap, WSA885X_PA1_FSM_CTL0, + 0x04, 0x04); + regmap_update_bits(wsa885x->regmap, WSA885X_PA1_FSM_CTL0, + 0x04, 0x00); + } + break; + default: + dev_warn(wsa885x->dev, "Unhandled IRQ: %d\n", irq); + return IRQ_NONE; + } + + pr_err_ratelimited("%s: handled %s interrupt\n", __func__, + wsa885x_irq_names[irq]); + + return IRQ_HANDLED; +} + +static irqreturn_t wsa885x_interrupt_handler(int irq, void *data) +{ + unsigned int status[NUM_REGS]; + int i, bit, ret = IRQ_NONE; + int irq_num; + struct wsa885x_i2c_priv *wsa885x = data; + int status_reg[NUM_REGS] = { + WSA885X_INTR_STATUS0, + WSA885X_INTR_STATUS0 + 1, + WSA885X_INTR_STATUS0 + 2 + }; + int clear_reg[NUM_REGS] = { + WSA885X_INTR_CLEAR0, + WSA885X_INTR_CLEAR0 + 1, + WSA885X_INTR_CLEAR0 + 2 + }; + + pr_debug("%s: interrupt for irq = %d triggered\n", __func__, irq); + /* Read all status registers */ + for (i = 0; i < NUM_REGS; i++) { + ret = regmap_read(wsa885x->regmap, status_reg[i], &status[i]); + if (ret) { + dev_err(wsa885x->dev, "Failed to read status_reg[%d] (0x%x): %d\n", + i, status_reg[i], ret); + return IRQ_NONE; + } + } + + for (i = 0; i < NUM_REGS; i++) { + for (bit = 0; bit < 8; bit++) { + if (status[i] & (1 << bit)) { + irq_num = i * 8 + bit; + ret = handle_wsa885x_i2c_irq(irq_num, wsa885x); + /* Clear the interrupt by writing 1 to the bit */ + regmap_update_bits(wsa885x->regmap, + clear_reg[i], + (1 << bit), + (1 << bit)); + /* Optionally clear again to 0 if needed */ + regmap_update_bits(wsa885x->regmap, + clear_reg[i], + (1 << bit), 0); + } + } + } + return ret; +} + +static int wsa885x_register_irq(struct wsa885x_i2c_priv *wsa885x) +{ + int ret; + + /* Get the IRQ number for the GPIO */ + int irq_number = gpiod_to_irq(wsa885x->intr_pin); + + if (irq_number < 0) { + pr_err("Failed to get IRQ number\n"); + gpiod_put(wsa885x->intr_pin); + return irq_number; + } + + ret = devm_request_threaded_irq(wsa885x->dev, irq_number, NULL, + wsa885x_interrupt_handler, + IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_FALLING, "WSA885X I2C Interrupt", + wsa885x); + if (ret) { + dev_err(wsa885x->dev, "Failed to request IRQ for wsa885x i2c\n"); + gpiod_put(wsa885x->intr_pin); + return ret; + } + return ret; +} + +static int wsa885x_i2c_probe(struct i2c_client *client) +{ + struct wsa885x_i2c_priv *wsa885x; + const char *init_table_prop = "wsa885x-init-table"; + int ret, i; + struct device *dev = &client->dev; + + wsa885x = devm_kzalloc(&client->dev, sizeof(struct wsa885x_i2c_priv), + GFP_KERNEL); + if (!wsa885x) + return -ENOMEM; + + wsa885x->client = client; + wsa885x->dev = dev; + wsa885x->stereo_voldB = -84; + wsa885x->regmap = devm_regmap_init_i2c(client, ®map_cfg); + atomic_set(&wsa885x->open_count, 0); + + if (IS_ERR(wsa885x->regmap)) + return PTR_ERR(wsa885x->regmap); + + wsa885x->init_table_size = + of_property_count_u32_elems(dev->of_node, init_table_prop); + + if (wsa885x->init_table_size <= 0) { + dev_err(dev, "%s: Failed to count elements from %s\n", + __func__, init_table_prop); + return -EINVAL; + } + + if (wsa885x->init_table_size % 2 != 0) { + dev_err(dev, "%s: Invalid number of elements in %s\n", + __func__, init_table_prop); + return -EINVAL; + } + + wsa885x->init_table = devm_kzalloc( + dev, wsa885x->init_table_size * sizeof(u32), GFP_KERNEL); + if (!wsa885x->init_table) + return -ENOMEM; + + if (of_property_read_u32_array(dev->of_node, init_table_prop, + wsa885x->init_table, + wsa885x->init_table_size)) { + dev_err(dev, + "%s: Failed to read %s\n", + __func__, init_table_prop); + return -EINVAL; + } + + ret = of_property_read_u32(dev->of_node, "qcom,battery_config", &wsa885x->batt_conf); + if (ret) { + dev_err(dev, "battery_config not specified, 1S is default: %d\n", ret); + wsa885x->batt_conf = batt_1s; + } + + for (i = 0; i < SUPPLIES_NUM; i++) + wsa885x->supplies[i].supply = supply_name[i]; + + ret = devm_regulator_bulk_get(dev, SUPPLIES_NUM, wsa885x->supplies); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ret = regulator_bulk_enable(SUPPLIES_NUM, wsa885x->supplies); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable regulators\n"); + + ret = devm_add_action_or_reset(dev, wsa885x_regulator_disable, + wsa885x->supplies); + if (ret) { + dev_err(dev, "failed to devm_add_action_or_reset, %d\n", ret); + return ret; + } + + wsa885x->sd_n = + devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH); + if (IS_ERR(wsa885x->sd_n)) + return dev_err_probe(dev, PTR_ERR(wsa885x->sd_n), + "Shutdown Control GPIO not found\n"); + + ret = wsa885x_gpio_set(wsa885x, false); + if (ret != 0) + return ret; + + ret = devm_add_action_or_reset(dev, wsa885x_gpio_powerdown, + wsa885x->sd_n); + if (ret) { + dev_err(dev, "failed to devm_add_action_or_reset, %d\n", ret); + return ret; + } + + ret = devm_snd_soc_register_component(dev, &wsa885x_i2c_component, wsa885x_i2c_dai, + ARRAY_SIZE(wsa885x_i2c_dai)); + if (ret) { + dev_err(dev, "Codec component registration failed\n"); + } else { + dev_dbg(dev, "Codec component:dai %s registration success!\n", + wsa885x_i2c_dai[0].name); + } + + i2c_set_clientdata(client, wsa885x); + + wsa885x->intr_pin = devm_gpiod_get_optional(dev, "interrupt", GPIOD_IN); + if (IS_ERR(wsa885x->intr_pin)) { + ret = PTR_ERR(wsa885x->intr_pin); + dev_err(dev, "Failed to get interrupt pin, %d\n", ret); + return ret; + } + + ret = wsa885x_register_irq(wsa885x); + if (ret) + dev_err(dev, "wsa885x irq registration failed ret: %d\n", ret); + + return ret; +} + +static const struct of_device_id wsa885x_i2c_dt_match[] = { + { + .compatible = "qcom,wsa885x-i2c", + }, + {}}; + +static const struct i2c_device_id wsa885x_id_i2c[] = { + {"wsa885x_i2c", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, wsa885x_id_i2c); + +static struct i2c_driver i2c_slave_driver = { + .driver = { + .name = "wsa885x_i2c", + .of_match_table = wsa885x_i2c_dt_match, + }, + .probe = wsa885x_i2c_probe, + .id_table = wsa885x_id_i2c, +}; + +module_i2c_driver(i2c_slave_driver); + +MODULE_DESCRIPTION("ASoC WSA8855-I2C Smart PA Codec Driver"); +MODULE_LICENSE("GPL"); From 74e831cd3e38548fb1916c0fb41cc78649de7ad5 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Mon, 11 May 2026 12:07:27 +0530 Subject: [PATCH 105/128] arm64: defconfig: Enable WSA885X-I2C and PM4125 Shikra EVK boards Signed-off-by: Mohammad Rafi Shaik --- arch/arm64/configs/defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 82cb75aa37033..f9e0583a83322 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1107,6 +1107,8 @@ CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_MESON_GX_SOUND_CARD=m CONFIG_SND_SOC_QCOM=m CONFIG_SND_SOC_APQ8016_SBC=m +CONFIG_SND_SOC_PM4125=m +CONFIG_SND_SOC_PM4125_SDW=m CONFIG_SND_SOC_QDSP6_USB=m CONFIG_SND_SOC_MSM8996=m CONFIG_SND_SOC_SDM845=m @@ -1188,6 +1190,7 @@ CONFIG_SND_SOC_WM8978=m CONFIG_SND_SOC_WSA881X=m CONFIG_SND_SOC_WSA883X=m CONFIG_SND_SOC_WSA884X=m +CONFIG_SND_SOC_WSA885X_I2C=m CONFIG_SND_SOC_NAU8822=m CONFIG_SND_SOC_LPASS_WSA_MACRO=m CONFIG_SND_SOC_LPASS_VA_MACRO=m From f60180667ca3594d0e630c1d75d404a602720fc1 Mon Sep 17 00:00:00 2001 From: Anandu Krishnan E Date: Thu, 14 May 2026 18:00:08 +0530 Subject: [PATCH 106/128] misc: fastrpc: fix NULL dereference on coherent sessions in fastrpc_map_attach() Commit c7d8100749c6 introduced a brace-less if that skips the dma_buf_map_attachment_unlocked() call when sess->coherent is true, leaving 'table' uninitialized. The unconditional IS_ERR(table) check that follows does not catch NULL, so execution continues with a NULL sg_table, causing a level-0 translation fault when the sgl pointer is dereferenced. Remove the guard; the mapping is always needed to obtain DMA addresses consumed by the rest of the function. Signed-off-by: Anandu Krishnan E --- drivers/misc/fastrpc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index bd30d816b24ee..30792d398f0e5 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -826,7 +826,6 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, err = PTR_ERR(map->attach); goto attach_err; } - if (!sess->coherent) table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); if (IS_ERR(table)) { err = PTR_ERR(table); From 5d43f538525d5e04f7a8d31fb021a67c4022b46a Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 11 May 2026 16:30:00 +0530 Subject: [PATCH 107/128] dt-bindings: regulator: qcom,usb-vbus-regulator: add qcom,pm4125-vbus-reg The pm4125 PMIC uses a different USB VBUS register layout than pm8150b. It uses a 2-bit VBOOST voltage selector supporting output voltages of 4.25 V, 4.5 V, 4.75 V and 5.0 V, instead of a current-limit selector. Move qcom,pm4125-vbus-reg from the pm8150b fallback items list into the standalone enum since the driver handles it with its own match-data and register layout. Make regulator-min/max-microamp conditional so they are only required for current-limit variants (pm8150b, pm6150, pm7250b, pmi632). Add an if/then condition for qcom,pm4125-vbus-reg requiring regulator-min/ max-microvolt instead, and update the pm4125 example accordingly. Signed-off-by: Rakesh Kota --- .../regulator/qcom,usb-vbus-regulator.yaml | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml index fcefc722ee2a4..d34b378517378 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml @@ -14,6 +14,13 @@ description: | regulator will be enabled in situations where the device is required to provide power to the connected peripheral. + The pm8150b variant uses an OTG current-limit selector, supporting limits + of 500 mA, 1000 mA, 1500 mA, 2000 mA, 2500 mA and 3000 mA. + + The pm4125 variant uses a different register layout with a 2-bit VBOOST + voltage selector supporting output voltages of 4.25 V, 4.5 V, 4.75 V + and 5.0 V. + allOf: - $ref: regulator.yaml# @@ -22,9 +29,9 @@ properties: oneOf: - enum: - qcom,pm8150b-vbus-reg + - qcom,pm4125-vbus-reg - items: - enum: - - qcom,pm4125-vbus-reg - qcom,pm6150-vbus-reg - qcom,pm7250b-vbus-reg - qcom,pmi632-vbus-reg @@ -34,11 +41,33 @@ properties: maxItems: 1 description: VBUS output base address +if: + properties: + compatible: + contains: + enum: + - qcom,pm8150b-vbus-reg + - qcom,pm6150-vbus-reg + - qcom,pm7250b-vbus-reg + - qcom,pmi632-vbus-reg +then: + required: + - regulator-min-microamp + - regulator-max-microamp + +if: + properties: + compatible: + contains: + const: qcom,pm4125-vbus-reg +then: + required: + - regulator-min-microvolt + - regulator-max-microvolt + required: - compatible - reg - - regulator-min-microamp - - regulator-max-microamp unevaluatedProperties: false @@ -55,4 +84,16 @@ examples: regulator-max-microamp = <3000000>; }; }; + - | + pmic { + #address-cells = <1>; + #size-cells = <0>; + + usb-vbus-regulator@5000 { + compatible = "qcom,pm4125-vbus-reg"; + reg = <0x1100>; + regulator-min-microvolt = <4250000>; + regulator-max-microvolt = <5000000>; + }; + }; ... From 38d628fa1fd3ff8701b05cd4aad4bdfd9b6e23da Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 11 May 2026 16:32:16 +0530 Subject: [PATCH 108/128] regulator: qcom_usb_vbus: add support for qcom,pm4125-vbus-reg The PM4125 PMIC uses a different register layout for USB VBUS control compared to PM8150B. On PM4125, CMD_OTG is at offset 0x50, OTG_CFG is at 0x56, and offset 0x52 is a 2-bit VBOOST voltage selector rather than a current-limit selector. Introduce per-compatible regulator descriptor data to accommodate these differences. This keeps the existing PM8150B current-limit logic intact while adding a dedicated voltage-selector path for PM4125. Signed-off-by: Rakesh Kota --- drivers/regulator/qcom_usb_vbus-regulator.c | 102 +++++++++++++++++--- 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index cd94ed67621fe..3d425452a0b35 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -20,10 +20,35 @@ #define OTG_CFG 0x53 #define OTG_EN_SRC_CFG BIT(1) +#define PM4125_CMD_OTG 0x50 +#define PM4125_VBOOST_CFG 0x52 +#define PM4125_VBOOST_CFG_MASK GENMASK(1, 0) +#define PM4125_OTG_CFG 0x56 +#define PM4125_OTG_EN_SRC_CFG BIT(0) + +struct qcom_usb_vbus_reg_data { + u16 cmd_otg; + u16 otg_cfg; + u8 otg_en_src_cfg; + u16 csel_reg; + u8 csel_mask; + const unsigned int *curr_table; + unsigned int n_current_limits; + u16 vsel_reg; + u8 vsel_mask; + const unsigned int *volt_table; + unsigned int n_voltages; + const struct regulator_ops *ops; +}; + static const unsigned int curr_table[] = { 500000, 1000000, 1500000, 2000000, 2500000, 3000000, }; +static const unsigned int pm4125_vboost_table[] = { + 4250000, 4500000, 4750000, 5000000, +}; + static const struct regulator_ops qcom_usb_vbus_reg_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -32,19 +57,43 @@ static const struct regulator_ops qcom_usb_vbus_reg_ops = { .set_current_limit = regulator_set_current_limit_regmap, }; -static struct regulator_desc qcom_usb_vbus_rdesc = { - .name = "usb_vbus", - .ops = &qcom_usb_vbus_reg_ops, - .owner = THIS_MODULE, - .type = REGULATOR_VOLTAGE, +static const struct regulator_ops qcom_usb_vbus_pm4125_reg_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_table, +}; + +static const struct qcom_usb_vbus_reg_data pm8150b_data = { + .cmd_otg = CMD_OTG, + .otg_cfg = OTG_CFG, + .otg_en_src_cfg = OTG_EN_SRC_CFG, + .csel_reg = OTG_CURRENT_LIMIT_CFG, + .csel_mask = OTG_CURRENT_LIMIT_MASK, .curr_table = curr_table, .n_current_limits = ARRAY_SIZE(curr_table), + .ops = &qcom_usb_vbus_reg_ops, +}; + +static const struct qcom_usb_vbus_reg_data pm4125_data = { + .cmd_otg = PM4125_CMD_OTG, + .otg_cfg = PM4125_OTG_CFG, + .otg_en_src_cfg = PM4125_OTG_EN_SRC_CFG, + .vsel_reg = PM4125_VBOOST_CFG, + .vsel_mask = PM4125_VBOOST_CFG_MASK, + .volt_table = pm4125_vboost_table, + .n_voltages = ARRAY_SIZE(pm4125_vboost_table), + .ops = &qcom_usb_vbus_pm4125_reg_ops, }; static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct qcom_usb_vbus_reg_data *data; struct regulator_dev *rdev; + struct regulator_desc *rdesc; struct regmap *regmap; struct regulator_config config = { }; struct regulator_init_data *init_data; @@ -57,27 +106,51 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) return ret; } + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + regmap = dev_get_regmap(dev->parent, NULL); if (!regmap) { dev_err(dev, "Failed to get regmap\n"); return -ENOENT; } - init_data = of_get_regulator_init_data(dev, dev->of_node, - &qcom_usb_vbus_rdesc); + rdesc = devm_kzalloc(dev, sizeof(*rdesc), GFP_KERNEL); + if (!rdesc) + return -ENOMEM; + + rdesc->name = "usb_vbus"; + rdesc->ops = data->ops; + rdesc->owner = THIS_MODULE; + rdesc->type = REGULATOR_VOLTAGE; + rdesc->enable_reg = base + data->cmd_otg; + rdesc->enable_mask = OTG_EN; + + if (data->curr_table) { + rdesc->curr_table = data->curr_table; + rdesc->n_current_limits = data->n_current_limits; + rdesc->csel_reg = base + data->csel_reg; + rdesc->csel_mask = data->csel_mask; + } + + if (data->volt_table) { + rdesc->volt_table = data->volt_table; + rdesc->n_voltages = data->n_voltages; + rdesc->vsel_reg = base + data->vsel_reg; + rdesc->vsel_mask = data->vsel_mask; + } + + init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc); if (!init_data) return -ENOMEM; - qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; - qcom_usb_vbus_rdesc.enable_mask = OTG_EN; - qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; - qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK; config.dev = dev; config.init_data = init_data; config.of_node = dev->of_node; config.regmap = regmap; - rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); + rdev = devm_regulator_register(dev, rdesc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(dev, "not able to register vbus reg %d\n", ret); @@ -85,13 +158,14 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) } /* Disable HW logic for VBUS enable */ - regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); + regmap_update_bits(regmap, base + data->otg_cfg, data->otg_en_src_cfg, 0); return 0; } static const struct of_device_id qcom_usb_vbus_regulator_match[] = { - { .compatible = "qcom,pm8150b-vbus-reg" }, + { .compatible = "qcom,pm8150b-vbus-reg", .data = &pm8150b_data }, + { .compatible = "qcom,pm4125-vbus-reg", .data = &pm4125_data }, { } }; MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match); From c5ad3cd60013d9d8b91501a170d946333d01cc9b Mon Sep 17 00:00:00 2001 From: Kuldeep Singh Date: Thu, 14 May 2026 18:29:02 +0530 Subject: [PATCH 109/128] FROMLIST: dt-bindings: crypto: qcom,prng: Document Shikra TRNG Document shikra compatible for the True Random Number Generator. Link: https://lore.kernel.org/lkml/20260514-shikra_rng-v1-1-4ea721a1429a@oss.qualcomm.com/ Signed-off-by: Kuldeep Singh --- Documentation/devicetree/bindings/crypto/qcom,prng.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml index 41402599e9ab8..cc89a90d56119 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,prng.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,prng.yaml @@ -27,6 +27,7 @@ properties: - qcom,sa8255p-trng - qcom,sa8775p-trng - qcom,sc7280-trng + - qcom,shikra-trng - qcom,sm8450-trng - qcom,sm8550-trng - qcom,sm8650-trng From 6fd0c8fe226ddd8caf4234187de43310006ada5f Mon Sep 17 00:00:00 2001 From: Kuldeep Singh Date: Fri, 15 May 2026 00:03:03 +0530 Subject: [PATCH 110/128] FROMLIST: dt-bindings: crypto: qcom-qce: Document the Shikra crypto engine Document the crypto engine on the Shikra platform. Link:https://lore.kernel.org/lkml/20260515-shikra_qcrypto-v1-1-80f07b345c29@oss.qualcomm.com/ Signed-off-by: Kuldeep Singh --- Documentation/devicetree/bindings/crypto/qcom-qce.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/crypto/qcom-qce.yaml b/Documentation/devicetree/bindings/crypto/qcom-qce.yaml index 79d5be2548bc5..d0cbb667aa4c7 100644 --- a/Documentation/devicetree/bindings/crypto/qcom-qce.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom-qce.yaml @@ -50,6 +50,7 @@ properties: - qcom,qcs8300-qce - qcom,sa8775p-qce - qcom,sc7280-qce + - qcom,shikra-qce - qcom,sm6350-qce - qcom,sm8250-qce - qcom,sm8350-qce From 6740a43f7c5118e314f077eb6c14fb2b00f55f6a Mon Sep 17 00:00:00 2001 From: Kuldeep Singh Date: Fri, 15 May 2026 00:03:58 +0530 Subject: [PATCH 111/128] dt-bindings: bam-dma: Increase maxItems to seven for iommus Shikra bam dma engine support seven iommu entries. Increase maxItems property for iommus to pass dtbs_check errors. Link: https://lore.kernel.org/lkml/20260515-shikra_qcrypto-v1-2-80f07b345c29@oss.qualcomm.com/ Signed-off-by: Kuldeep Singh --- Documentation/devicetree/bindings/dma/qcom,bam-dma.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/qcom,bam-dma.yaml b/Documentation/devicetree/bindings/dma/qcom,bam-dma.yaml index 6493a6968bb4b..ffdb308352c3f 100644 --- a/Documentation/devicetree/bindings/dma/qcom,bam-dma.yaml +++ b/Documentation/devicetree/bindings/dma/qcom,bam-dma.yaml @@ -46,7 +46,7 @@ properties: iommus: minItems: 1 - maxItems: 6 + maxItems: 7 num-channels: $ref: /schemas/types.yaml#/definitions/uint32 From 22329f7d2509cd4d8da85d98be23df27175e67e5 Mon Sep 17 00:00:00 2001 From: Kuldeep Singh Date: Wed, 13 May 2026 18:00:30 +0530 Subject: [PATCH 112/128] dt-bindings: crypto: qcom,inline-crypto-engine: Document Shikra ICE Document the Inline Crypto Engine (ICE) on the Shikra platform. Signed-off-by: Kuldeep Singh --- .../devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml index 876bf90ed96ef..0d5fbbce14986 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml @@ -20,6 +20,7 @@ properties: - qcom,sa8775p-inline-crypto-engine - qcom,sc7180-inline-crypto-engine - qcom,sc7280-inline-crypto-engine + - qcom,shikra-inline-crypto-engine - qcom,sm8450-inline-crypto-engine - qcom,sm8550-inline-crypto-engine - qcom,sm8650-inline-crypto-engine From ad7a03b4ee8784d88915bacdc05b19c2e768de98 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Fri, 8 May 2026 17:21:41 +0530 Subject: [PATCH 113/128] clk: qcom: common: Register reset controller only when resets are present Some clock controller descriptors do not provide any reset lines. Avoid registering a reset controller when desc->num_resets is zero by making the registration conditional. Signed-off-by: Imran Shaik --- drivers/clk/qcom/common.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index eec369d2173b5..be9b6ebb2fffd 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -359,17 +359,19 @@ int qcom_cc_really_probe(struct device *dev, qcom_cc_clk_regs_configure(dev, desc->driver_data, regmap); } - reset = &cc->reset; - reset->rcdev.of_node = dev->of_node; - reset->rcdev.ops = &qcom_reset_ops; - reset->rcdev.owner = dev->driver->owner; - reset->rcdev.nr_resets = desc->num_resets; - reset->regmap = regmap; - reset->reset_map = desc->resets; - - ret = devm_reset_controller_register(dev, &reset->rcdev); - if (ret) - goto put_rpm; + if (desc->num_resets) { + reset = &cc->reset; + reset->rcdev.of_node = dev->of_node; + reset->rcdev.ops = &qcom_reset_ops; + reset->rcdev.owner = dev->driver->owner; + reset->rcdev.nr_resets = desc->num_resets; + reset->regmap = regmap; + reset->reset_map = desc->resets; + + ret = devm_reset_controller_register(dev, &reset->rcdev); + if (ret) + goto put_rpm; + } if (desc->gdscs && desc->num_gdscs) { scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL); From 2dcb496403d09ad21e03f8fbba54123716d1cadc Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Tue, 12 May 2026 18:41:56 +0530 Subject: [PATCH 114/128] clk: qcom: common: Skip NULL clock hw entries during registration Some Qualcomm clock controller descriptors may contain NULL entries in the clk_hws array. Skip such entries when registering clock hardware to avoid passing NULL pointers to the clock framework. Signed-off-by: Imran Shaik --- drivers/clk/qcom/common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index be9b6ebb2fffd..000bfdcc5391f 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -408,6 +408,9 @@ int qcom_cc_really_probe(struct device *dev, qcom_cc_drop_protected(dev, cc); for (i = 0; i < num_clk_hws; i++) { + if (!clk_hws[i]) + continue; + ret = devm_clk_hw_register(dev, clk_hws[i]); if (ret) goto put_rpm; From 51cfc2c8c65847ee6b4e167fb59fbc42d34bafdf Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 7 May 2026 14:05:07 +0530 Subject: [PATCH 115/128] dt-bindings: clock: qcom: Add GCC LPASS clocks support for Shikra Add GCC LPASS clocks support for Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- include/dt-bindings/clock/qcom,shikra-gcc.h | 203 ++++++++++---------- 1 file changed, 103 insertions(+), 100 deletions(-) diff --git a/include/dt-bindings/clock/qcom,shikra-gcc.h b/include/dt-bindings/clock/qcom,shikra-gcc.h index 2e88a9cd9f535..dc55e5652caae 100644 --- a/include/dt-bindings/clock/qcom,shikra-gcc.h +++ b/include/dt-bindings/clock/qcom,shikra-gcc.h @@ -119,106 +119,109 @@ #define GCC_GPU_CFG_AHB_CLK 109 #define GCC_GPU_GPLL0_CLK_SRC 110 #define GCC_GPU_GPLL0_DIV_CLK_SRC 111 -#define GCC_GPU_MEMNOC_GFX_CLK 112 -#define GCC_GPU_SMMU_VOTE_CLK 113 -#define GCC_GPU_SNOC_DVM_GFX_CLK 114 -#define GCC_GPU_THROTTLE_CORE_CLK 115 -#define GCC_MMU_TCU_VOTE_CLK 116 -#define GCC_PCIE_AUX_CLK 117 -#define GCC_PCIE_AUX_CLK_SRC 118 -#define GCC_PCIE_AUX_PHY_CLK_SRC 119 -#define GCC_PCIE_CFG_AHB_CLK 120 -#define GCC_PCIE_CLKREF_EN 121 -#define GCC_PCIE_MSTR_AXI_CLK 122 -#define GCC_PCIE_PIPE_CLK 123 -#define GCC_PCIE_PIPE_CLK_SRC 124 -#define GCC_PCIE_RCHNG_PHY_CLK 125 -#define GCC_PCIE_RCHNG_PHY_CLK_SRC 126 -#define GCC_PCIE_SLEEP_CLK 127 -#define GCC_PCIE_SLV_AXI_CLK 128 -#define GCC_PCIE_SLV_Q2A_AXI_CLK 129 -#define GCC_PCIE_TBU_CLK 130 -#define GCC_PCIE_THROTTLE_CORE_CLK 131 -#define GCC_PCIE_THROTTLE_XO_CLK 132 -#define GCC_PCIE_TILE_AXI_SYS_NOC_CLK 133 -#define GCC_PDM2_CLK 134 -#define GCC_PDM2_CLK_SRC 135 -#define GCC_PDM_AHB_CLK 136 -#define GCC_PDM_XO4_CLK 137 -#define GCC_PWM0_XO512_CLK 138 -#define GCC_QMIP_CAMERA_NRT_AHB_CLK 139 -#define GCC_QMIP_CAMERA_RT_AHB_CLK 140 -#define GCC_QMIP_DISP_AHB_CLK 141 -#define GCC_QMIP_GPU_CFG_AHB_CLK 142 -#define GCC_QMIP_PCIE_CFG_AHB_CLK 143 -#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 144 -#define GCC_QUPV3_WRAP0_CORE_2X_CLK 145 -#define GCC_QUPV3_WRAP0_CORE_CLK 146 -#define GCC_QUPV3_WRAP0_S0_CLK 147 -#define GCC_QUPV3_WRAP0_S0_CLK_SRC 148 -#define GCC_QUPV3_WRAP0_S1_CLK 149 -#define GCC_QUPV3_WRAP0_S1_CLK_SRC 150 -#define GCC_QUPV3_WRAP0_S2_CLK 151 -#define GCC_QUPV3_WRAP0_S2_CLK_SRC 152 -#define GCC_QUPV3_WRAP0_S3_CLK 153 -#define GCC_QUPV3_WRAP0_S3_CLK_SRC 154 -#define GCC_QUPV3_WRAP0_S4_CLK 155 -#define GCC_QUPV3_WRAP0_S4_CLK_SRC 156 -#define GCC_QUPV3_WRAP0_S5_CLK 157 -#define GCC_QUPV3_WRAP0_S5_CLK_SRC 158 -#define GCC_QUPV3_WRAP0_S6_CLK 159 -#define GCC_QUPV3_WRAP0_S6_CLK_SRC 160 -#define GCC_QUPV3_WRAP0_S7_CLK 161 -#define GCC_QUPV3_WRAP0_S7_CLK_SRC 162 -#define GCC_QUPV3_WRAP0_S8_CLK 163 -#define GCC_QUPV3_WRAP0_S8_CLK_SRC 164 -#define GCC_QUPV3_WRAP0_S9_CLK 165 -#define GCC_QUPV3_WRAP0_S9_CLK_SRC 166 -#define GCC_QUPV3_WRAP_0_M_AHB_CLK 167 -#define GCC_QUPV3_WRAP_0_S_AHB_CLK 168 -#define GCC_SDCC1_AHB_CLK 169 -#define GCC_SDCC1_APPS_CLK 170 -#define GCC_SDCC1_APPS_CLK_SRC 171 -#define GCC_SDCC1_ICE_CORE_CLK 172 -#define GCC_SDCC1_ICE_CORE_CLK_SRC 173 -#define GCC_SDCC2_AHB_CLK 174 -#define GCC_SDCC2_APPS_CLK 175 -#define GCC_SDCC2_APPS_CLK_SRC 176 -#define GCC_SYS_NOC_CPUSS_AHB_CLK 177 -#define GCC_SYS_NOC_USB2_PRIM_AXI_CLK 178 -#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK 179 -#define GCC_TSCSS_AHB_CLK 180 -#define GCC_TSCSS_CLK_SRC 181 -#define GCC_TSCSS_CNTR_CLK 182 -#define GCC_TSCSS_ETU_CLK 183 -#define GCC_UFS_CLKREF_EN 184 -#define GCC_USB20_MASTER_CLK 185 -#define GCC_USB20_MASTER_CLK_SRC 186 -#define GCC_USB20_MOCK_UTMI_CLK 187 -#define GCC_USB20_MOCK_UTMI_CLK_SRC 188 -#define GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC 189 -#define GCC_USB20_SLEEP_CLK 190 -#define GCC_USB30_PRIM_MASTER_CLK 191 -#define GCC_USB30_PRIM_MASTER_CLK_SRC 192 -#define GCC_USB30_PRIM_MOCK_UTMI_CLK 193 -#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 194 -#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 195 -#define GCC_USB30_PRIM_SLEEP_CLK 196 -#define GCC_USB3_PRIM_CLKREF_EN 197 -#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 198 -#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 199 -#define GCC_USB3_PRIM_PHY_PIPE_CLK 200 -#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 201 -#define GCC_VCODEC0_AXI_CLK 202 -#define GCC_VENUS_AHB_CLK 203 -#define GCC_VENUS_CTL_AXI_CLK 204 -#define GCC_VIDEO_AHB_CLK 205 -#define GCC_VIDEO_AXI0_CLK 206 -#define GCC_VIDEO_THROTTLE_CORE_CLK 207 -#define GCC_VIDEO_VCODEC0_SYS_CLK 208 -#define GCC_VIDEO_VENUS_CLK_SRC 209 -#define GCC_VIDEO_VENUS_CTL_CLK 210 -#define GCC_VIDEO_XO_CLK 211 +#define GCC_GPU_IREF_CLK 112 +#define GCC_GPU_MEMNOC_GFX_CLK 113 +#define GCC_GPU_SMMU_VOTE_CLK 114 +#define GCC_GPU_SNOC_DVM_GFX_CLK 115 +#define GCC_GPU_THROTTLE_CORE_CLK 116 +#define GCC_LPASS_CONFIG_CLK 117 +#define GCC_LPASS_CORE_AXIM_CLK 118 +#define GCC_MMU_TCU_VOTE_CLK 119 +#define GCC_PCIE_AUX_CLK 120 +#define GCC_PCIE_AUX_CLK_SRC 121 +#define GCC_PCIE_AUX_PHY_CLK_SRC 122 +#define GCC_PCIE_CFG_AHB_CLK 123 +#define GCC_PCIE_CLKREF_EN 124 +#define GCC_PCIE_MSTR_AXI_CLK 125 +#define GCC_PCIE_PIPE_CLK 126 +#define GCC_PCIE_PIPE_CLK_SRC 127 +#define GCC_PCIE_RCHNG_PHY_CLK 128 +#define GCC_PCIE_RCHNG_PHY_CLK_SRC 129 +#define GCC_PCIE_SLEEP_CLK 130 +#define GCC_PCIE_SLV_AXI_CLK 131 +#define GCC_PCIE_SLV_Q2A_AXI_CLK 132 +#define GCC_PCIE_TBU_CLK 133 +#define GCC_PCIE_THROTTLE_CORE_CLK 134 +#define GCC_PCIE_THROTTLE_XO_CLK 135 +#define GCC_PCIE_TILE_AXI_SYS_NOC_CLK 136 +#define GCC_PDM2_CLK 137 +#define GCC_PDM2_CLK_SRC 138 +#define GCC_PDM_AHB_CLK 139 +#define GCC_PDM_XO4_CLK 140 +#define GCC_PWM0_XO512_CLK 141 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 142 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 143 +#define GCC_QMIP_DISP_AHB_CLK 144 +#define GCC_QMIP_GPU_CFG_AHB_CLK 145 +#define GCC_QMIP_PCIE_CFG_AHB_CLK 146 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 147 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 148 +#define GCC_QUPV3_WRAP0_CORE_CLK 149 +#define GCC_QUPV3_WRAP0_S0_CLK 150 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 151 +#define GCC_QUPV3_WRAP0_S1_CLK 152 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 153 +#define GCC_QUPV3_WRAP0_S2_CLK 154 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 155 +#define GCC_QUPV3_WRAP0_S3_CLK 156 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 157 +#define GCC_QUPV3_WRAP0_S4_CLK 158 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 159 +#define GCC_QUPV3_WRAP0_S5_CLK 160 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 161 +#define GCC_QUPV3_WRAP0_S6_CLK 162 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 163 +#define GCC_QUPV3_WRAP0_S7_CLK 164 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 165 +#define GCC_QUPV3_WRAP0_S8_CLK 166 +#define GCC_QUPV3_WRAP0_S8_CLK_SRC 167 +#define GCC_QUPV3_WRAP0_S9_CLK 168 +#define GCC_QUPV3_WRAP0_S9_CLK_SRC 169 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 170 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 171 +#define GCC_SDCC1_AHB_CLK 172 +#define GCC_SDCC1_APPS_CLK 173 +#define GCC_SDCC1_APPS_CLK_SRC 174 +#define GCC_SDCC1_ICE_CORE_CLK 175 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 176 +#define GCC_SDCC2_AHB_CLK 177 +#define GCC_SDCC2_APPS_CLK 178 +#define GCC_SDCC2_APPS_CLK_SRC 179 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 180 +#define GCC_SYS_NOC_USB2_PRIM_AXI_CLK 181 +#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK 182 +#define GCC_TSCSS_AHB_CLK 183 +#define GCC_TSCSS_CLK_SRC 184 +#define GCC_TSCSS_CNTR_CLK 185 +#define GCC_TSCSS_ETU_CLK 186 +#define GCC_UFS_CLKREF_EN 187 +#define GCC_USB20_MASTER_CLK 188 +#define GCC_USB20_MASTER_CLK_SRC 189 +#define GCC_USB20_MOCK_UTMI_CLK 190 +#define GCC_USB20_MOCK_UTMI_CLK_SRC 191 +#define GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC 192 +#define GCC_USB20_SLEEP_CLK 193 +#define GCC_USB30_PRIM_MASTER_CLK 194 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 195 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 196 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 197 +#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC 198 +#define GCC_USB30_PRIM_SLEEP_CLK 199 +#define GCC_USB3_PRIM_CLKREF_EN 200 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 201 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 202 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 203 +#define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 204 +#define GCC_VCODEC0_AXI_CLK 205 +#define GCC_VENUS_AHB_CLK 206 +#define GCC_VENUS_CTL_AXI_CLK 207 +#define GCC_VIDEO_AHB_CLK 208 +#define GCC_VIDEO_AXI0_CLK 209 +#define GCC_VIDEO_THROTTLE_CORE_CLK 210 +#define GCC_VIDEO_VCODEC0_SYS_CLK 211 +#define GCC_VIDEO_VENUS_CLK_SRC 212 +#define GCC_VIDEO_VENUS_CTL_CLK 213 +#define GCC_VIDEO_XO_CLK 214 /* GCC power domains */ #define GCC_CAMSS_TOP_GDSC 0 From ac6b0434c39c1aaa1fd99eb13fbd24eff3df2956 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 7 May 2026 14:05:30 +0530 Subject: [PATCH 116/128] clk: qcom: gcc-shikra: Mark GCC LPASS clocks as critical The GCC LPASS clocks must be enabled to access audio core clock controller registers. Hence, mark them as critical on Qualcomm Shikra SoCs. Signed-off-by: Imran Shaik --- drivers/clk/qcom/gcc-shikra.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/gcc-shikra.c b/drivers/clk/qcom/gcc-shikra.c index 8834618354882..65cd42e0334de 100644 --- a/drivers/clk/qcom/gcc-shikra.c +++ b/drivers/clk/qcom/gcc-shikra.c @@ -4347,6 +4347,8 @@ static u32 gcc_shikra_critical_cbcrs[] = { 0x1702c, /* GCC_DISP_XO_CLK */ 0x36004, /* GCC_GPU_CFG_AHB_CLK */ 0x36100, /* GCC_GPU_IREF_CLK */ + 0x3a00c, /* GCC_LPASS_CONFIG_CLK */ + 0x3a008, /* GCC_LPASS_CORE_AXIM_CLK */ 0x79004, /* GCC_SYS_NOC_CPUSS_AHB_CLK */ 0x17004, /* GCC_VIDEO_AHB_CLK */ 0x17024, /* GCC_VIDEO_XO_CLK */ From c1255bcdc2bdd04ab4770a0556d1a2be20a36d9e Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 7 May 2026 14:35:05 +0530 Subject: [PATCH 117/128] dt-bindings: clock: qcom: Add Qualcomm Shikra Audio Core Clock Controller Add device tree bindings for the Audio Core clock controller on Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- .../clock/qcom,shikra-audiocorecc.yaml | 62 +++++++++++++++++++ .../clock/qcom,shikra-audiocorecc.h | 49 +++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml create mode 100644 include/dt-bindings/clock/qcom,shikra-audiocorecc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml new file mode 100644 index 0000000000000..2ed1d9d871175 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,shikra-audiocorecc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Audio Core Clock & Reset Controller for Qualcomm Shikra SoC + +maintainers: + - Imran Shaik + +description: | + Audio core clock control module provides the clocks and resets + on Qualcomm Shikra SoC platform. + + See also: + - include/dt-bindings/clock/qcom,shikra-audiocorecc.h + +properties: + compatible: + enum: + - qcom,shikra-cqm-audiocorecc + - qcom,shikra-cqs-audiocorecc + + clocks: + items: + - description: Board XO source + - description: Board sleep clock + - description: Audio ref clock source + + reg: + maxItems: 2 + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + #include + clock-controller@a0a0000 { + compatible = "qcom,shikra-cqm-audiocorecc"; + reg = <0x0a0a0000 0x10000>, + <0x0a0b4000 0x1000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <&aud_ref_clk_src>; + #clock-cells = <1>; + #reset-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,shikra-audiocorecc.h b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h new file mode 100644 index 0000000000000..bc77d7a3946ea --- /dev/null +++ b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H +#define _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H + +/* AUDIO_CORE_CC clocks */ +#define AUDIO_CORE_CC_DIG_PLL 0 +#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX 1 +#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX2 2 +#define AUDIO_CORE_CC_AIF_IF0_CLK_SRC 3 +#define AUDIO_CORE_CC_AIF_IF0_EBIT_CLK 4 +#define AUDIO_CORE_CC_AIF_IF0_IBIT_CLK 5 +#define AUDIO_CORE_CC_AIF_IF1_CLK_SRC 6 +#define AUDIO_CORE_CC_AIF_IF1_EBIT_CLK 7 +#define AUDIO_CORE_CC_AIF_IF1_IBIT_CLK 8 +#define AUDIO_CORE_CC_AIF_IF2_CLK_SRC 9 +#define AUDIO_CORE_CC_AIF_IF2_EBIT_CLK 10 +#define AUDIO_CORE_CC_AIF_IF2_IBIT_CLK 11 +#define AUDIO_CORE_CC_AIF_IF3_CLK_SRC 12 +#define AUDIO_CORE_CC_AIF_IF3_EBIT_CLK 13 +#define AUDIO_CORE_CC_AIF_IF3_IBIT_CLK 14 +#define AUDIO_CORE_CC_AUD_DMA_CLK 15 +#define AUDIO_CORE_CC_AUD_DMA_CLK_SRC 16 +#define AUDIO_CORE_CC_AUD_DMA_MEM_CLK 17 +#define AUDIO_CORE_CC_BUS_CLK 18 +#define AUDIO_CORE_CC_BUS_CLK_SRC 19 +#define AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC 20 +#define AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC 21 +#define AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK 22 +#define AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC 23 +#define AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK 24 +#define AUDIO_CORE_CC_IM_SLEEP_CLK 25 +#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK 26 +#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC 27 +#define AUDIO_CORE_CC_RX_MCLK_2X_CLK 28 +#define AUDIO_CORE_CC_RX_MCLK_CLK 29 +#define AUDIO_CORE_CC_SAMPLING_CLK 30 +#define AUDIO_CORE_CC_TX_MCLK_2X_CLK 31 +#define AUDIO_CORE_CC_TX_MCLK_CLK 32 +#define AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC 33 + +/* AUDIO_CORE_CC resets */ +#define AUDIO_CORE_CSR_RX_SWR_CGCR 0 +#define AUDIO_CORE_CSR_TX_SWR_CGCR 1 + +#endif From 0409df376de3b34e30acedf47b874ee8583e8a95 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Wed, 6 May 2026 16:57:36 +0530 Subject: [PATCH 118/128] clk: qcom: Add Audio Core clock controller support on Qualcomm Shikra SoC Add support for Audio core clock controller on Qualcomm Shikra SoC. Signed-off-by: Imran Shaik --- drivers/clk/qcom/Kconfig | 11 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/audiocorecc-shikra.c | 815 ++++++++++++++++++++++++++ 3 files changed, 827 insertions(+) create mode 100644 drivers/clk/qcom/audiocorecc-shikra.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index f665e5d542a6e..d0cab526ca779 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -155,6 +155,17 @@ config CLK_NORD_GCC SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination of GCC, SE_GCC, NE_GCC and NW_GCC. +config CLK_SHIKRA_AUDIOCORECC + tristate "Shikra Audio Core Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_SHIKRA_GCC + default m if ARCH_QCOM + help + Support for the Audio Core clock controller on Qualcomm Technologies, Inc + Shikra devices. + Say Y if you want to use AudioCoreCC clocks required to support audio + devices and it's functionality. + config CLK_SHIKRA_DISPCC tristate "Shikra Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 12eaa5b02e45c..00611a9a82413 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o +obj-$(CONFIG_CLK_SHIKRA_AUDIOCORECC) += audiocorecc-shikra.o obj-$(CONFIG_CLK_SHIKRA_DISPCC) += dispcc-shikra.o obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o obj-$(CONFIG_CLK_SHIKRA_GPUCC) += gpucc-shikra.o diff --git a/drivers/clk/qcom/audiocorecc-shikra.c b/drivers/clk/qcom/audiocorecc-shikra.c new file mode 100644 index 0000000000000..f7655b2cbd458 --- /dev/null +++ b/drivers/clk/qcom/audiocorecc-shikra.c @@ -0,0 +1,815 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_AUD_REF_CLK_SRC, +}; + +enum { + P_AUD_REF_CLK_SRC, + P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, + P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, + P_BI_TCXO, + P_SLEEP_CLK, +}; + +static const struct pll_vco spark_vco[] = { + { 500000000, 1000000000, 2 }, +}; + +/* 614.4 MHz Configuration */ +static const struct alpha_pll_config audio_core_cc_dig_pll_config = { + .l = 0x20, + .alpha = 0x0, + .vco_val = BIT(21), + .post_div_val = 0x28100, + .post_div_mask = GENMASK(17, 8), + .vco_mask = GENMASK(21, 20), + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .aux2_output_mask = BIT(2), + .config_ctl_val = 0x4001055b, + .test_ctl_hi_val = 0x1, + .test_ctl_hi_mask = 0x1, +}; + +static struct clk_alpha_pll audio_core_cc_dig_pll = { + .offset = 0x0, + .config = &audio_core_cc_dig_pll_config, + .vco_table = spark_vco, + .num_vco = ARRAY_SIZE(spark_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_dig_pll", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_ops, + }, + }, +}; + +static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data) { + .name = "audio_core_cc_dig_pll_out_aux", + .parent_data = &(const struct clk_parent_data) { + .hw = &audio_core_cc_dig_pll.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data) { + .name = "audio_core_cc_dig_pll_out_aux2", + .parent_data = &(const struct clk_parent_data) { + .hw = &audio_core_cc_dig_pll.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct parent_map audio_core_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_AUD_REF_CLK_SRC, 1 }, + { P_SLEEP_CLK, 2 }, + { P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4 }, + { P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 6 }, +}; + +static const struct clk_parent_data audio_core_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_AUD_REF_CLK_SRC }, + { .index = DT_SLEEP_CLK }, + { .hw = &audio_core_cc_dig_pll_out_aux.hw }, + { .hw = &audio_core_cc_dig_pll_out_aux2.hw }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aif_if0_clk_src[] = { + F(240000, P_BI_TCXO, 10, 1, 8), + F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32), + F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16), + F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16), + F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8), + F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8), + F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4), + F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4), + F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2), + F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2), + F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aif_if0_clk_src = { + .cmd_rcgr = 0x104c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_aif_if1_clk_src = { + .cmd_rcgr = 0x10b0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_aif_if2_clk_src = { + .cmd_rcgr = 0x1114, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aif_if3_clk_src[] = { + F(240000, P_BI_TCXO, 10, 1, 8), + F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32), + F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16), + F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16), + F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8), + F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8), + F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4), + F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4), + F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2), + F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2), + F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + F(49152000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aif_if3_clk_src = { + .cmd_rcgr = 0x1178, + .mnd_width = 16, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if3_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_aud_dma_clk_src[] = { + F(102400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 3, 0, 0), + F(153600000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 2, 0, 0), + F(307200000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_aud_dma_clk_src = { + .cmd_rcgr = 0x1028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aud_dma_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_bus_clk_src[] = { + F(38400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 8, 0, 0), + F(76800000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 4, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_bus_clk_src = { + .cmd_rcgr = 0x1008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_bus_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_bus_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_ext_mclka_clk_src = { + .cmd_rcgr = 0x123c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclka_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 audio_core_cc_ext_mclkb_clk_src = { + .cmd_rcgr = 0x125c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclkb_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_lpaif_pcmoe_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(15360000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 8, 0, 0), + F(30720000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4, 0, 0), + F(61440000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_lpaif_pcmoe_clk_src = { + .cmd_rcgr = 0x12ac, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_lpaif_pcmoe_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_lpaif_pcmoe_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_audio_core_cc_tx_mclk_rcg_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0), + { } +}; + +static struct clk_rcg2 audio_core_cc_tx_mclk_rcg_clk_src = { + .cmd_rcgr = 0x127c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = audio_core_cc_parent_map_0, + .freq_tbl = ftbl_audio_core_cc_tx_mclk_rcg_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_rcg_clk_src", + .parent_data = audio_core_cc_parent_data_0, + .num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div audio_core_cc_cdiv_tx_mclk_div_clk_src = { + .reg = 0x129c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_cdiv_tx_mclk_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch audio_core_cc_aif_if0_ebit_clk = { + .halt_reg = 0x1068, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if0_ibit_clk = { + .halt_reg = 0x1064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if0_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if1_ebit_clk = { + .halt_reg = 0x10cc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if1_ibit_clk = { + .halt_reg = 0x10c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if1_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if2_ebit_clk = { + .halt_reg = 0x1130, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1130, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if2_ibit_clk = { + .halt_reg = 0x112c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if2_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if3_ebit_clk = { + .halt_reg = 0x1194, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1194, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_ebit_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aif_if3_ibit_clk = { + .halt_reg = 0x1190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1190, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aif_if3_ibit_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aif_if3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aud_dma_clk = { + .halt_reg = 0x1040, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aud_dma_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_aud_dma_mem_clk = { + .halt_reg = 0x1044, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_aud_dma_mem_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_aud_dma_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_bus_clk = { + .halt_reg = 0x1020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_bus_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_bus_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_ext_mclka_out_clk = { + .halt_reg = 0x1254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclka_out_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_ext_mclka_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_ext_mclkb_out_clk = { + .halt_reg = 0x1274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_ext_mclkb_out_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_ext_mclkb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_im_sleep_clk = { + .halt_reg = 0x12cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_im_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_lpaif_pcmoe_clk = { + .halt_reg = 0x12c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_lpaif_pcmoe_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_lpaif_pcmoe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_rx_mclk_2x_clk = { + .halt_reg = 0x1298, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1298, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_rx_mclk_2x_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_rx_mclk_clk = { + .halt_reg = 0x12a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_rx_mclk_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_sampling_clk = { + .halt_reg = 0x1000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_sampling_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_tx_mclk_2x_clk = { + .halt_reg = 0x1294, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1294, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_2x_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch audio_core_cc_tx_mclk_clk = { + .halt_reg = 0x12a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "audio_core_cc_tx_mclk_clk", + .parent_hws = (const struct clk_hw*[]) { + &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_hw *audio_core_cc_shikra_hws[] = { + [AUDIO_CORE_CC_DIG_PLL_OUT_AUX] = &audio_core_cc_dig_pll_out_aux.hw, + [AUDIO_CORE_CC_DIG_PLL_OUT_AUX2] = &audio_core_cc_dig_pll_out_aux2.hw, +}; + +static struct clk_regmap *audio_core_cc_shikra_clocks[] = { + [AUDIO_CORE_CC_AIF_IF0_CLK_SRC] = &audio_core_cc_aif_if0_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF0_EBIT_CLK] = &audio_core_cc_aif_if0_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF0_IBIT_CLK] = &audio_core_cc_aif_if0_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF1_CLK_SRC] = &audio_core_cc_aif_if1_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF1_EBIT_CLK] = &audio_core_cc_aif_if1_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF1_IBIT_CLK] = &audio_core_cc_aif_if1_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF2_CLK_SRC] = &audio_core_cc_aif_if2_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF2_EBIT_CLK] = &audio_core_cc_aif_if2_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF2_IBIT_CLK] = &audio_core_cc_aif_if2_ibit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF3_CLK_SRC] = &audio_core_cc_aif_if3_clk_src.clkr, + [AUDIO_CORE_CC_AIF_IF3_EBIT_CLK] = &audio_core_cc_aif_if3_ebit_clk.clkr, + [AUDIO_CORE_CC_AIF_IF3_IBIT_CLK] = &audio_core_cc_aif_if3_ibit_clk.clkr, + [AUDIO_CORE_CC_AUD_DMA_CLK] = &audio_core_cc_aud_dma_clk.clkr, + [AUDIO_CORE_CC_AUD_DMA_CLK_SRC] = &audio_core_cc_aud_dma_clk_src.clkr, + [AUDIO_CORE_CC_AUD_DMA_MEM_CLK] = &audio_core_cc_aud_dma_mem_clk.clkr, + [AUDIO_CORE_CC_BUS_CLK] = &audio_core_cc_bus_clk.clkr, + [AUDIO_CORE_CC_BUS_CLK_SRC] = &audio_core_cc_bus_clk_src.clkr, + [AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC] = &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr, + [AUDIO_CORE_CC_DIG_PLL] = &audio_core_cc_dig_pll.clkr, + [AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC] = &audio_core_cc_ext_mclka_clk_src.clkr, + [AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK] = &audio_core_cc_ext_mclka_out_clk.clkr, + [AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC] = &audio_core_cc_ext_mclkb_clk_src.clkr, + [AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK] = &audio_core_cc_ext_mclkb_out_clk.clkr, + [AUDIO_CORE_CC_IM_SLEEP_CLK] = &audio_core_cc_im_sleep_clk.clkr, + [AUDIO_CORE_CC_LPAIF_PCMOE_CLK] = &audio_core_cc_lpaif_pcmoe_clk.clkr, + [AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC] = &audio_core_cc_lpaif_pcmoe_clk_src.clkr, + [AUDIO_CORE_CC_RX_MCLK_2X_CLK] = &audio_core_cc_rx_mclk_2x_clk.clkr, + [AUDIO_CORE_CC_RX_MCLK_CLK] = &audio_core_cc_rx_mclk_clk.clkr, + [AUDIO_CORE_CC_SAMPLING_CLK] = &audio_core_cc_sampling_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_2X_CLK] = &audio_core_cc_tx_mclk_2x_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_CLK] = &audio_core_cc_tx_mclk_clk.clkr, + [AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC] = &audio_core_cc_tx_mclk_rcg_clk_src.clkr, +}; + +static struct clk_alpha_pll *audio_core_cc_shikra_plls[] = { + &audio_core_cc_dig_pll, +}; + +static const struct regmap_config audio_core_cc_shikra_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x305c, + .fast_io = true, +}; + +static const struct qcom_reset_map audio_core_cc_shikra_resets[] = { + [AUDIO_CORE_CSR_RX_SWR_CGCR] = { 0x1c }, + [AUDIO_CORE_CSR_TX_SWR_CGCR] = { 0x30 }, +}; + +static const struct regmap_config audio_core_cc_shikra_reset_regmap_config = { + .name = "audio_core_cc_shikra_reset", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, + .max_register = 0x34, +}; + +static struct qcom_cc_driver_data audio_core_cc_shikra_driver_data = { + .alpha_plls = audio_core_cc_shikra_plls, + .num_alpha_plls = ARRAY_SIZE(audio_core_cc_shikra_plls), +}; + +static const struct qcom_cc_desc audio_core_cc_shikra_reset_desc = { + .config = &audio_core_cc_shikra_reset_regmap_config, + .resets = audio_core_cc_shikra_resets, + .num_resets = ARRAY_SIZE(audio_core_cc_shikra_resets), +}; + +static const struct qcom_cc_desc audio_core_cc_shikra_desc = { + .config = &audio_core_cc_shikra_regmap_config, + .clk_hws = audio_core_cc_shikra_hws, + .num_clk_hws = ARRAY_SIZE(audio_core_cc_shikra_hws), + .clks = audio_core_cc_shikra_clocks, + .num_clks = ARRAY_SIZE(audio_core_cc_shikra_clocks), + .driver_data = &audio_core_cc_shikra_driver_data, +}; + +static const struct of_device_id audio_core_cc_shikra_match_table[] = { + { .compatible = "qcom,shikra-cqm-audiocorecc" }, + { .compatible = "qcom,shikra-cqs-audiocorecc" }, + { } +}; +MODULE_DEVICE_TABLE(of, audio_core_cc_shikra_match_table); + +static int audio_core_cc_shikra_probe(struct platform_device *pdev) +{ + int ret; + + ret = qcom_cc_probe_by_index(pdev, 1, &audio_core_cc_shikra_reset_desc); + if (ret) + return ret; + + if (device_is_compatible(&pdev->dev, "qcom,shikra-cqs-audiocorecc")) + return 0; + + return qcom_cc_probe(pdev, &audio_core_cc_shikra_desc); +} + +static struct platform_driver audio_core_cc_shikra_driver = { + .probe = audio_core_cc_shikra_probe, + .driver = { + .name = "audiocorecc-shikra", + .of_match_table = audio_core_cc_shikra_match_table, + }, +}; + +module_platform_driver(audio_core_cc_shikra_driver); + +MODULE_DESCRIPTION("QTI AUDIOCORECC Shikra Driver"); +MODULE_LICENSE("GPL"); From ec15f8b9064ceff6598eb0fedf981e6abbaf8568 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Fri, 15 May 2026 15:19:21 +0530 Subject: [PATCH 119/128] soc: qcom: rpmpd: Reuse sm6125 power domains for shikra Shikra shares the same power domain topology as sm6125. Remove the dedicated shikra_rpmpds[] and update shikra_desc to reuse sm6125_rpmpds[] with RPM_SMD_LEVEL_TURBO_NO_CPR. Signed-off-by: Rakesh Kota --- drivers/pmdomain/qcom/rpmpd.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c index 6f751ee5a7833..5f55fc791131a 100644 --- a/drivers/pmdomain/qcom/rpmpd.c +++ b/drivers/pmdomain/qcom/rpmpd.c @@ -863,21 +863,6 @@ static const struct rpmpd_desc sdm660_desc = { .max_state = RPM_SMD_LEVEL_TURBO, }; -static struct rpmpd *shikra_rpmpds[] = { - [RPMPD_VDDCX] = &cx_rwcx0_lvl, - [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao, - [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl, - [RPMPD_VDDMX] = &mx_rwmx0_lvl, - [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao, - [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl, -}; - -static const struct rpmpd_desc shikra_desc = { - .rpmpds = shikra_rpmpds, - .num_pds = ARRAY_SIZE(shikra_rpmpds), - .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, -}; - static struct rpmpd *sm6115_rpmpds[] = { [SM6115_VDDCX] = &cx_rwcx0_lvl, [SM6115_VDDCX_AO] = &cx_rwcx0_lvl_ao, @@ -910,6 +895,12 @@ static const struct rpmpd_desc sm6125_desc = { .max_state = RPM_SMD_LEVEL_BINNING, }; +static const struct rpmpd_desc shikra_desc = { + .rpmpds = sm6125_rpmpds, + .num_pds = ARRAY_SIZE(sm6125_rpmpds), + .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, +}; + static struct rpmpd *sm6375_rpmpds[] = { [SM6375_VDDCX] = &cx_rwcx0_lvl, [SM6375_VDDCX_AO] = &cx_rwcx0_lvl_ao, From 3aa65ff0ed32fd936027959bc4ae2934cc2d936c Mon Sep 17 00:00:00 2001 From: Anurag Pateriya Date: Fri, 15 May 2026 14:37:22 +0530 Subject: [PATCH 120/128] soc: qcom: pd-mapper: Add shikra PD support for CQM/CQS/IQS All Shikra SoC variants (CQM, CQS, IQS) share the same protection domain requirements: mpss_wlan_pd only. audio_pd is not required on any of these variants. Introduce shikra_cqm_domains with mpss_wlan_pd and wire all three compatibles (qcom,shikra-cqm, qcom,shikra-cqs, qcom,shikra-iqs) to it. Signed-off-by: Anurag Pateriya --- drivers/soc/qcom/qcom_pd_mapper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index 7bb14c20ab5d6..d36558c316321 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -456,6 +456,11 @@ static const struct qcom_pdm_domain_data *sc8280xp_domains[] = { NULL, }; +static const struct qcom_pdm_domain_data *shikra_cqm_domains[] = { + &mpss_wlan_pd, + NULL, +}; + /* Unlike SDM660, SDM630/636 lack CDSP */ static const struct qcom_pdm_domain_data *sdm630_domains[] = { &adsp_audio_pd, @@ -599,6 +604,9 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = { { .compatible = "qcom,sc7280", .data = sc7280_domains, }, { .compatible = "qcom,sc8180x", .data = sc8180x_domains, }, { .compatible = "qcom,sc8280xp", .data = sc8280xp_domains, }, + { .compatible = "qcom,shikra-cqm", .data = shikra_cqm_domains, }, + { .compatible = "qcom,shikra-cqs", .data = shikra_cqm_domains, }, + { .compatible = "qcom,shikra-iqs", .data = shikra_cqm_domains, }, { .compatible = "qcom,sdm630", .data = sdm630_domains, }, { .compatible = "qcom,sdm636", .data = sdm630_domains, }, { .compatible = "qcom,sda660", .data = sdm660_domains, }, From 62230ea7e6c9dd9bbf6c85fdcabc3dca5d903d64 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Thu, 16 Apr 2026 17:29:18 +0530 Subject: [PATCH 121/128] dt-bindings: crypto: qcom,ice: Fix missing power-domain and iface clk The DT bindings for inline-crypto engine do not specify the UFS_PHY_GDSC power-domain and iface clock. Without enabling the iface clock and the associated power-domain the ICE hardware cannot function correctly and leads to unclocked hardware accesses being observed during probe. Fix the DT bindings for inline-crypto engine to require the UFS_PHY_GDSC power-domain and iface clock for new devices (Eliza and Milos) introduced in the current release (7.1) with yet-to-stabilize ABI, while preserving backward compatibility for older devices. Fixes: 618195a7ac3df ("dt-bindings: crypto: qcom,inline-crypto-engine: Document the Eliza ICE") Fixes: 85faec1e85555 ("dt-bindings: crypto: qcom,inline-crypto-engine: document the Milos ICE") Reviewed-by: Kuldeep Singh Reviewed-by: Krzysztof Kozlowski Signed-off-by: Harshal Dev --- .../crypto/qcom,inline-crypto-engine.yaml | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml index 0d5fbbce14986..c0b083da78bf2 100644 --- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml @@ -31,6 +31,16 @@ properties: maxItems: 1 clocks: + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + items: + - const: core + - const: iface + + power-domains: maxItems: 1 operating-points-v2: true @@ -45,6 +55,25 @@ required: additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + enum: + - qcom,eliza-inline-crypto-engine + - qcom,milos-inline-crypto-engine + + then: + required: + - power-domains + - clock-names + properties: + clocks: + minItems: 2 + clock-names: + minItems: 2 + examples: - | #include @@ -53,7 +82,11 @@ examples: compatible = "qcom,sm8550-inline-crypto-engine", "qcom,inline-crypto-engine"; reg = <0x01d88000 0x8000>; - clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "core", + "iface"; + power-domains = <&gcc UFS_PHY_GDSC>; operating-points-v2 = <&ice_opp_table>; From b26f0d6cd72616e9e8c19142f8e290f6fb262967 Mon Sep 17 00:00:00 2001 From: Harshal Dev Date: Thu, 16 Apr 2026 17:29:19 +0530 Subject: [PATCH 122/128] soc: qcom: ice: Allow explicit votes on 'iface' clock for ICE Since Qualcomm inline-crypto engine (ICE) is now a dedicated driver de-coupled from the QCOM UFS driver, it explicitly votes for its required clocks during probe. For scenarios where the 'clk_ignore_unused' flag is not passed on the kernel command line, to avoid potential unclocked ICE hardware register access during probe the ICE driver should additionally vote on the 'iface' clock. Also update the suspend and resume callbacks to handle un-voting and voting on the 'iface' clock. Fixes: 2afbf43a4aec6 ("soc: qcom: Make the Qualcomm UFS/SDCC ICE a dedicated driver") Reviewed-by: Manivannan Sadhasivam Reviewed-by: Kuldeep Singh Reviewed-by: Konrad Dybcio Signed-off-by: Harshal Dev --- drivers/soc/qcom/ice.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index b203bc685cadd..bf4ab2d9e5c03 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -108,6 +108,7 @@ struct qcom_ice { void __iomem *base; struct clk *core_clk; + struct clk *iface_clk; bool use_hwkm; bool hwkm_init_complete; u8 hwkm_version; @@ -312,8 +313,13 @@ int qcom_ice_resume(struct qcom_ice *ice) err = clk_prepare_enable(ice->core_clk); if (err) { - dev_err(dev, "failed to enable core clock (%d)\n", - err); + dev_err(dev, "Failed to enable core clock: %d\n", err); + return err; + } + + err = clk_prepare_enable(ice->iface_clk); + if (err) { + dev_err(dev, "Failed to enable iface clock: %d\n", err); return err; } qcom_ice_hwkm_init(ice); @@ -323,6 +329,7 @@ EXPORT_SYMBOL_GPL(qcom_ice_resume); int qcom_ice_suspend(struct qcom_ice *ice) { + clk_disable_unprepare(ice->iface_clk); clk_disable_unprepare(ice->core_clk); ice->hwkm_init_complete = false; @@ -579,11 +586,17 @@ static struct qcom_ice *qcom_ice_create(struct device *dev, engine->core_clk = devm_clk_get_optional_enabled(dev, "ice_core_clk"); if (!engine->core_clk) engine->core_clk = devm_clk_get_optional_enabled(dev, "ice"); + if (!engine->core_clk) + engine->core_clk = devm_clk_get_optional_enabled(dev, "core"); if (!engine->core_clk) engine->core_clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(engine->core_clk)) return ERR_CAST(engine->core_clk); + engine->iface_clk = devm_clk_get_optional_enabled(dev, "iface"); + if (IS_ERR(engine->iface_clk)) + return ERR_CAST(engine->iface_clk); + if (!qcom_ice_check_supported(engine)) return ERR_PTR(-EOPNOTSUPP); From d6c35663f9eab574099992b48c406f77912af550 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Wed, 20 May 2026 14:42:35 +0530 Subject: [PATCH 123/128] Add qcom-next log files for 20260520 Adding merge log file and topic_SHA1 file Signed-off-by: Salendarsingh Gaud --- qcom-next/merge.log | 468 +++++++++++++++++++++++++++++++++++++++++++ qcom-next/topic_SHA1 | 49 +++++ 2 files changed, 517 insertions(+) create mode 100644 qcom-next/merge.log create mode 100644 qcom-next/topic_SHA1 diff --git a/qcom-next/merge.log b/qcom-next/merge.log new file mode 100644 index 0000000000000..9c49e925ad846 --- /dev/null +++ b/qcom-next/merge.log @@ -0,0 +1,468 @@ +Verified existence of local and remote repos: Success +/local/mnt/workspace/sgaud/Builds/Github/All_Runners/kernel-automation/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics /local/mnt/workspace/sgaud/Builds/Github/All_Runners/kernel-automation/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics +Reuse-Recorded-Resolution: Enabled +Downloaded shared rerere cache +Local tree is clean +Removing old remotes ... +The remote kernel https://github.com/qualcomm-linux/kernel.git is no longer tracked. +Delete it [Y/n]? The remote origin https://github.com/qualcomm-linux/kernel-topics.git is no longer tracked. +Delete it [Y/n]? The remote trovalds https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git is no longer tracked. +Delete it [Y/n]? Done, removed 3 old remote(s). +Adding new remotes... +Adding remote baseline https://github.com/qualcomm-linux/kernel.git qcom-next-staging +Updating baseline +Adding remote tech/bsp/clk https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/clk +Updating tech/bsp/clk +Adding remote tech/bsp/devfreq https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/devfreq +Updating tech/bsp/devfreq +Adding remote tech/bsp/ec https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/ec +Updating tech/bsp/ec +Adding remote tech/bsp/interconnect https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/interconnect +Updating tech/bsp/interconnect +Adding remote tech/mem/secure-buffer https://github.com/qualcomm-linux/kernel-topics.git tech/mem/secure-buffer +Updating tech/mem/secure-buffer +Adding remote tech/security/firmware-smc https://github.com/qualcomm-linux/kernel-topics.git tech/security/firmware-smc +Updating tech/security/firmware-smc +Adding remote tech/bsp/soc-infra https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/soc-infra +Updating tech/bsp/soc-infra +Adding remote tech/debug/soc https://github.com/qualcomm-linux/kernel-topics.git tech/debug/soc +Updating tech/debug/soc +Adding remote tech/bsp/pinctrl https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/pinctrl +Updating tech/bsp/pinctrl +Adding remote tech/bsp/remoteproc https://github.com/qualcomm-linux/kernel-topics.git tech/bsp/remoteproc +Updating tech/bsp/remoteproc +Adding remote tech/bus/peripherals https://github.com/qualcomm-linux/kernel-topics.git tech/bus/peripherals +Updating tech/bus/peripherals +Adding remote tech/bus/pci/all https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/all +Updating tech/bus/pci/all +Adding remote tech/bus/pci/mhi https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/mhi +Updating tech/bus/pci/mhi +Adding remote tech/bus/pci/phy https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/phy +Updating tech/bus/pci/phy +Adding remote tech/bus/pci/pwrctl https://github.com/qualcomm-linux/kernel-topics.git tech/bus/pci/pwrctl +Updating tech/bus/pci/pwrctl +Adding remote tech/bus/usb/dwc https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/dwc +Updating tech/bus/usb/dwc +Adding remote tech/bus/usb/gadget https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/gadget +Updating tech/bus/usb/gadget +Adding remote tech/bus/usb/phy https://github.com/qualcomm-linux/kernel-topics.git tech/bus/usb/phy +Updating tech/bus/usb/phy +Adding remote tech/debug/eud https://github.com/qualcomm-linux/kernel-topics.git tech/debug/eud +Updating tech/debug/eud +Adding remote tech/debug/hwtracing https://github.com/qualcomm-linux/kernel-topics.git tech/debug/hwtracing +Updating tech/debug/hwtracing +Adding remote tech/debug/rdbg https://github.com/qualcomm-linux/kernel-topics.git tech/debug/rdbg +Updating tech/debug/rdbg +Adding remote tech/pmic/backlight https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/backlight +Updating tech/pmic/backlight +Adding remote tech/pmic/mfd https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/mfd +Updating tech/pmic/mfd +Adding remote tech/pmic/misc https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/misc +Updating tech/pmic/misc +Adding remote tech/pmic/regulator https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/regulator +Updating tech/pmic/regulator +Adding remote tech/pmic/supply https://github.com/qualcomm-linux/kernel-topics.git tech/pmic/supply +Updating tech/pmic/supply +Adding remote tech/mem/dma-buf https://github.com/qualcomm-linux/kernel-topics.git tech/mem/dma-buf +Updating tech/mem/dma-buf +Adding remote tech/mem/iommu https://github.com/qualcomm-linux/kernel-topics.git tech/mem/iommu +Updating tech/mem/iommu +Adding remote tech/mm/audio/all https://github.com/qualcomm-linux/kernel-topics.git tech/mm/audio/all +Updating tech/mm/audio/all +Adding remote tech/mm/audio/soundwire https://github.com/qualcomm-linux/kernel-topics.git tech/mm/audio/soundwire +Updating tech/mm/audio/soundwire +Adding remote tech/mm/camss https://github.com/qualcomm-linux/kernel-topics.git tech/mm/camss +Updating tech/mm/camss +Adding remote tech/mm/drm https://github.com/qualcomm-linux/kernel-topics.git tech/mm/drm +Updating tech/mm/drm +Adding remote tech/mm/fastrpc https://github.com/qualcomm-linux/kernel-topics.git tech/mm/fastrpc +Updating tech/mm/fastrpc +Adding remote tech/mm/phy https://github.com/qualcomm-linux/kernel-topics.git tech/mm/phy +Updating tech/mm/phy +Adding remote tech/mm/video https://github.com/qualcomm-linux/kernel-topics.git tech/mm/video +Updating tech/mm/video +Adding remote tech/mm/gpu https://github.com/qualcomm-linux/kernel-topics.git tech/mm/gpu +Updating tech/mm/gpu +Adding remote tech/mproc/rpmsg https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/rpmsg +Updating tech/mproc/rpmsg +Adding remote tech/mproc/qmi https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/qmi +Updating tech/mproc/qmi +Adding remote tech/net/ath https://github.com/qualcomm-linux/kernel-topics.git tech/net/ath +Updating tech/net/ath +Adding remote tech/net/eth https://github.com/qualcomm-linux/kernel-topics.git tech/net/eth +Updating tech/net/eth +Adding remote tech/net/rmnet https://github.com/qualcomm-linux/kernel-topics.git tech/net/rmnet +Updating tech/net/rmnet +Adding remote tech/net/qrtr https://github.com/qualcomm-linux/kernel-topics.git tech/net/qrtr +Updating tech/net/qrtr +Adding remote tech/net/phy https://github.com/qualcomm-linux/kernel-topics.git tech/net/phy +Updating tech/net/phy +Adding remote tech/net/bluetooth https://github.com/qualcomm-linux/kernel-topics.git tech/net/bluetooth +Updating tech/net/bluetooth +Adding remote tech/pm/opp https://github.com/qualcomm-linux/kernel-topics.git tech/pm/opp +Updating tech/pm/opp +Adding remote tech/pm/pmdomain https://github.com/qualcomm-linux/kernel-topics.git tech/pm/pmdomain +Updating tech/pm/pmdomain +Adding remote tech/pm/power https://github.com/qualcomm-linux/kernel-topics.git tech/pm/power +Updating tech/pm/power +Adding remote tech/pm/thermal https://github.com/qualcomm-linux/kernel-topics.git tech/pm/thermal +Updating tech/pm/thermal +Adding remote tech/security/crypto https://github.com/qualcomm-linux/kernel-topics.git tech/security/crypto +Updating tech/security/crypto +Adding remote tech/security/fscrypt https://github.com/qualcomm-linux/kernel-topics.git tech/security/fscrypt +Updating tech/security/fscrypt +Adding remote tech/security/ice https://github.com/qualcomm-linux/kernel-topics.git tech/security/ice +Updating tech/security/ice +Adding remote tech/storage/nvmem https://github.com/qualcomm-linux/kernel-topics.git tech/storage/nvmem +Updating tech/storage/nvmem +Adding remote tech/storage/phy https://github.com/qualcomm-linux/kernel-topics.git tech/storage/phy +Updating tech/storage/phy +Adding remote tech/storage/all https://github.com/qualcomm-linux/kernel-topics.git tech/storage/all +Updating tech/storage/all +Adding remote tech/virt/gunyah https://github.com/qualcomm-linux/kernel-topics.git tech/virt/gunyah +Updating tech/virt/gunyah +Adding remote tech/all/dt/qcs6490 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs6490 +Updating tech/all/dt/qcs6490 +Adding remote tech/all/dt/qcs9100 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs9100 +Updating tech/all/dt/qcs9100 +Adding remote tech/all/dt/qcs8300 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs8300 +Updating tech/all/dt/qcs8300 +Adding remote tech/all/dt/qcs615 https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/qcs615 +Updating tech/all/dt/qcs615 +Adding remote tech/all/dt/agatti https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/agatti +Updating tech/all/dt/agatti +Adding remote tech/all/dt/hamoa https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/hamoa +Updating tech/all/dt/hamoa +Adding remote tech/all/dt/glymur https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/glymur +Updating tech/all/dt/glymur +Adding remote tech/all/dt/kaanapali https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/kaanapali +Updating tech/all/dt/kaanapali +Adding remote tech/all/dt/pakala https://github.com/qualcomm-linux/kernel-topics.git tech/all/dt/pakala +Updating tech/all/dt/pakala +Adding remote tech/all/config https://github.com/qualcomm-linux/kernel-topics.git tech/all/config +Updating tech/all/config +Adding remote tech/overlay/dt https://github.com/qualcomm-linux/kernel-topics.git tech/overlay/dt +Updating tech/overlay/dt +Adding remote tech/all/workaround https://github.com/qualcomm-linux/kernel-topics.git tech/all/workaround +Updating tech/all/workaround +Adding remote tech/mproc/all https://github.com/qualcomm-linux/kernel-topics.git tech/mproc/all +Updating tech/mproc/all +Adding remote tech/noup/debug/all https://github.com/qualcomm-linux/kernel-topics.git tech/noup/debug/all +Updating tech/noup/debug/all +Adding remote tech/hwe/unoq https://github.com/qualcomm-linux/kernel-topics.git tech/hwe/unoq +Updating tech/hwe/unoq +Adding remote early/hwe/shikra/drivers https://github.com/qualcomm-linux/kernel-topics.git early/hwe/shikra/drivers +Updating early/hwe/shikra/drivers +Adding remote early/hwe/shikra/dt https://github.com/qualcomm-linux/kernel-topics.git early/hwe/shikra/dt +Updating early/hwe/shikra/dt +Done, added 73 new remote(s). +Updating the remotes ... +Updating tech/bsp/clk +Updating tech/bsp/devfreq +Updating tech/bsp/ec +Updating tech/bsp/interconnect +Updating tech/mem/secure-buffer +Updating tech/security/firmware-smc +Updating tech/bsp/soc-infra +Updating tech/debug/soc +Updating tech/bsp/pinctrl +Updating tech/bsp/remoteproc +Updating tech/bus/peripherals +Updating tech/bus/pci/all +Updating tech/bus/pci/mhi +Updating tech/bus/pci/phy +Updating tech/bus/pci/pwrctl +Updating tech/bus/usb/dwc +Updating tech/bus/usb/gadget +Updating tech/bus/usb/phy +Updating tech/debug/eud +Updating tech/debug/hwtracing +Updating tech/debug/rdbg +Updating tech/pmic/backlight +Updating tech/pmic/mfd +Updating tech/pmic/misc +Updating tech/pmic/regulator +Updating tech/pmic/supply +Updating tech/mem/dma-buf +Updating tech/mem/iommu +Updating tech/mm/audio/all +Updating tech/mm/audio/soundwire +Updating tech/mm/camss +Updating tech/mm/drm +Updating tech/mm/fastrpc +Updating tech/mm/phy +Updating tech/mm/video +Updating tech/mm/gpu +Updating tech/mproc/rpmsg +Updating tech/mproc/qmi +Updating tech/net/ath +Updating tech/net/eth +Updating tech/net/rmnet +Updating tech/net/qrtr +Updating tech/net/phy +Updating tech/net/bluetooth +Updating tech/pm/opp +Updating tech/pm/pmdomain +Updating tech/pm/power +Updating tech/pm/thermal +Updating tech/security/crypto +Updating tech/security/fscrypt +Updating tech/security/ice +Updating tech/storage/nvmem +Updating tech/storage/phy +Updating tech/storage/all +Updating tech/virt/gunyah +Updating tech/all/dt/qcs6490 +Updating tech/all/dt/qcs9100 +Updating tech/all/dt/qcs8300 +Updating tech/all/dt/qcs615 +Updating tech/all/dt/agatti +Updating tech/all/dt/hamoa +Updating tech/all/dt/glymur +Updating tech/all/dt/kaanapali +Updating tech/all/dt/pakala +Updating tech/all/config +Updating tech/overlay/dt +Updating tech/all/workaround +Updating tech/mproc/all +Updating tech/noup/debug/all +Updating tech/hwe/unoq +Updating early/hwe/shikra/drivers +Updating early/hwe/shikra/dt +Done, updated 0 remote(s). +Updating baseline ... +Fetching baseline +latest tag/id is 5200f5f493f79f14bbdc349e402a40dfb32f23c8 +Done, updated baseline. +Latest tag is 5200f5f493f79f14bbdc349e402a40dfb32f23c8 +Create a new integration branch based on 5200f5f493f79f14bbdc349e402a40dfb32f23c8 +Merging topic branches... +------------------------------------------ + ** Merging topic branch: tech/bsp/clk/tech/bsp/clk +Merge successful : tech/bsp/clk : eea3e9858db5f675261967f5b88b78727049bf98 : 11 +------------------------------------------ + ** Merging topic branch: tech/bsp/devfreq/tech/bsp/devfreq +Merge successful : tech/bsp/devfreq : a0c2f214c89b578a9732844ad8996b65e82ddc77 : 6 +------------------------------------------ + ** Merging topic branch: tech/bsp/ec/tech/bsp/ec +Merge successful : tech/bsp/ec : 643c24b2b397b497d80baf7b4dea28a0a59de898 : 2 +------------------------------------------ + ** Merging topic branch: tech/bsp/interconnect/tech/bsp/interconnect +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/secure-buffer/tech/mem/secure-buffer +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/firmware-smc/tech/security/firmware-smc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/soc-infra/tech/bsp/soc-infra +Merge successful : tech/bsp/soc-infra : 20c09ce873000ed6ee8e4ad9a3ff596f49f63778 : 3 +------------------------------------------ + ** Merging topic branch: tech/debug/soc/tech/debug/soc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/pinctrl/tech/bsp/pinctrl +Merge successful : tech/bsp/pinctrl : 3f1acf892d6623a15a7245d398ae04bb6d1e9f50 : 1 +------------------------------------------ + ** Merging topic branch: tech/bsp/remoteproc/tech/bsp/remoteproc +Merge successful : tech/bsp/remoteproc : a7b9b6d8b0ef8713aea096ed6c6c0fa74db2ed25 : 10 +------------------------------------------ + ** Merging topic branch: tech/bus/peripherals/tech/bus/peripherals +Merge successful : tech/bus/peripherals : 287f0f5c451d23c09c4c15a25cff6c282ab9b13b : 8 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/all/tech/bus/pci/all +Merge successful : tech/bus/pci/all : c266573af0cf27d4d9586ca3984e214ba621028f : 14 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/mhi/tech/bus/pci/mhi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/pci/phy/tech/bus/pci/phy +Merge successful : tech/bus/pci/phy : aaf8ef1234f456bd05343c235d7ad0b921a97220 : 4 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/pwrctl/tech/bus/pci/pwrctl +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/dwc/tech/bus/usb/dwc +Merge successful : tech/bus/usb/dwc : 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 : 2 +------------------------------------------ + ** Merging topic branch: tech/bus/usb/gadget/tech/bus/usb/gadget +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/phy/tech/bus/usb/phy +Merge successful : tech/bus/usb/phy : 8c7f91d8f5390117341ccedf03dbca8620e1fede : 35 +------------------------------------------ + ** Merging topic branch: tech/debug/eud/tech/debug/eud +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/debug/hwtracing/tech/debug/hwtracing +Merge successful : tech/debug/hwtracing : 25c6a748cd3b64e815a8ee8c741a7adcf3852618 : 30 +------------------------------------------ + ** Merging topic branch: tech/debug/rdbg/tech/debug/rdbg +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/backlight/tech/pmic/backlight +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/mfd/tech/pmic/mfd +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/misc/tech/pmic/misc +Merge successful : tech/pmic/misc : ee32a8c23d8ea363b214127b66f1cb16a4432953 : 5 +------------------------------------------ + ** Merging topic branch: tech/pmic/regulator/tech/pmic/regulator +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/supply/tech/pmic/supply +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/dma-buf/tech/mem/dma-buf +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/iommu/tech/mem/iommu +Merge successful : tech/mem/iommu : 1fa98cb308186a3c850369ade7be19f644199f66 : 5 +------------------------------------------ + ** Merging topic branch: tech/mm/audio/all/tech/mm/audio/all +Merge successful : tech/mm/audio/all : cab3357f188207843476df34b2a294a9009efa5b : 10 +------------------------------------------ + ** Merging topic branch: tech/mm/audio/soundwire/tech/mm/audio/soundwire +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/camss/tech/mm/camss +Merge successful : tech/mm/camss : 147ae875b923556a03d9eeb58324e986fd391c24 : 28 +------------------------------------------ + ** Merging topic branch: tech/mm/drm/tech/mm/drm +Merge successful : tech/mm/drm : 2fbdd74ad152cbed32ae7fb4d4be2bec77f2f192 : 60 +------------------------------------------ + ** Merging topic branch: tech/mm/fastrpc/tech/mm/fastrpc +Merge successful : tech/mm/fastrpc : e0ba7183d63d0a96142a2eac288975e0393d172c : 9 +------------------------------------------ + ** Merging topic branch: tech/mm/phy/tech/mm/phy +Merge successful : tech/mm/phy : 56ccbf40aba9e63c5917bd041bc51dce8a05a75d : 1 +------------------------------------------ + ** Merging topic branch: tech/mm/video/tech/mm/video +Merge successful : tech/mm/video : 8bbe314fd7346ec4e74b160b99f54b818af35da2 : 36 +------------------------------------------ + ** Merging topic branch: tech/mm/gpu/tech/mm/gpu +Merge successful : tech/mm/gpu : cee779428b078ee0bf0cad246cb92d692e5e4a41 : 5 +------------------------------------------ + ** Merging topic branch: tech/mproc/rpmsg/tech/mproc/rpmsg +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mproc/qmi/tech/mproc/qmi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/ath/tech/net/ath +Merge successful : tech/net/ath : 850c3c0a83b47e345f1abf5bea36d21044da79cd : 15 +------------------------------------------ + ** Merging topic branch: tech/net/eth/tech/net/eth +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/rmnet/tech/net/rmnet +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/qrtr/tech/net/qrtr +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/phy/tech/net/phy +Merge successful : tech/net/phy : a3602e9cbd3dd4519ddc446ddba1261fe4e156bd : 1 +------------------------------------------ + ** Merging topic branch: tech/net/bluetooth/tech/net/bluetooth +Merge successful : tech/net/bluetooth : 9cca4937e7633b28cefedc4c976f4ca2a0442cb3 : 2 +------------------------------------------ + ** Merging topic branch: tech/pm/opp/tech/pm/opp +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/pmdomain/tech/pm/pmdomain +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/power/tech/pm/power +Merge successful : tech/pm/power : 2d42c35af66ed0db002e2d2d8481719dd05b804b : 9 +------------------------------------------ + ** Merging topic branch: tech/pm/thermal/tech/pm/thermal +Merge successful : tech/pm/thermal : 3f033cbfa8a76a10568dbbe3d1699852f6288851 : 7 +------------------------------------------ + ** Merging topic branch: tech/security/crypto/tech/security/crypto +Merge successful : tech/security/crypto : f030676615c0917a3bb04a3d0f4ca63d7561371b : 14 +------------------------------------------ + ** Merging topic branch: tech/security/fscrypt/tech/security/fscrypt +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/ice/tech/security/ice +Merge successful : tech/security/ice : 1564b829d7522416a7f06506f0c800139c0c1680 : 25 +------------------------------------------ + ** Merging topic branch: tech/storage/nvmem/tech/storage/nvmem +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/phy/tech/storage/phy +Merge successful : tech/storage/phy : cf1667fd75c27b29680062ba04eddb466195156b : 1 +------------------------------------------ + ** Merging topic branch: tech/storage/all/tech/storage/all +Merge successful : tech/storage/all : e254daed78f7b24bf852df097b78455ca142666a : 1 +------------------------------------------ + ** Merging topic branch: tech/virt/gunyah/tech/virt/gunyah +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs6490/tech/all/dt/qcs6490 +Merge successful : tech/all/dt/qcs6490 : 58c1242600cda87a8c2e7a4937dca96b0d7d8e2d : 20 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs9100/tech/all/dt/qcs9100 +Merge successful : tech/all/dt/qcs9100 : b51f0eeb31f509be3067ab34b742fc2479ef93b0 : 18 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs8300/tech/all/dt/qcs8300 +Merge successful : tech/all/dt/qcs8300 : ffd35fec5e1b2ef8197f59f8bdfbcdd9f1931df6 : 16 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs615/tech/all/dt/qcs615 +Merge successful : tech/all/dt/qcs615 : 9e2f111b1297b44c140e3b9c46a2507a3e162741 : 9 +------------------------------------------ + ** Merging topic branch: tech/all/dt/agatti/tech/all/dt/agatti +Merge successful : tech/all/dt/agatti : c828f10cd2c53b7ff2cc061e73b239973ee17bc6 : 1 +------------------------------------------ + ** Merging topic branch: tech/all/dt/hamoa/tech/all/dt/hamoa +Merge successful : tech/all/dt/hamoa : 670d0021452a91a99d66fcef03c0af876b85469f : 29 +------------------------------------------ + ** Merging topic branch: tech/all/dt/glymur/tech/all/dt/glymur +Merge successful : tech/all/dt/glymur : 29aa2aba8e767e1057666a6483923c8da2edd816 : 25 +------------------------------------------ + ** Merging topic branch: tech/all/dt/kaanapali/tech/all/dt/kaanapali +Merge failed, manual merge +No files need merging +[qcom-next 399169427f29] Merge remote-tracking branch tech/all/dt/kaanapali into qcom-next +Merge successful : tech/all/dt/kaanapali : 33d3cd72cd0ee06579a99577fa5a913b58db65c6 : 11 +------------------------------------------ + ** Merging topic branch: tech/all/dt/pakala/tech/all/dt/pakala +Merge successful : tech/all/dt/pakala : fee7c34a4bbc61e8af1b65b450337beca2396f27 : 8 +------------------------------------------ + ** Merging topic branch: tech/all/config/tech/all/config +Merge successful : tech/all/config : ff67f6a055a339d05f0386c7e3bcbfbe3cc472a9 : 61 +------------------------------------------ + ** Merging topic branch: tech/overlay/dt/tech/overlay/dt +Merge successful : tech/overlay/dt : bc664592261b19a8dac0e6ce3c3dd907a225b3e7 : 47 +------------------------------------------ + ** Merging topic branch: tech/all/workaround/tech/all/workaround +Merge failed, manual merge +No files need merging +[qcom-next fd16fe997139] Merge remote-tracking branch tech/all/workaround into qcom-next +Merge successful : tech/all/workaround : d15f5a17f8be4c6116c1a398ab5e6c3a25852ef1 : 15 +------------------------------------------ + ** Merging topic branch: tech/mproc/all/tech/mproc/all +Merge successful : tech/mproc/all : 0aa90b7d45babe6116bcbb3006ae4636256b6e0f : 3 +------------------------------------------ + ** Merging topic branch: tech/noup/debug/all/tech/noup/debug/all +Merge successful : tech/noup/debug/all : d2b684d4e5b36500580ec454a89441903f6ab329 : 25 +------------------------------------------ + ** Merging topic branch: tech/hwe/unoq/tech/hwe/unoq +Merge successful : tech/hwe/unoq : b2ea57bfc5f97af1b5f7b0d750ae315c60921580 : 5 +------------------------------------------ + ** Merging topic branch: early/hwe/shikra/drivers/early/hwe/shikra/drivers +Merge failed, manual merge +No files need merging +[qcom-next a842b21a154d] Merge remote-tracking branch early/hwe/shikra/drivers into qcom-next +Merge successful : early/hwe/shikra/drivers : b26f0d6cd72616e9e8c19142f8e290f6fb262967 : 86 +------------------------------------------ + ** Merging topic branch: early/hwe/shikra/dt/early/hwe/shikra/dt +Merge successful : early/hwe/shikra/dt : 919fd6caf1f2c9a69bf6edcb6acd24a592cd74e3 : 61 +Done, merged 47 topic(s). +[main 850aea9] New rr-cache entries from ci-merge + 2 files changed, 307 insertions(+), 42 deletions(-) + create mode 100644 rr-cache/b86154ddef960120cad1ae8555243b6a74f5f80d/thisimage diff --git a/qcom-next/topic_SHA1 b/qcom-next/topic_SHA1 new file mode 100644 index 0000000000000..ec4ebfd9e248d --- /dev/null +++ b/qcom-next/topic_SHA1 @@ -0,0 +1,49 @@ +Name SHA Commits +------------------------------------------------------------------------------------ +tech/bsp/clk eea3e9858db5f675261967f5b88b78727049bf98 11 +tech/bsp/devfreq a0c2f214c89b578a9732844ad8996b65e82ddc77 6 +tech/bsp/ec 643c24b2b397b497d80baf7b4dea28a0a59de898 2 +tech/bsp/soc-infra 20c09ce873000ed6ee8e4ad9a3ff596f49f63778 3 +tech/bsp/pinctrl 3f1acf892d6623a15a7245d398ae04bb6d1e9f50 1 +tech/bsp/remoteproc a7b9b6d8b0ef8713aea096ed6c6c0fa74db2ed25 10 +tech/bus/peripherals 287f0f5c451d23c09c4c15a25cff6c282ab9b13b 8 +tech/bus/pci/all c266573af0cf27d4d9586ca3984e214ba621028f 14 +tech/bus/pci/phy aaf8ef1234f456bd05343c235d7ad0b921a97220 4 +tech/bus/usb/dwc 49ac8e0eb9656bdaa63dfa8431879f8fe6798742 2 +tech/bus/usb/phy 8c7f91d8f5390117341ccedf03dbca8620e1fede 35 +tech/debug/hwtracing 25c6a748cd3b64e815a8ee8c741a7adcf3852618 30 +tech/pmic/misc ee32a8c23d8ea363b214127b66f1cb16a4432953 5 +tech/mem/iommu 1fa98cb308186a3c850369ade7be19f644199f66 5 +tech/mm/audio/all cab3357f188207843476df34b2a294a9009efa5b 10 +tech/mm/camss 147ae875b923556a03d9eeb58324e986fd391c24 28 +tech/mm/drm 2fbdd74ad152cbed32ae7fb4d4be2bec77f2f192 60 +tech/mm/fastrpc e0ba7183d63d0a96142a2eac288975e0393d172c 9 +tech/mm/phy 56ccbf40aba9e63c5917bd041bc51dce8a05a75d 1 +tech/mm/video 8bbe314fd7346ec4e74b160b99f54b818af35da2 36 +tech/mm/gpu cee779428b078ee0bf0cad246cb92d692e5e4a41 5 +tech/net/ath 850c3c0a83b47e345f1abf5bea36d21044da79cd 15 +tech/net/phy a3602e9cbd3dd4519ddc446ddba1261fe4e156bd 1 +tech/net/bluetooth 9cca4937e7633b28cefedc4c976f4ca2a0442cb3 2 +tech/pm/power 2d42c35af66ed0db002e2d2d8481719dd05b804b 9 +tech/pm/thermal 3f033cbfa8a76a10568dbbe3d1699852f6288851 7 +tech/security/crypto f030676615c0917a3bb04a3d0f4ca63d7561371b 14 +tech/security/ice 1564b829d7522416a7f06506f0c800139c0c1680 25 +tech/storage/phy cf1667fd75c27b29680062ba04eddb466195156b 1 +tech/storage/all e254daed78f7b24bf852df097b78455ca142666a 1 +tech/all/dt/qcs6490 58c1242600cda87a8c2e7a4937dca96b0d7d8e2d 20 +tech/all/dt/qcs9100 b51f0eeb31f509be3067ab34b742fc2479ef93b0 18 +tech/all/dt/qcs8300 ffd35fec5e1b2ef8197f59f8bdfbcdd9f1931df6 16 +tech/all/dt/qcs615 9e2f111b1297b44c140e3b9c46a2507a3e162741 9 +tech/all/dt/agatti c828f10cd2c53b7ff2cc061e73b239973ee17bc6 1 +tech/all/dt/hamoa 670d0021452a91a99d66fcef03c0af876b85469f 29 +tech/all/dt/glymur 29aa2aba8e767e1057666a6483923c8da2edd816 25 +tech/all/dt/kaanapali 33d3cd72cd0ee06579a99577fa5a913b58db65c6 11 +tech/all/dt/pakala fee7c34a4bbc61e8af1b65b450337beca2396f27 8 +tech/all/config ff67f6a055a339d05f0386c7e3bcbfbe3cc472a9 61 +tech/overlay/dt bc664592261b19a8dac0e6ce3c3dd907a225b3e7 47 +tech/all/workaround d15f5a17f8be4c6116c1a398ab5e6c3a25852ef1 15 +tech/mproc/all 0aa90b7d45babe6116bcbb3006ae4636256b6e0f 3 +tech/noup/debug/all d2b684d4e5b36500580ec454a89441903f6ab329 25 +tech/hwe/unoq b2ea57bfc5f97af1b5f7b0d750ae315c60921580 5 +early/hwe/shikra/drivers b26f0d6cd72616e9e8c19142f8e290f6fb262967 86 +early/hwe/shikra/dt 919fd6caf1f2c9a69bf6edcb6acd24a592cd74e3 61 From 2fd1cb84e069b1299e40b92b681aef875b15a921 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Tue, 19 May 2026 16:19:51 +0530 Subject: [PATCH 124/128] FROMLIST: arm64: dts: qcom: glymur: Enable SPEL powercap driver The Qualcomm SoC Power and Electrical Limits (SPEL) provides hardware based power monitoring and limiting capabilities for various power domains including System, SoC, CPU clusters, GPU, and various other subsystems for glymur. Signed-off-by: Manaf Meethalavalappu Pallikunhi Link: https://patch.msgid.link/20260519-qcom_spel_driver_upstream-v1-3-75356d1b7f94@oss.qualcomm.com --- arch/arm64/boot/dts/qcom/glymur.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 939140ef9ea38..5d2f05b9fbc8b 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -6028,6 +6028,16 @@ }; }; + power-controller@ef3b000 { + compatible = "qcom,spel"; + reg = <0x0 0x0ef3e000 0x0 0x1000>, + <0x0 0x0ef3d000 0x0 0x1000>, + <0x0 0x0ef3b000 0x0 0x1000>; + reg-names = "nodes", + "constraints", + "config"; + }; + tlmm: pinctrl@f100000 { compatible = "qcom,glymur-tlmm"; reg = <0x0 0x0f100000 0x0 0xf00000>; From aca2e0c017dc7801ff4846d5d2dabd1beea6f183 Mon Sep 17 00:00:00 2001 From: Saurabh Anand Date: Thu, 21 May 2026 16:52:11 +0530 Subject: [PATCH 125/128] FROMLIST: arm64: dts: qcom: glymur: Configure DP endpoints for 2-lane operation Add explicit data-lanes to the MDSS DP output endpoints to enable display port in 2 lanes configuration and disable the mode-switch property from the USB QMP PHY node. Signed-off-by: Saurabh Anand Link: https://lore.kernel.org/all/20260521120058.2966709-1-saurabh.anand@oss.qualcomm.com/ --- arch/arm64/boot/dts/qcom/glymur.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index 5d2f05b9fbc8b..f4240190a36d9 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi @@ -2509,7 +2509,6 @@ #clock-cells = <1>; #phy-cells = <1>; - mode-switch; orientation-switch; status = "disabled"; @@ -2583,7 +2582,6 @@ #clock-cells = <1>; #phy-cells = <1>; - mode-switch; orientation-switch; status = "disabled"; @@ -5545,6 +5543,7 @@ reg = <1>; mdss_dp0_out: endpoint { + data-lanes = <0 1>; remote-endpoint = <&usb_dp_qmpphy_dp_in>; }; }; @@ -5636,6 +5635,7 @@ reg = <1>; mdss_dp1_out: endpoint { + data-lanes = <0 1>; remote-endpoint = <&usb_1_qmpphy_dp_in>; }; }; From df3ae9703774b70a7b7758b53498a25de9f87174 Mon Sep 17 00:00:00 2001 From: Aastha Pandey Date: Tue, 19 May 2026 19:17:34 +0530 Subject: [PATCH 126/128] QCLINUX: defconfig: Enable Qualcomm SPEL driver The Qualcomm SoC Power and Electrical Limits (SPEL) provides hardware based power monitoring and limiting capabilities for various power domains including System, SoC, CPU clusters, GPU, and various other subsystems. The driver integrates with the Linux powercap framework, exposing SPEL capabilities through powercap sysfs interfaces. This allows userspace applications and thermal management daemons to monitor energy consumption and configure power limits for optimal power/performance balance. Signed-off-by: Aastha Pandey --- arch/arm64/configs/qcom.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/qcom.config b/arch/arm64/configs/qcom.config index 9de3118a8f584..3cfe0efb06c86 100644 --- a/arch/arm64/configs/qcom.config +++ b/arch/arm64/configs/qcom.config @@ -49,6 +49,7 @@ CONFIG_POWERCAP=y CONFIG_PROC_EVENTS=y CONFIG_QCA808X_PHY=m CONFIG_QCOM_QMI_COOLING=y +CONFIG_QCOM_SPEL=m CONFIG_QCOM_TGU=m CONFIG_REMOTEPROC_THERMAL=y CONFIG_SCHED_DEBUG=y From c3b68405a8a19fc05beb4a97c7b7ee0dc7944ac0 Mon Sep 17 00:00:00 2001 From: Sunyun Yang Date: Thu, 7 May 2026 10:42:13 +0800 Subject: [PATCH 127/128] dt-bindings: bridge: Add Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver LT9611C(EX/UXD) is an I2C-controlled chip that Receiver signal/dual port mipi dsi and output hdmi, differences in hardware features: - LT9611C: supports 1-port mipi dsi to hdmi 1.4 - LT9611EX: supports 2-port mipi dsi to hdmi 1.4 - LT9611UXD: supports 2-port mipi dsi to hdmi 1.4/2.0 Link : https://lore.kernel.org/lkml/20260508134009.4582-3-syyang@lontium.com/ Signed-off-by: Sunyun Yang Signed-off-by: Mohit Dsor --- .../bindings/display/bridge/lontium,lt9611.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml index 429a06057ae85..b20a43456b017 100644 --- a/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml @@ -4,19 +4,23 @@ $id: http://devicetree.org/schemas/display/bridge/lontium,lt9611.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Lontium LT9611(UXC) 2 Port MIPI to HDMI Bridge +title: Lontium LT9611(UXC/C/EX/UXD) 2 Port MIPI DSI to HDMI Bridge maintainers: - Vinod Koul description: | - The LT9611 and LT9611UXC are bridge devices which convert DSI to HDMI + The LT9611、LT9611UXC、LT9611C、LT9611EX and LT9611UXD + are bridge devices which convert DSI to HDMI properties: compatible: enum: - lontium,lt9611 - lontium,lt9611uxc + - lontium,lt9611c + - lontium,lt9611ex + - lontium,lt9611uxd reg: maxItems: 1 From 049d3ab5041ceb4acb8235b9de2f2b93c8003ae1 Mon Sep 17 00:00:00 2001 From: Sunyun Yang Date: Thu, 7 May 2026 10:42:14 +0800 Subject: [PATCH 128/128] drm/bridge: Add Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver LT9611C(EX/UXD) is an I2C-controlled chip that Receiver signal/dual port mipi dsi and output hdmi, differences in hardware features: - LT9611C: supports 1-port mipi dsi to hdmi 1.4 - LT9611EX: supports 2-port mipi dsi to hdmi 1.4 - LT9611UXD: supports 2-port mipi dsi to hdmi 1.4/2.0 Link : https://lore.kernel.org/lkml/20260508134009.4582-3-syyang@lontium.com/ Signed-off-by: Sunyun Yang Signed-off-by: Mohit Dsor Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/Kconfig | 18 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/lontium-lt9611c.c | 1240 ++++++++++++++++++++++ 3 files changed, 1259 insertions(+) create mode 100644 drivers/gpu/drm/bridge/lontium-lt9611c.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index c3209b0f46786..32b85a2a65d9c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -177,6 +177,24 @@ config DRM_LONTIUM_LT9611 HDMI signals Please say Y if you have such hardware. +config DRM_LONTIUM_LT9611C + tristate "Lontium LT9611C DSI/HDMI bridge" + select SND_SOC_HDMI_CODEC if SND_SOC + depends on OF + select CRC8 + select FW_LOADER + select DRM_PANEL_BRIDGE + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_HDMI_STATE_HELPER + select REGMAP_I2C + help + Driver for Lontium DSI to HDMI bridge + chip driver that converts dual DSI and I2S to + HDMI signals + Please say Y if you have such hardware. + config DRM_LONTIUM_LT9611UXC tristate "Lontium LT9611UXC DSI/HDMI bridge" select SND_SOC_HDMI_CODEC if SND_SOC diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index beab5b695a6e1..92688be9692fb 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o obj-$(CONFIG_DRM_LONTIUM_LT9211) += lontium-lt9211.o obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o +obj-$(CONFIG_DRM_LONTIUM_LT9611C) += lontium-lt9611c.o obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o obj-$(CONFIG_DRM_LONTIUM_LT8713SX) += lontium-lt8713sx.o obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o diff --git a/drivers/gpu/drm/bridge/lontium-lt9611c.c b/drivers/gpu/drm/bridge/lontium-lt9611c.c new file mode 100644 index 0000000000000..16c40b4535681 --- /dev/null +++ b/drivers/gpu/drm/bridge/lontium-lt9611c.c @@ -0,0 +1,1240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Lontium Semiconductor, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FW_SIZE (64 * 1024) +#define LT_PAGE_SIZE 256 +#define FW_FILE "Lontium/lt9611c_fw.bin" +#define LT9611C_CRC_POLYNOMIAL 0x31 +#define LT9611C_PAGE_CONTROL 0xff + +enum lt9611_chip_type { + CHIP_LT9611C = 0, + CHIP_LT9611EX, + CHIP_LT9611UXD, +}; + +struct lt9611c { + struct device *dev; + struct i2c_client *client; + struct drm_bridge bridge; + struct regmap *regmap; + /* Protects all accesses to registers by stopping the on-chip MCU */ + struct mutex ocm_lock; + struct work_struct work; + struct device_node *dsi0_node; + struct device_node *dsi1_node; + struct mipi_dsi_device *dsi0; + struct mipi_dsi_device *dsi1; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[2]; + int fw_version; + /* Chip variant: C/EX/UXD */ + enum lt9611_chip_type chip_type; + /* HDMI cable connection status */ + bool hdmi_connected; +}; + +DECLARE_CRC8_TABLE(lt9611c_crc8_table); + +static const struct regmap_range_cfg lt9611c_ranges[] = { + { + .name = "register_range", + .range_min = 0, + .range_max = 0xfe9c, + .selector_reg = LT9611C_PAGE_CONTROL, + .selector_mask = 0xff, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x100, + }, +}; + +static const struct regmap_config lt9611c_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xfe9c, + .ranges = lt9611c_ranges, + .num_ranges = ARRAY_SIZE(lt9611c_ranges), +}; + +static int lt9611c_read_write_flow(struct lt9611c *lt9611c, u8 *params, + unsigned int param_count, u8 *return_buffer, + unsigned int return_count) +{ + int ret; + unsigned int i; + unsigned int temp; + unsigned int max_params = 0xe0dd - 0xe0b0 + 1; + + regmap_write(lt9611c->regmap, 0xe0de, 0x01); + + ret = regmap_read_poll_timeout(lt9611c->regmap, 0xe0ae, temp, + temp == 0x01, 1000, 100 * 1000); + if (ret) + return -ETIMEDOUT; + + for (i = 0; i < param_count && i < max_params; i++) + regmap_write(lt9611c->regmap, 0xe0b0 + i, params[i]); + + regmap_write(lt9611c->regmap, 0xe0de, 0x02); + + ret = regmap_read_poll_timeout(lt9611c->regmap, 0xe0ae, temp, + temp == 0x02, 1000, 100 * 1000); + if (ret) + return -ETIMEDOUT; + + return regmap_bulk_read(lt9611c->regmap, 0xe085, return_buffer, + return_count); +} + +static void lt9611c_config_parameters(struct lt9611c *lt9611c) +{ + const struct reg_sequence seq_write_paras[] = { + REG_SEQ0(0xe0ee, 0x01), + REG_SEQ0(0xe103, 0x3f), /*fifo rst*/ + REG_SEQ0(0xe103, 0xff), + REG_SEQ0(0xe05e, 0xc1), + REG_SEQ0(0xe058, 0x00), + REG_SEQ0(0xe059, 0x50), + REG_SEQ0(0xe05a, 0x10), + REG_SEQ0(0xe05a, 0x00), + REG_SEQ0(0xe058, 0x21), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write_paras, ARRAY_SIZE(seq_write_paras)); +} + +static void lt9611c_wren(struct lt9611c *lt9611c) +{ + regmap_write(lt9611c->regmap, 0xe05a, 0x04); + regmap_write(lt9611c->regmap, 0xe05a, 0x00); +} + +static void lt9611c_wrdi(struct lt9611c *lt9611c) +{ + regmap_write(lt9611c->regmap, 0xe05a, 0x08); + regmap_write(lt9611c->regmap, 0xe05a, 0x00); +} + +static void lt9611c_erase_op(struct lt9611c *lt9611c, u32 addr) +{ + const struct reg_sequence seq_write[] = { + REG_SEQ0(0xe0ee, 0x01), + REG_SEQ0(0xe05a, 0x04), + REG_SEQ0(0xe05a, 0x00), + REG_SEQ0(0xe05b, (addr >> 16) & 0xff), + REG_SEQ0(0xe05c, (addr >> 8) & 0xff), + REG_SEQ0(0xe05d, addr & 0xff), + REG_SEQ0(0xe05a, 0x01), + REG_SEQ0(0xe05a, 0x00), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write, ARRAY_SIZE(seq_write)); +} + +static void read_flash_reg_status(struct lt9611c *lt9611c, unsigned int *status) +{ + const struct reg_sequence seq_write[] = { + REG_SEQ0(0xe103, 0x3f), + REG_SEQ0(0xe103, 0xff), + REG_SEQ0(0xe05e, 0x40), + REG_SEQ0(0xe056, 0x05), + REG_SEQ0(0xe055, 0x25), + REG_SEQ0(0xe055, 0x01), + REG_SEQ0(0xe058, 0x21), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write, ARRAY_SIZE(seq_write)); + + regmap_read(lt9611c->regmap, 0xe05f, status); +} + +static void lt9611c_crc_to_sram(struct lt9611c *lt9611c) +{ + const struct reg_sequence seq_write[] = { + REG_SEQ0(0xe051, 0x00), + REG_SEQ0(0xe055, 0xc0), + REG_SEQ0(0xe055, 0x80), + REG_SEQ0(0xe05e, 0xc0), + REG_SEQ0(0xe058, 0x21), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write, ARRAY_SIZE(seq_write)); +} + +static void lt9611c_data_to_sram(struct lt9611c *lt9611c) +{ + const struct reg_sequence seq_write[] = { + REG_SEQ0(0xe051, 0xff), + REG_SEQ0(0xe055, 0x80), + REG_SEQ0(0xe05e, 0xc0), + REG_SEQ0(0xe058, 0x21), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write, ARRAY_SIZE(seq_write)); +} + +static void lt9611c_sram_to_flash(struct lt9611c *lt9611c, size_t addr) +{ + const struct reg_sequence seq_write[] = { + REG_SEQ0(0xe05b, (addr >> 16) & 0xff), + REG_SEQ0(0xe05c, (addr >> 8) & 0xff), + REG_SEQ0(0xe05d, addr & 0xff), + REG_SEQ0(0xe05a, 0x30), + REG_SEQ0(0xe05a, 0x00), + }; + + regmap_multi_reg_write(lt9611c->regmap, seq_write, ARRAY_SIZE(seq_write)); +} + +static void lt9611c_block_erase(struct lt9611c *lt9611c) +{ + struct device *dev = lt9611c->dev; + int i; + unsigned int block_num; + unsigned int flash_status = 0; + u32 flash_addr = 0; + + for (block_num = 0; block_num < 2; block_num++) { + flash_addr = (block_num * 0x008000); + lt9611c_erase_op(lt9611c, flash_addr); + msleep(100); + i = 0; + while (1) { + read_flash_reg_status(lt9611c, &flash_status); + if ((flash_status & 0x01) == 0) + break; + + if (i > 50) + break; + + i++; + msleep(50); + } + } + + dev_dbg(dev, "erase flash done.\n"); +} + +static int lt9611c_write_data(struct lt9611c *lt9611c, const struct firmware *fw, size_t addr) +{ + struct device *dev = lt9611c->dev; + int ret; + unsigned int page = 0, num = 0, i = 0; + size_t size, index; + const u8 *data; + u8 value; + + data = fw->data; + size = fw->size; + page = (size + LT_PAGE_SIZE - 1) / LT_PAGE_SIZE; + if (page * LT_PAGE_SIZE > FW_SIZE) { + dev_err(dev, "firmware size out of range\n"); + return -EINVAL; + } + + dev_dbg(dev, "%u pages, total size %zu byte\n", page, size); + + for (num = 0; num < page; num++) { + lt9611c_data_to_sram(lt9611c); + + for (i = 0; i < LT_PAGE_SIZE; i++) { + index = num * LT_PAGE_SIZE + i; + value = (index < size) ? data[index] : 0xff; + + ret = regmap_write(lt9611c->regmap, 0xe059, value); + if (ret < 0) { + dev_err(dev, "write error at page %u, index %u\n", num, i); + return ret; + } + } + + lt9611c_wren(lt9611c); + lt9611c_sram_to_flash(lt9611c, addr); + + addr += LT_PAGE_SIZE; + } + + lt9611c_wrdi(lt9611c); + + return 0; +} + +static int lt9611c_write_crc(struct lt9611c *lt9611c, u8 fw_crc, size_t addr) +{ + struct device *dev = lt9611c->dev; + int ret; + + lt9611c_crc_to_sram(lt9611c); + ret = regmap_write(lt9611c->regmap, 0xe059, fw_crc); + if (ret < 0) { + dev_err(dev, "failed to write crc\n"); + return ret; + } + + lt9611c_wren(lt9611c); + lt9611c_sram_to_flash(lt9611c, addr); + lt9611c_wrdi(lt9611c); + + dev_dbg(dev, "crc 0x%02x written to flash at addr 0x%zx\n", fw_crc, addr); + + return 0; +} + +static void lt9611c_reset(struct lt9611c *lt9611c) +{ + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1); + msleep(20); + + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); + msleep(20); + + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1); + msleep(400); + + dev_dbg(lt9611c->dev, "lt9611c reset"); +} + +static int lt9611c_upgrade_result(struct lt9611c *lt9611c, u8 fw_crc) +{ + struct device *dev = lt9611c->dev; + unsigned int crc_result; + + regmap_write(lt9611c->regmap, 0xe0ee, 0x01); + regmap_read(lt9611c->regmap, 0xe021, &crc_result); + + if (crc_result != fw_crc) { + dev_err(dev, "lt9611c fw upgrade failed, expected crc=0x%02x, read crc=0x%02x\n", + fw_crc, crc_result); + return -1; + } + + dev_dbg(dev, "lt9611c firmware upgrade success, crc=0x%02x\n", crc_result); + return 0; +} + +static int lt9611c_firmware_upgrade(struct lt9611c *lt9611c) +{ + struct device *dev = lt9611c->dev; + const struct firmware *fw; + u8 *buffer; + size_t total_size = FW_SIZE - 1; + u8 fw_crc; + int ret; + + /*1. load firmware*/ + ret = request_firmware(&fw, FW_FILE, dev); + if (ret) + return dev_err_probe(dev, ret, "failed to load '%s'\n", FW_FILE); + + /*2. check size*/ + if (fw->size > total_size) { + dev_err(dev, "firmware too large (%zu > %zu)\n", fw->size, total_size); + ret = -EINVAL; + goto out_release_fw; + } + dev_dbg(dev, "firmware size: %zu bytes\n", fw->size); + + /*3. calculate crc8 */ + buffer = kzalloc(total_size, GFP_KERNEL); + if (!buffer) { + ret = -ENOMEM; + goto out_release_fw; + } + + memset(buffer, 0xff, total_size); + memcpy(buffer, fw->data, fw->size); + + fw_crc = crc8(lt9611c_crc8_table, buffer, total_size, 0); + kfree(buffer); + + dev_dbg(dev, "firmware crc: 0x%02x\n", fw_crc); + dev_dbg(dev, "starting firmware upgrade, size: %zu bytes\n", fw->size); + + lt9611c_config_parameters(lt9611c); + lt9611c_block_erase(lt9611c); + + ret = lt9611c_write_data(lt9611c, fw, 0); + if (ret < 0) { + dev_err(dev, "failed to write firmware data\n"); + goto out_release_fw; + } + + ret = lt9611c_write_crc(lt9611c, fw_crc, FW_SIZE - 1); + if (ret < 0) { + dev_err(dev, "failed to write firmware crc\n"); + goto out_release_fw; + } + + /*5. check upgrade of result*/ + lt9611c_reset(lt9611c); + ret = lt9611c_upgrade_result(lt9611c, fw_crc); + +out_release_fw: + release_firmware(fw); + return ret; +} + +static struct lt9611c *bridge_to_lt9611c(struct drm_bridge *bridge) +{ + return container_of(bridge, struct lt9611c, bridge); +} + +/*read only*/ +static const struct lt9611c *bridge_to_lt9611c_const(const struct drm_bridge *bridge) +{ + return container_of(bridge, const struct lt9611c, bridge); +} + +static void lt9611c_lock(struct lt9611c *lt9611c) +{ + mutex_lock(<9611c->ocm_lock); + regmap_write(lt9611c->regmap, 0xe0ee, 0x01); +} + +static void lt9611c_unlock(struct lt9611c *lt9611c) +{ + regmap_write(lt9611c->regmap, 0xe0ee, 0x00); + mutex_unlock(<9611c->ocm_lock); +} + +static irqreturn_t lt9611c_irq_thread_handler(int irq, void *dev_id) +{ + struct lt9611c *lt9611c = dev_id; + struct device *dev = lt9611c->dev; + int ret; + unsigned int irq_status; + u8 cmd[5] = {0x52, 0x48, 0x31, 0x3a, 0x00}; + u8 data[5]; + + guard(mutex)(<9611c->ocm_lock); + + ret = regmap_read(lt9611c->regmap, 0xe084, &irq_status); + if (ret) { + dev_err(dev, "failed to read irq status: %d\n", ret); + return IRQ_HANDLED; + } + + if (!(irq_status & BIT(0))) + return IRQ_HANDLED; + + ret = lt9611c_read_write_flow(lt9611c, cmd, ARRAY_SIZE(cmd), data, ARRAY_SIZE(data)); + if (ret) { + dev_err(dev, "failed to read HPD status\n"); + } else { + lt9611c->hdmi_connected = (data[4] == 0x02); + dev_dbg(dev, "HDMI %s\n", lt9611c->hdmi_connected ? "connected" : "disconnected"); + } + + /*Clear interrupt: hardware requires two writes with delay*/ + regmap_write(lt9611c->regmap, 0xe0df, irq_status & BIT(0)); + usleep_range(10000, 12000); + regmap_write(lt9611c->regmap, 0xe0df, irq_status & (~BIT(0))); + + schedule_work(<9611c->work); + + return IRQ_HANDLED; +} + +static void lt9611c_hpd_work(struct work_struct *work) +{ + struct lt9611c *lt9611c = container_of(work, struct lt9611c, work); + bool connected; + + mutex_lock(<9611c->ocm_lock); + connected = lt9611c->hdmi_connected; + mutex_unlock(<9611c->ocm_lock); + + drm_bridge_hpd_notify(<9611c->bridge, + connected ? connector_status_connected : + connector_status_disconnected); +} + +static int lt9611c_regulator_init(struct lt9611c *lt9611c) +{ + struct device *dev = lt9611c->dev; + int ret; + + lt9611c->supplies[0].supply = "vcc"; + lt9611c->supplies[1].supply = "vdd"; + + ret = devm_regulator_bulk_get(dev, 2, lt9611c->supplies); + + return ret; +} + +static struct mipi_dsi_device *lt9611c_attach_dsi(struct lt9611c *lt9611c, + struct device_node *dsi_node) +{ + const struct mipi_dsi_device_info info = { "lt9611c", 0, NULL }; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + struct device *dev = lt9611c->dev; + int ret; + + host = of_find_mipi_dsi_host_by_node(dsi_node); + if (!host) + return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n")); + + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + if (IS_ERR(dsi)) + return ERR_PTR(dev_err_probe(dev, PTR_ERR(dsi), "failed to create dsi device\n")); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_VIDEO_HSE; + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) + return ERR_PTR(dev_err_probe(dev, ret, "failed to attach dsi to host\n")); + + return dsi; +} + +static int lt9611c_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, + enum drm_bridge_attach_flags flags) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + + return drm_bridge_attach(encoder, lt9611c->bridge.next_bridge, bridge, flags); +} + +static enum drm_mode_status +lt9611c_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, + const struct drm_display_mode *mode, + unsigned long long tmds_rate) +{ + const struct lt9611c *lt9611c = bridge_to_lt9611c_const(bridge); + + if (lt9611c->chip_type == CHIP_LT9611UXD) { + if (tmds_rate > 600000000) + return MODE_CLOCK_HIGH; + + } else { + if (tmds_rate > 340000000) + return MODE_CLOCK_HIGH; + } + + if (tmds_rate < 25000000) + return MODE_CLOCK_LOW; + + return MODE_OK; +} + +static void lt9611c_video_setup(struct lt9611c *lt9611c, + const struct drm_display_mode *mode) +{ + struct device *dev = lt9611c->dev; + int ret; + u32 h_total, hactive, hsync_len, hfront_porch, hback_porch; + u32 v_total, vactive, vsync_len, vfront_porch, vback_porch; + u8 timing_set_cmd[26] = {0x57, 0x4d, 0x33, 0x3a}; + u8 return_param[3]; + u8 framerate; + u8 vic = 0x00; + + guard(mutex)(<9611c->ocm_lock); + h_total = mode->htotal; + hactive = mode->hdisplay; + hsync_len = mode->hsync_end - mode->hsync_start; + hfront_porch = mode->hsync_start - mode->hdisplay; + hback_porch = mode->htotal - mode->hsync_end; + + v_total = mode->vtotal; + vactive = mode->vdisplay; + vsync_len = mode->vsync_end - mode->vsync_start; + vfront_porch = mode->vsync_start - mode->vdisplay; + vback_porch = mode->vtotal - mode->vsync_end; + framerate = drm_mode_vrefresh(mode); + vic = drm_match_cea_mode(mode); + + dev_dbg(dev, "hactive=%d, vactive=%d\n", hactive, vactive); + dev_dbg(dev, "framerate=%d\n", framerate); + dev_dbg(dev, "vic = 0x%02x\n", vic); + + timing_set_cmd[4] = (h_total >> 8) & 0xff; + timing_set_cmd[5] = h_total & 0xff; + timing_set_cmd[6] = (hactive >> 8) & 0xff; + timing_set_cmd[7] = hactive & 0xff; + timing_set_cmd[8] = (hfront_porch >> 8) & 0xff; + timing_set_cmd[9] = hfront_porch & 0xff; + timing_set_cmd[10] = (hsync_len >> 8) & 0xff; + timing_set_cmd[11] = hsync_len & 0xff; + timing_set_cmd[12] = (hback_porch >> 8) & 0xff; + timing_set_cmd[13] = hback_porch & 0xff; + timing_set_cmd[14] = (v_total >> 8) & 0xff; + timing_set_cmd[15] = v_total & 0xff; + timing_set_cmd[16] = (vactive >> 8) & 0xff; + timing_set_cmd[17] = vactive & 0xFF; + timing_set_cmd[18] = (vfront_porch >> 8) & 0xff; + timing_set_cmd[19] = vfront_porch & 0xff; + timing_set_cmd[20] = (vsync_len >> 8) & 0xff; + timing_set_cmd[21] = vsync_len & 0xff; + timing_set_cmd[22] = (vback_porch >> 8) & 0xff; + timing_set_cmd[23] = vback_porch & 0xff; + timing_set_cmd[24] = framerate; + timing_set_cmd[25] = vic; + + ret = lt9611c_read_write_flow(lt9611c, + timing_set_cmd, ARRAY_SIZE(timing_set_cmd), + return_param, ARRAY_SIZE(return_param)); + if (ret) + dev_err(dev, "video set failed\n"); +} + +static void lt9611c_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + if (ret) + dev_err(lt9611c->dev, "regulator bulk enable failed.\n"); + lt9611c_reset(lt9611c); +} + +static void lt9611c_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + struct drm_display_mode *mode; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!conn_state)) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (WARN_ON(!crtc_state)) + return; + + mode = &crtc_state->adjusted_mode; + + lt9611c_video_setup(lt9611c, mode); +} + +static void lt9611c_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + int ret; + + ret = regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + if (ret) + dev_err(lt9611c->dev, "regulator bulk disable failed.\n"); + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); +} + +static enum drm_connector_status +lt9611c_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + struct device *dev = lt9611c->dev; + int ret; + bool connected = false; + u8 cmd[5] = {0x52, 0x48, 0x31, 0x3a, 0x00}; + u8 data[5]; + + guard(mutex)(<9611c->ocm_lock); + + ret = lt9611c_read_write_flow(lt9611c, cmd, ARRAY_SIZE(cmd), data, ARRAY_SIZE(data)); + if (ret) + dev_err(dev, "failed to read HPD status (err=%d)\n", ret); + else + connected = (data[4] == 0x02); + + lt9611c->hdmi_connected = connected; + + return connected ? connector_status_connected : + connector_status_disconnected; +} + +static int lt9611c_get_edid_block(void *data, u8 *buf, + unsigned int block, size_t len) +{ + struct lt9611c *lt9611c = data; + struct device *dev = lt9611c->dev; + u8 cmd[5] = {0x52, 0x48, 0x33, 0x3a, 0x00}; + u8 packet[37]; + int ret, i, offset = 0; + + if (len != 128) + return -EINVAL; + guard(mutex)(<9611c->ocm_lock); + + for (i = 0; i < 4; i++) { + cmd[4] = block * 4 + i; + ret = lt9611c_read_write_flow(lt9611c, cmd, ARRAY_SIZE(cmd), + packet, ARRAY_SIZE(packet)); + if (ret) { + dev_err(dev, "Failed to read EDID block %u packet %d\n", + block, i); + return ret; + } + memcpy(buf + offset, &packet[5], 32); + offset += 32; + } + + return 0; +} + +static const struct drm_edid *lt9611c_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + + return drm_edid_read_custom(connector, lt9611c_get_edid_block, lt9611c); +} + +static int lt9611c_hdmi_write_avi_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + u8 *cmd; + u8 data[5]; + int ret; + + guard(mutex)(<9611c->ocm_lock); + + cmd = kmalloc(5 + len, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd[0] = 0x57; + cmd[1] = 0x48; + cmd[2] = 0x35; + cmd[3] = 0x3a; + cmd[4] = 0x01;/*write avi*/ + memcpy(cmd + 5, buffer, len); + + ret = lt9611c_read_write_flow(lt9611c, cmd, 5 + len, + data, ARRAY_SIZE(data)); + kfree(cmd); + + if (ret < 0) { + dev_err(lt9611c->dev, "write avi infoframe failed!\n"); + return ret; + } + + return 0; +} + +static int lt9611c_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + u8 cmd[5] = {0x57, 0x48, 0x42, 0x3a, 0x01}; + u8 data[5]; + int ret; + + guard(mutex)(<9611c->ocm_lock); + + ret = lt9611c_read_write_flow(lt9611c, cmd, ARRAY_SIZE(cmd), + data, ARRAY_SIZE(data)); + + if (ret < 0) { + dev_err(lt9611c->dev, "clear avi infoframe failed!\n"); + return ret; + } + + return 0; +} + +static int lt9611c_hdmi_write_audio_infoframe(struct drm_bridge *bridge, + const u8 *buffer, size_t len) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + u8 *cmd; + u8 data[5]; + int ret; + + guard(mutex)(<9611c->ocm_lock); + + cmd = kmalloc(5 + len, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd[0] = 0x57; + cmd[1] = 0x48; + cmd[2] = 0x35; + cmd[3] = 0x3a; + cmd[4] = 0x02;/*write audio*/ + memcpy(cmd + 5, buffer, len); + + ret = lt9611c_read_write_flow(lt9611c, cmd, 5 + len, + data, ARRAY_SIZE(data)); + + kfree(cmd); + + if (ret < 0) { + dev_err(lt9611c->dev, "write audio infoframe failed!\n"); + return ret; + } + + return 0; +} + +static int lt9611c_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + u8 cmd[5] = {0x57, 0x48, 0x42, 0x3a, 0x02}; + u8 data[5]; + int ret; + + guard(mutex)(<9611c->ocm_lock); + + ret = lt9611c_read_write_flow(lt9611c, cmd, ARRAY_SIZE(cmd), + data, ARRAY_SIZE(data)); + + if (ret < 0) { + dev_err(lt9611c->dev, "clear audio infoframe failed!\n"); + return ret; + } + + return 0; +} + +static int lt9611c_hdmi_audio_prepare(struct drm_bridge *bridge, + struct drm_connector *connector, + struct hdmi_codec_daifmt *fmt, + struct hdmi_codec_params *hparms) +{ + struct lt9611c *lt9611c = bridge_to_lt9611c(bridge); + u8 audio_cmd[6] = {0x57, 0x48, 0x36, 0x3a}; + u8 data[5]; + int ret; + + if (hparms->sample_width == 32) + return -EINVAL; + + switch (fmt->fmt) { + case HDMI_I2S: + audio_cmd[4] = 0x01; + break; + case HDMI_SPDIF: + audio_cmd[4] = 0x02; + break; + default: + return -EINVAL; + } + + audio_cmd[5] = hparms->channels; + guard(mutex)(<9611c->ocm_lock); + + ret = lt9611c_read_write_flow(lt9611c, audio_cmd, sizeof(audio_cmd), + data, sizeof(data)); + if (ret < 0) { + dev_err(lt9611c->dev, "set audio info failed!\n"); + return ret; + } + + return drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, + &hparms->cea); +} + +static void lt9611c_hdmi_audio_shutdown(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector); +} + +static int lt9611c_hdmi_audio_startup(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + return 0; +} + +static const struct drm_bridge_funcs lt9611c_bridge_funcs = { + .attach = lt9611c_bridge_attach, + .detect = lt9611c_bridge_detect, + .edid_read = lt9611c_bridge_edid_read, + .atomic_pre_enable = lt9611c_bridge_atomic_pre_enable, + .atomic_enable = lt9611c_bridge_atomic_enable, + .atomic_post_disable = lt9611c_bridge_atomic_post_disable, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + + .hdmi_tmds_char_rate_valid = lt9611c_hdmi_tmds_char_rate_valid, + .hdmi_write_avi_infoframe = lt9611c_hdmi_write_avi_infoframe, + .hdmi_clear_avi_infoframe = lt9611c_hdmi_clear_avi_infoframe, + .hdmi_write_audio_infoframe = lt9611c_hdmi_write_audio_infoframe, + .hdmi_clear_audio_infoframe = lt9611c_hdmi_clear_audio_infoframe, + + .hdmi_audio_startup = lt9611c_hdmi_audio_startup, + .hdmi_audio_prepare = lt9611c_hdmi_audio_prepare, + .hdmi_audio_shutdown = lt9611c_hdmi_audio_shutdown, +}; + +static int lt9611c_parse_dt(struct device *dev, + struct lt9611c *lt9611c) +{ + lt9611c->dsi0_node = of_graph_get_remote_node(dev->of_node, 0, -1); + if (!lt9611c->dsi0_node) + return dev_err_probe(dev, -ENODEV, "failed to get remote node for primary dsi\n"); + + lt9611c->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1); + + return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, <9611c->bridge.next_bridge); +} + +static int lt9611c_gpio_init(struct lt9611c *lt9611c) +{ + struct device *dev = lt9611c->dev; + + lt9611c->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(lt9611c->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(lt9611c->reset_gpio), + "failed to acquire reset gpio\n"); + + return 0; +} + +static int lt9611c_read_version(struct lt9611c *lt9611c) +{ + u8 buf[2]; + int ret; + + ret = regmap_write(lt9611c->regmap, 0xe0ee, 0x01); + if (ret) + return ret; + + ret = regmap_bulk_read(lt9611c->regmap, 0xe080, buf, ARRAY_SIZE(buf)); + if (ret) + return ret; + + return (buf[0] << 8) | buf[1]; +} + +static int lt9611c_read_chipid(struct lt9611c *lt9611c) +{ + struct device *dev = lt9611c->dev; + u8 chipid[2]; + int ret; + + ret = regmap_write(lt9611c->regmap, 0xe0ee, 0x01); + if (ret) + return ret; + + ret = regmap_bulk_read(lt9611c->regmap, 0xe100, chipid, 2); + if (ret) + return ret; + + if (chipid[0] != 0x23 || chipid[1] != 0x06) { + dev_err(dev, "ChipID: 0x%02x 0x%02x\n", chipid[0], chipid[1]); + return -ENODEV; + } + + return 0; +} + +static ssize_t lt9611c_firmware_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct lt9611c *lt9611c = dev_get_drvdata(dev); + int ret; + + lt9611c_lock(lt9611c); + + ret = lt9611c_firmware_upgrade(lt9611c); + if (ret < 0) + dev_err(dev, "upgrade failure\n"); + + lt9611c_unlock(lt9611c); + + return ret < 0 ? ret : len; +} + +static ssize_t lt9611c_firmware_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct lt9611c *lt9611c = dev_get_drvdata(dev); + + return sysfs_emit(buf, "0x%04x\n", lt9611c->fw_version); +} + +static DEVICE_ATTR_RW(lt9611c_firmware); + +static struct attribute *lt9611c_attrs[] = { + &dev_attr_lt9611c_firmware.attr, + NULL, +}; + +static const struct attribute_group lt9611c_attr_group = { + .attrs = lt9611c_attrs, +}; + +static const struct attribute_group *lt9611c_attr_groups[] = { + <9611c_attr_group, + NULL, +}; + +static int lt9611c_probe(struct i2c_client *client) +{ + const struct i2c_device_id *id = i2c_client_get_device_id(client); + struct lt9611c *lt9611c; + struct device *dev = &client->dev; + bool fw_updated = false; + int ret; + + crc8_populate_msb(lt9611c_crc8_table, LT9611C_CRC_POLYNOMIAL); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return dev_err_probe(dev, -ENODEV, "device doesn't support I2C\n"); + + lt9611c = devm_drm_bridge_alloc(dev, struct lt9611c, bridge, <9611c_bridge_funcs); + if (IS_ERR(lt9611c)) + return dev_err_probe(dev, PTR_ERR(lt9611c), "drm bridge alloc failed.\n"); + + lt9611c->dev = dev; + lt9611c->client = client; + lt9611c->chip_type = id->driver_data; + ret = devm_mutex_init(dev, <9611c->ocm_lock); + if (ret) + return dev_err_probe(dev, ret, "failed to init mutex\n"); + + lt9611c->regmap = devm_regmap_init_i2c(client, <9611c_regmap_config); + if (IS_ERR(lt9611c->regmap)) + return dev_err_probe(dev, PTR_ERR(lt9611c->regmap), "regmap i2c init failed\n"); + + ret = lt9611c_parse_dt(dev, lt9611c); + if (ret) + return dev_err_probe(dev, ret, "failed to parse device tree\n"); + + ret = lt9611c_gpio_init(lt9611c); + if (ret < 0) + goto err_of_put; + + ret = lt9611c_regulator_init(lt9611c); + if (ret < 0) + goto err_of_put; + + ret = regulator_bulk_enable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + if (ret) + goto err_of_put; + + lt9611c_reset(lt9611c); + + lt9611c_lock(lt9611c); + + ret = lt9611c_read_chipid(lt9611c); + if (ret < 0) { + dev_err(dev, "failed to read chip id.\n"); + lt9611c_unlock(lt9611c); + goto err_disable_regulators; + } + +retry: + lt9611c->fw_version = lt9611c_read_version(lt9611c); + if (lt9611c->fw_version < 0) { + dev_err(dev, "failed to read fw version\n"); + ret = -EOPNOTSUPP; + lt9611c_unlock(lt9611c); + goto err_disable_regulators; + + } else if (lt9611c->fw_version == 0) { + if (!fw_updated) { + fw_updated = true; + ret = lt9611c_firmware_upgrade(lt9611c); + if (ret < 0) { + lt9611c_unlock(lt9611c); + goto err_disable_regulators; + } + + goto retry; + + } else { + dev_err(dev, "fw version 0x%04x, update failed\n", lt9611c->fw_version); + ret = -EOPNOTSUPP; + lt9611c_unlock(lt9611c); + goto err_disable_regulators; + } + } + + lt9611c_unlock(lt9611c); + dev_dbg(dev, "current version:0x%04x", lt9611c->fw_version); + + INIT_WORK(<9611c->work, lt9611c_hpd_work); + + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, + lt9611c_irq_thread_handler, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT | + IRQF_NO_AUTOEN, + "lt9611c", lt9611c); + if (ret) { + dev_err(dev, "failed to request irq\n"); + goto err_disable_regulators; + } + + lt9611c->bridge.of_node = client->dev.of_node; + lt9611c->bridge.ops = DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HPD | + DRM_BRIDGE_OP_HDMI | + DRM_BRIDGE_OP_HDMI_AUDIO; + lt9611c->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + + lt9611c->bridge.hdmi_audio_dev = dev; + lt9611c->bridge.hdmi_audio_max_i2s_playback_channels = 8; + lt9611c->bridge.hdmi_audio_dai_port = 2; + + devm_drm_bridge_add(dev, <9611c->bridge); + + /* Attach primary DSI */ + lt9611c->dsi0 = lt9611c_attach_dsi(lt9611c, lt9611c->dsi0_node); + if (IS_ERR(lt9611c->dsi0)) { + ret = PTR_ERR(lt9611c->dsi0); + goto err_remove_bridge; + } + + /* Attach secondary DSI, if specified */ + if (lt9611c->dsi1_node) { + lt9611c->dsi1 = lt9611c_attach_dsi(lt9611c, lt9611c->dsi1_node); + if (IS_ERR(lt9611c->dsi1)) { + ret = PTR_ERR(lt9611c->dsi1); + goto err_remove_bridge; + } + } + + lt9611c->hdmi_connected = false; + i2c_set_clientdata(client, lt9611c); + enable_irq(client->irq); + lt9611c_reset(lt9611c); + + return 0; + +err_remove_bridge: + free_irq(client->irq, lt9611c); + cancel_work_sync(<9611c->work); + drm_bridge_remove(<9611c->bridge); + +err_disable_regulators: + regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + +err_of_put: + of_node_put(lt9611c->dsi1_node); + of_node_put(lt9611c->dsi0_node); + + return ret; +} + +static void lt9611c_remove(struct i2c_client *client) +{ + struct lt9611c *lt9611c = i2c_get_clientdata(client); + + free_irq(client->irq, lt9611c); + cancel_work_sync(<9611c->work); + regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + of_node_put(lt9611c->dsi1_node); + of_node_put(lt9611c->dsi0_node); +} + +static int lt9611c_bridge_suspend(struct device *dev) +{ + struct lt9611c *lt9611c = dev_get_drvdata(dev); + int ret; + + dev_dbg(lt9611c->dev, "suspend\n"); + disable_irq(lt9611c->client->irq); + ret = regulator_bulk_disable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + if (ret) { + dev_err(lt9611c->dev, "regulator bulk disable failed.\n"); + return ret; + } + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); + + return ret; +} + +static int lt9611c_bridge_resume(struct device *dev) +{ + struct lt9611c *lt9611c = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(lt9611c->supplies), lt9611c->supplies); + if (ret) { + dev_err(lt9611c->dev, "regulator bulk enable failed.\n"); + return ret; + } + enable_irq(lt9611c->client->irq); + lt9611c_reset(lt9611c); + dev_dbg(lt9611c->dev, "resume\n"); + + return ret; +} + +static const struct dev_pm_ops lt9611c_bridge_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(lt9611c_bridge_suspend, + lt9611c_bridge_resume) +}; + +static struct i2c_device_id lt9611c_id[] = { + /* chip_type */ + { "lontium,lt9611c", 0 }, + { "lontium,lt9611ex", 1 }, + { "lontium,lt9611uxd", 2 }, + { /* sentinel */ } +}; + +static const struct of_device_id lt9611c_match_table[] = { + { .compatible = "lontium,lt9611c" }, + { .compatible = "lontium,lt9611ex" }, + { .compatible = "lontium,lt9611uxd" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lt9611c_match_table); + +static struct i2c_driver lt9611c_driver = { + .driver = { + .name = "lt9611c", + .of_match_table = lt9611c_match_table, + .pm = <9611c_bridge_pm_ops, + .dev_groups = lt9611c_attr_groups, + }, + .probe = lt9611c_probe, + .remove = lt9611c_remove, + .id_table = lt9611c_id, +}; +module_i2c_driver(lt9611c_driver); + +MODULE_AUTHOR("SunYun Yang "); +MODULE_DESCRIPTION("Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(FW_FILE); +