* [PATCH v6 0/6] Add support to load QUP SE firmware from
@ 2025-08-22 7:26 Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 1/6] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
In Qualcomm SoCs, firmware loading for Serial Engines (SE) in the QUP
hardware has traditionally been managed by TrustZone (TZ). This setup
handled Serial Engines(SE) assignments and access control permissions,
ensuring a high level of security but limiting flexibility and
accessibility.
This limitation poses a significant challenge for developers who need more
flexibility to enable any protocol on any of the SEs within the QUP
hardware.
To address this, we are introducing a change that opens the firmware
loading mechanism to the Linux environment. This enhancement increases
flexibility and allows for more streamlined and efficient management. We
can now handle SE assignments and access control permissions directly
within Linux, eliminating the dependency on TZ.
We propose an alternative method for firmware loading and SE
ownership/transfer mode configuration based on device tree configuration.
This method does not rely on other execution environments, making it
accessible to all developers.
For SEs used prior to the kernel, their firmware will be loaded by the
respective image drivers (e.g., Debug UART, Secure or trusted SE).
Additionally, the GSI firmware, which is common to all SEs per QUPV3 core,
will not be loaded by Linux driver but TZ only. At the kernel level, only
the SE protocol driver should load the respective protocol firmware.
---
v5 -> v6:
- Added extra patch for cleanup in qcom-geni-se.c file.
- Moved contents of qup-fw-load.h into qcom-geni-se.c.
- Specified endianness for all members of the se_fw_hdr structure.
- Changed the return type and arguments of the geni_read_elf function.
- Renamed geni_read_elf to geni_find_protocol_fw for clarity.
- Added error logging for corrupt firmware.
- Passed SE mode and protocol type explicitly to all relevant functions.
- Replaced writel_relaxed with writel for stricter memory ordering.
- Renamed variable reg_val to reg for consistency.
- Moved firmware length validation logic into geni_find_protocol_fw.
- Updated function documentation for clarity and accuracy.
- Removed redundant firmware length check.
- Inlined the qup_fw_load function and removed its definition.
- Removed the MAX_PROTOCOL macro.
- Dropped mode and protocol fields from the geni_se structure.
- Moved unrelated firmware loading code into a separate patch.
- Added Acked-by tag.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-1-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Added Reviewd-by tag.
- Resolved kernel test robot error by including the missing bitfield header file.
- Updated the SE firmware ELF structure name for consistency.
- Specified _leb4 format for the magic number definition.
- Updated the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-1-quic_vdadhani@quicinc.com/
v3 -> v4:
- Drop patch 1 of the v3 series as it has been reviewed and merged.
- Update the qcom,gsi-dma-allowed property name to qcom,enable-gsi-dma.
- Remove the full stop from the title.
- Add a reference to the common schema YAML in the I2C, SPI, and SERIAL
YAML files in a single patch and drop the individual patches for protocol YAML.
- Update the commit message.
- Resolve kernel test robot warnings.
- Add a multiline comment in the Copyright section.
- Remove valid_seg_size and geni_config_common_control functions and add the code inline.
- Rename read_elf function to geni_read_elf.
- Add a firmware size check.
- Assign *pelfseg after finding a match.
- Break one large condition check into multiple checks to improve code readability.
- Remove return type documentation for void functions.
- Update error messages to be more descriptive.
- Correct indentation.
- Rename geni_flash_fw_revision function to geni_write_fw_revision.
- Remove __func__ from all print statements.
- Move resource_on to the appropriate section after parsing the firmware file.
- Update variable names and function arguments as suggested.
- Use FIELD_GET, FIELD_PREP, and GENMASK.
- Use memcpy_toio() instead of memcpy.
- Remove duplicate registers and bitmask macros.
- Remove rsc struct and add required variables in geni_se struct.
- Add a patch dependency note.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-1-quic_vdadhani@quicinc.com/
v2 -> v3:
- Add a new YAML file for QUP peripheral-specific properties for I2C, SPI, and SERIAL buses.
- Drop the 'qcom,xfer-mode' property and add the 'qcom,gsi-dma-allowed' property in protocol-specific YAML.
- Add a reference for the QUP peripheral shared YAML to protocol-specific YAML.
- Enhance error handling and remove redundant if conditions in the qcom-geni-se.c driver.
- Remove the ternary operator in the qup_fw_load function.
- Update function descriptions and use imperative mood in qcom-geni-se.c
- Load firmware during probe only if the protocol is invalid.
v2 Link: https://lore.kernel.org/linux-kernel/20250124105309.295769-1-quic_vdadhani@quicinc.com/
v1 -> v2:
- Drop the qcom,load-firmware property.
- Remove the fixed firmware path.
- Add the 'firmware-name' property in the QUP common driver.
- Add logic to read the firmware path from the device tree.
- Resolve kernel test robot warnings.
- Update the 'qcom,xfer-mode' property description.
v1 Link: https://lore.kernel.org/linux-kernel/20241204150326.1470749-1-quic_vdadhani@quicinc.com/
---
Viken Dadhaniya (6):
dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties
for I2C, SPI, and SERIAL bus
soc: qcom: geni-se: Cleanup register defines and update copyright
soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux
subsystem
i2c: qcom-geni: Load i2c qup Firmware from linux side
spi: geni-qcom: Load spi qup Firmware from linux side
serial: qcom-geni: Load UART qup Firmware from linux side
.../bindings/i2c/qcom,i2c-geni-qcom.yaml | 1 +
.../serial/qcom,serial-geni-qcom.yaml | 1 +
.../soc/qcom/qcom,se-common-props.yaml | 26 +
.../bindings/spi/qcom,spi-geni-qcom.yaml | 1 +
drivers/i2c/busses/i2c-qcom-geni.c | 8 +-
drivers/soc/qcom/qcom-geni-se.c | 493 +++++++++++++++++-
drivers/spi/spi-geni-qcom.c | 6 +
drivers/tty/serial/qcom_geni_serial.c | 8 +-
include/linux/soc/qcom/geni-se.h | 4 +
9 files changed, 527 insertions(+), 21 deletions(-)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v6 1/6] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 2/6] soc: qcom: geni-se: Cleanup register defines and update copyright Viken Dadhaniya
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya, Krzysztof Kozlowski
Introduce a new YAML schema for QUP-supported peripherals. Define common
properties used across QUP-supported peripherals.
Add property `qcom,enable-gsi-dma` to configure the Serial Engine (SE) for
QCOM GPI DMA mode.
Reference the common schema YAML in the GENI I2C, SPI, and SERIAL YAML
files.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Co-developed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
v5 -> v6:
- No change.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-2-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Add Reviewed-by tag.
- Update the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-2-quic_vdadhani@quicinc.com/
v3 -> v4:
- Update qcom,gsi-dma-allowed property name to qcom,enable-gsi-dma.
- Remove full stop form title.
- Add reference of common schema YAML in the I2C, SPI, and SERIAL YAML files.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-3-quic_vdadhani@quicinc.com/
---
---
.../bindings/i2c/qcom,i2c-geni-qcom.yaml | 1 +
.../serial/qcom,serial-geni-qcom.yaml | 1 +
.../soc/qcom/qcom,se-common-props.yaml | 26 +++++++++++++++++++
.../bindings/spi/qcom,spi-geni-qcom.yaml | 1 +
4 files changed, 29 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml
index 9f66a3bb1f80..51534953a69c 100644
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml
@@ -75,6 +75,7 @@ required:
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
+ - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
- if:
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml
index dd33794b3534..ed7b3909d87d 100644
--- a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml
+++ b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml
@@ -12,6 +12,7 @@ maintainers:
allOf:
- $ref: /schemas/serial/serial.yaml#
+ - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml
new file mode 100644
index 000000000000..6a34f05a07e8
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/qcom/qcom,se-common-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: QUP Peripheral-specific properties for I2C, SPI and SERIAL bus
+
+description:
+ The Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) is
+ a programmable module that supports a wide range of serial interfaces
+ such as UART, SPI, I2C, I3C, etc. This defines the common properties used
+ across QUP-supported peripherals.
+
+maintainers:
+ - Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
+ - Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
+
+properties:
+ qcom,enable-gsi-dma:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ Configure the Serial Engine (SE) to transfer data in QCOM GPI DMA mode.
+ By default, FIFO mode (PIO/CPU DMA) will be selected.
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml
index 2e20ca313ec1..d12c5a060ed0 100644
--- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml
@@ -25,6 +25,7 @@ description:
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
+ - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
properties:
compatible:
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 2/6] soc: qcom: geni-se: Cleanup register defines and update copyright
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 1/6] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
Refactor register macros for consistency and clarity and remove redundant
definitions and update naming for better alignment.
Update copyright to include Qualcomm Technologies, Inc.
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
drivers/soc/qcom/qcom-geni-se.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 3c3b796333a6..e8ab2833815e 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -1,5 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
/* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */
#define __DISABLE_TRACE_MMIO__
@@ -110,22 +113,20 @@ struct geni_se_desc {
static const char * const icc_path_names[] = {"qup-core", "qup-config",
"qup-memory"};
-#define QUP_HW_VER_REG 0x4
+/* Common QUPV3 registers */
+#define QUPV3_HW_VER_REG 0x4
/* Common SE registers */
-#define GENI_INIT_CFG_REVISION 0x0
-#define GENI_S_INIT_CFG_REVISION 0x4
-#define GENI_OUTPUT_CTRL 0x24
-#define GENI_CGC_CTRL 0x28
-#define GENI_CLK_CTRL_RO 0x60
-#define GENI_FW_S_REVISION_RO 0x6c
+#define SE_GENI_INIT_CFG_REVISION 0x0
+#define SE_GENI_S_INIT_CFG_REVISION 0x4
+#define SE_GENI_CGC_CTRL 0x28
+#define SE_GENI_CLK_CTRL_RO 0x60
+#define SE_GENI_FW_S_REVISION_RO 0x6c
#define SE_GENI_BYTE_GRAN 0x254
#define SE_GENI_TX_PACKING_CFG0 0x260
#define SE_GENI_TX_PACKING_CFG1 0x264
#define SE_GENI_RX_PACKING_CFG0 0x284
#define SE_GENI_RX_PACKING_CFG1 0x288
-#define SE_GENI_M_GP_LENGTH 0x910
-#define SE_GENI_S_GP_LENGTH 0x914
#define SE_DMA_TX_PTR_L 0xc30
#define SE_DMA_TX_PTR_H 0xc34
#define SE_DMA_TX_ATTR 0xc38
@@ -142,7 +143,6 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
#define SE_DMA_RX_IRQ_EN 0xd48
#define SE_DMA_RX_IRQ_EN_SET 0xd4c
#define SE_DMA_RX_IRQ_EN_CLR 0xd50
-#define SE_DMA_RX_LEN_IN 0xd54
#define SE_DMA_RX_MAX_BURST 0xd5c
#define SE_DMA_RX_FLUSH 0xd60
#define SE_GSI_EVENT_EN 0xe18
@@ -179,7 +179,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
/* SE_DMA_GENERAL_CFG */
#define DMA_RX_CLK_CGC_ON BIT(0)
#define DMA_TX_CLK_CGC_ON BIT(1)
-#define DMA_AHB_SLV_CFG_ON BIT(2)
+#define DMA_AHB_SLV_CLK_CGC_ON BIT(2)
#define AHB_SEC_SLV_CLK_CGC_ON BIT(3)
#define DUMMY_RX_NON_BUFFERABLE BIT(4)
#define RX_DMA_ZERO_PADDING_EN BIT(5)
@@ -196,7 +196,7 @@ u32 geni_se_get_qup_hw_version(struct geni_se *se)
{
struct geni_wrapper *wrapper = se->wrapper;
- return readl_relaxed(wrapper->base + QUP_HW_VER_REG);
+ return readl_relaxed(wrapper->base + QUPV3_HW_VER_REG);
}
EXPORT_SYMBOL_GPL(geni_se_get_qup_hw_version);
@@ -220,12 +220,12 @@ static void geni_se_io_init(void __iomem *base)
{
u32 val;
- val = readl_relaxed(base + GENI_CGC_CTRL);
+ val = readl_relaxed(base + SE_GENI_CGC_CTRL);
val |= DEFAULT_CGC_EN;
- writel_relaxed(val, base + GENI_CGC_CTRL);
+ writel_relaxed(val, base + SE_GENI_CGC_CTRL);
val = readl_relaxed(base + SE_DMA_GENERAL_CFG);
- val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON;
+ val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON;
val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
writel_relaxed(val, base + SE_DMA_GENERAL_CFG);
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 1/6] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 2/6] soc: qcom: geni-se: Cleanup register defines and update copyright Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
2025-08-23 3:11 ` kernel test robot
2025-08-22 7:26 ` [PATCH v6 4/6] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
` (2 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
In Qualcomm SoCs, firmware loading for Serial Engines (SE) within the QUP
hardware has traditionally been managed by TrustZone (TZ). This restriction
poses a significant challenge for developers, as it limits their ability to
enable various protocols on any of the SEs from the Linux side, reducing
flexibility.
Load the firmware to QUP SE based on the 'firmware-name' property specified
in devicetree at bootup time.
Co-developed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
v5 -> v6:
- Moved contents of qup-fw-load.h into qcom-geni-se.c.
- Specified endianness for all members of the se_fw_hdr structure.
- Changed the return type and arguments of the geni_read_elf function.
- Renamed geni_read_elf to geni_find_protocol_fw for clarity.
- Added error logging for corrupt firmware.
- Passed SE mode and protocol type explicitly to all relevant functions.
- Replaced writel_relaxed with writel for stricter memory ordering.
- Renamed variable reg_val to reg for consistency.
- Moved firmware length validation logic into geni_find_protocol_fw.
- Updated function documentation for clarity and accuracy.
- Removed redundant firmware length check.
- Inlined the qup_fw_load function and removed its definition.
- Removed the MAX_PROTOCOL macro.
- Dropped mode and protocol fields from the geni_se structure.
- Moved unrelated firmware loading code into a separate patch.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-3-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Resolved kernel test robot error by including the missing bitfield header file.
- Updated the SE firmware ELF structure name for consistency.
- Specified _leb4 format for the magic number definition.
- Updated the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-3-quic_vdadhani@quicinc.com/
v3 -> v4:
- Update the commit message.
- Resolve kernel test robot warnings.
- Add a multiline comment in the Copyright section.
- Remove valid_seg_size and geni_config_common_control functions, and add the code inline.
- Rename read_elf function to geni_read_elf.
- Add a firmware size check.
- Assign *pelfseg after finding a match.
- Break one large condition check into multiple checks to improve code readability.
- Remove return type documentation for void functions.
- Update error messages to be more descriptive.
- Correct indentation.
- Rename geni_flash_fw_revision function to geni_write_fw_revision.
- Remove __func__ from all print statements.
- Move resource_on to the appropriate section after parsing the firmware file.
- Update variable names and function arguments as suggested.
- Use FIELD_GET, FIELD_PREP, and GENMASK.
- Use memcpy_toio() instead of memcpy.
- Remove duplicate registers and bitmask macros.
- Remove rsc struct and add required variables in geni_se struct.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-7-quic_vdadhani@quicinc.com/
v2 -> v3:
- Remove code related to the 'qcom,xfer-mode' property.
- Add logic to read the boolean property 'qcom,gsi-dma-allowed' and select the transfer mode.
- Hardcode FIFO mode for the serial driver as GSI mode is currently not supported.
- Update function descriptions as suggested.
- Enhance error handling and remove redundant if conditions.
- Drop the ternary operator.
v2 Link: https://lore.kernel.org/linux-arm-msm/20250124105309.295769-6-quic_vdadhani@quicinc.com/
v1 -> v2:
- Remove the fixed firmware path and add logic to read the path from the device tree.
- Remove code related to the 'qcom,load-firmware' property.
- Resolve kernel test robot warnings.
- Update the commit message.
- Update Copyright year.
v1 Link: https://lore.kernel.org/linux-kernel/20241204150326.1470749-5-quic_vdadhani@quicinc.com/
---
---
drivers/soc/qcom/qcom-geni-se.c | 461 ++++++++++++++++++++++++++++++-
include/linux/soc/qcom/geni-se.h | 4 +
2 files changed, 462 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index e8ab2833815e..d40b6d0395d0 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -8,7 +8,9 @@
#define __DISABLE_TRACE_MMIO__
#include <linux/acpi.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
+#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
@@ -113,8 +115,80 @@ struct geni_se_desc {
static const char * const icc_path_names[] = {"qup-core", "qup-config",
"qup-memory"};
+static const char * const protocol_name[] = { "None", "SPI", "UART", "I2C", "I3C", "SPI SLAVE" };
+
+/**
+ * struct se_fw_hdr - Serial Engine firmware configuration header
+ *
+ * This structure defines the SE firmware header, which together with the
+ * firmware payload is stored in individual ELF segments.
+ *
+ * @magic: Set to 'SEFW'.
+ * @version: Structure version number.
+ * @core_version: QUPV3 hardware version.
+ * @serial_protocol: Encoded in GENI_FW_REVISION.
+ * @fw_version: Firmware version, from GENI_FW_REVISION.
+ * @cfg_version: Configuration version, from GENI_INIT_CFG_REVISION.
+ * @fw_size_in_items: Number of 32-bit words in GENI_FW_RAM.
+ * @fw_offset: Byte offset to GENI_FW_RAM array.
+ * @cfg_size_in_items: Number of GENI_FW_CFG index/value pairs.
+ * @cfg_idx_offset: Byte offset to GENI_FW_CFG index array.
+ * @cfg_val_offset: Byte offset to GENI_FW_CFG values array.
+ */
+struct se_fw_hdr {
+ __le32 magic;
+ __le32 version;
+ __le32 core_version;
+ __le16 serial_protocol;
+ __le16 fw_version;
+ __le16 cfg_version;
+ __le16 fw_size_in_items;
+ __le16 fw_offset;
+ __le16 cfg_size_in_items;
+ __le16 cfg_idx_offset;
+ __le16 cfg_val_offset;
+};
+
+/*Magic numbers*/
+#define SE_MAGIC_NUM 0x57464553
+
+#define MAX_GENI_CFG_RAMn_CNT 455
+
+#define MI_PBT_NON_PAGED_SEGMENT 0x0
+#define MI_PBT_HASH_SEGMENT 0x2
+#define MI_PBT_NOTUSED_SEGMENT 0x3
+#define MI_PBT_SHARED_SEGMENT 0x4
+
+#define MI_PBT_FLAG_PAGE_MODE BIT(20)
+#define MI_PBT_FLAG_SEGMENT_TYPE GENMASK(26, 24)
+#define MI_PBT_FLAG_ACCESS_TYPE GENMASK(23, 21)
+
+#define MI_PBT_PAGE_MODE_VALUE(x) FIELD_GET(MI_PBT_FLAG_PAGE_MODE, x)
+
+#define MI_PBT_SEGMENT_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_SEGMENT_TYPE, x)
+
+#define MI_PBT_ACCESS_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_ACCESS_TYPE, x)
+
+#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \
+ M_IO_DATA_DEASSERT_EN | \
+ M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \
+ M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \
+ M_TX_FIFO_WR_ERR_EN)
+
/* Common QUPV3 registers */
#define QUPV3_HW_VER_REG 0x4
+#define QUPV3_SE_AHB_M_CFG 0x118
+#define QUPV3_COMMON_CFG 0x120
+#define QUPV3_COMMON_CGC_CTRL 0x21c
+
+/* QUPV3_COMMON_CFG fields */
+#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0)
+
+/* QUPV3_SE_AHB_M_CFG fields */
+#define AHB_M_CLK_CGC_ON BIT(0)
+
+/* QUPV3_COMMON_CGC_CTRL fields */
+#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0)
/* Common SE registers */
#define SE_GENI_INIT_CFG_REVISION 0x0
@@ -122,11 +196,13 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
#define SE_GENI_CGC_CTRL 0x28
#define SE_GENI_CLK_CTRL_RO 0x60
#define SE_GENI_FW_S_REVISION_RO 0x6c
+#define SE_GENI_CFG_REG0 0x100
#define SE_GENI_BYTE_GRAN 0x254
#define SE_GENI_TX_PACKING_CFG0 0x260
#define SE_GENI_TX_PACKING_CFG1 0x264
#define SE_GENI_RX_PACKING_CFG0 0x284
#define SE_GENI_RX_PACKING_CFG1 0x288
+#define SE_GENI_S_IRQ_ENABLE 0x644
#define SE_DMA_TX_PTR_L 0xc30
#define SE_DMA_TX_PTR_H 0xc34
#define SE_DMA_TX_ATTR 0xc38
@@ -148,6 +224,15 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
#define SE_GSI_EVENT_EN 0xe18
#define SE_IRQ_EN 0xe1c
#define SE_DMA_GENERAL_CFG 0xe30
+#define SE_GENI_FW_REVISION 0x1000
+#define SE_GENI_S_FW_REVISION 0x1004
+#define SE_GENI_CFG_RAMN 0x1010
+#define SE_GENI_CLK_CTRL 0x2000
+#define SE_DMA_IF_EN 0x2004
+#define SE_FIFO_IF_DISABLE 0x2008
+
+/* GENI_FW_REVISION_RO fields */
+#define FW_REV_VERSION_MSK GENMASK(7, 0)
/* GENI_OUTPUT_CTRL fields */
#define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0)
@@ -186,6 +271,15 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
#define RX_DMA_IRQ_DELAY_MSK GENMASK(8, 6)
#define RX_DMA_IRQ_DELAY_SHFT 6
+/* GENI_CLK_CTRL fields */
+#define SER_CLK_SEL BIT(0)
+
+/* GENI_DMA_IF_EN fields */
+#define DMA_IF_EN BIT(0)
+
+#define geni_setbits32(_addr, _v) writel(readl(_addr) | (_v), _addr)
+#define geni_clrbits32(_addr, _v) writel(readl(_addr) & ~(_v), _addr)
+
/**
* geni_se_get_qup_hw_version() - Read the QUP wrapper Hardware version
* @se: Pointer to the corresponding serial engine.
@@ -658,9 +752,12 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
}
EXPORT_SYMBOL_GPL(geni_se_clk_freq_match);
-#define GENI_SE_DMA_DONE_EN BIT(0)
-#define GENI_SE_DMA_EOT_EN BIT(1)
-#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
+#define GENI_SE_DMA_DONE_EN BIT(0)
+#define GENI_SE_DMA_EOT_EN BIT(1)
+#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
+#define GENI_SE_DMA_RESET_DONE_EN BIT(3)
+#define GENI_SE_DMA_FLUSH_DONE BIT(4)
+
#define GENI_SE_DMA_EOT_BUF BIT(0)
/**
@@ -891,6 +988,364 @@ int geni_icc_disable(struct geni_se *se)
}
EXPORT_SYMBOL_GPL(geni_icc_disable);
+/**
+ * geni_find_protocol_fw() - Locate and validate SE firmware for a protocol.
+ * @dev: Pointer to the device structure.
+ * @fw: Pointer to the firmware image.
+ * @protocol: Expected serial engine protocol type.
+ *
+ * Identifies the appropriate firmware image or configuration required for a
+ * specific communication protocol instance running on a Qualcomm GENI
+ * controller.
+ *
+ * Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise.
+ */
+static struct se_fw_hdr *geni_find_protocol_fw(struct device *dev, const struct firmware *fw,
+ enum geni_se_protocol_type protocol)
+{
+ const struct elf32_hdr *ehdr;
+ const struct elf32_phdr *phdrs;
+ const struct elf32_phdr *phdr;
+ struct se_fw_hdr *sefw;
+ int i;
+
+ if (!fw || fw->size < sizeof(struct elf32_hdr))
+ return NULL;
+
+ ehdr = (const struct elf32_hdr *)fw->data;
+ phdrs = (const struct elf32_phdr *)(fw->data + ehdr->e_phoff);
+
+ /*
+ * The firmware is expected to have at least two program headers (segments).
+ * One for metadata and the other for the actual protocol-specific firmware.
+ */
+ if (ehdr->e_phnum < 2) {
+ dev_err(dev, "Invalid firmware: less than 2 program headers\n");
+ return NULL;
+ }
+
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ phdr = &phdrs[i];
+
+ if (fw->size < phdr->p_offset + phdr->p_filesz) {
+ dev_err(dev, "Firmware size (%zu) is smaller than expected offset + size (%u + %u)\n",
+ fw->size, phdr->p_offset, phdr->p_filesz);
+ return NULL;
+ }
+
+ if (phdr->p_type != PT_LOAD || !phdr->p_memsz)
+ continue;
+
+ if (MI_PBT_PAGE_MODE_VALUE(phdr->p_flags) != MI_PBT_NON_PAGED_SEGMENT ||
+ MI_PBT_SEGMENT_TYPE_VALUE(phdr->p_flags) == MI_PBT_HASH_SEGMENT ||
+ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_NOTUSED_SEGMENT ||
+ MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_SHARED_SEGMENT)
+ continue;
+
+ if (phdr->p_filesz < sizeof(struct se_fw_hdr))
+ continue;
+
+ sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset);
+
+ if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1)
+ continue;
+
+ if (le32_to_cpu(sefw->serial_protocol) != protocol)
+ continue;
+
+ if (sefw->fw_size_in_items % 2 != 0)
+ sefw->fw_size_in_items++;
+
+ if (sefw->fw_size_in_items >= MAX_GENI_CFG_RAMn_CNT) {
+ dev_err(dev, "Corrupt firmware: fw_size_in_items (%u) exceeds max allowed RAMn count (%u)\n",
+ sefw->fw_size_in_items, MAX_GENI_CFG_RAMn_CNT);
+ continue;
+ }
+
+ if (sefw->fw_offset + sefw->fw_size_in_items * sizeof(u32) > phdr->p_filesz ||
+ sefw->cfg_idx_offset + sefw->cfg_size_in_items * sizeof(u8) > phdr->p_filesz ||
+ sefw->cfg_val_offset + sefw->cfg_size_in_items * sizeof(u32) > phdr->p_filesz) {
+ dev_err(dev, "Truncated or corrupt SE FW segment found at index %d\n", i);
+ continue;
+ }
+
+ return sefw;
+ }
+
+ dev_err(dev, "Failed to get %s protocol firmware\n", protocol_name[protocol]);
+ return NULL;
+}
+
+/**
+ * geni_configure_xfer_mode() - Set the transfer mode.
+ * @se: Pointer to the concerned serial engine.
+ * @mode: SE data transfer mode.
+ *
+ * Set the transfer mode to either FIFO or DMA according to the mode specified
+ * by the protocol driver.
+ *
+ * Return: 0 if successful, otherwise return an error value.
+ */
+static int geni_configure_xfer_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
+{
+ /* Configure SE FIFO, DMA or GSI mode. */
+ switch (mode) {
+ case GENI_GPI_DMA:
+ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
+ writel(0x0, se->base + SE_IRQ_EN);
+ writel(DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | GENI_M_EVENT_EN | GENI_S_EVENT_EN,
+ se->base + SE_GSI_EVENT_EN);
+ break;
+
+ case GENI_SE_FIFO:
+ geni_clrbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
+ writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
+ se->base + SE_IRQ_EN);
+ writel(0x0, se->base + SE_GSI_EVENT_EN);
+ break;
+
+ case GENI_SE_DMA:
+ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
+ writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
+ se->base + SE_IRQ_EN);
+ writel(0x0, se->base + SE_GSI_EVENT_EN);
+ break;
+
+ default:
+ dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", mode);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * geni_enable_interrupts() - Enable interrupts.
+ * @se: Pointer to the concerned serial engine.
+ *
+ * Enable the required interrupts during the firmware load process.
+ */
+static void geni_enable_interrupts(struct geni_se *se)
+{
+ u32 val;
+
+ /* Enable required interrupts. */
+ writel(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN);
+
+ val = S_CMD_OVERRUN_EN | S_ILLEGAL_CMD_EN | S_CMD_CANCEL_EN | S_CMD_ABORT_EN |
+ S_GP_IRQ_0_EN | S_GP_IRQ_1_EN | S_GP_IRQ_2_EN | S_GP_IRQ_3_EN |
+ S_RX_FIFO_WR_ERR_EN | S_RX_FIFO_RD_ERR_EN;
+ writel(val, se->base + SE_GENI_S_IRQ_ENABLE);
+
+ /* DMA mode configuration. */
+ val = GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN | GENI_SE_DMA_DONE_EN;
+ writel(val, se->base + SE_DMA_TX_IRQ_EN_SET);
+ val = GENI_SE_DMA_FLUSH_DONE | GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN |
+ GENI_SE_DMA_DONE_EN;
+ writel(val, se->base + SE_DMA_RX_IRQ_EN_SET);
+}
+
+/**
+ * geni_write_fw_revision() - Write the firmware revision.
+ * @se: Pointer to the concerned serial engine.
+ * @serial_protocol: serial protocol type.
+ * @fw_version: QUP firmware version.
+ *
+ * Write the firmware revision and protocol into the respective register.
+ */
+static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version)
+{
+ u32 reg;
+
+ reg = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol);
+ reg |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version);
+
+ writel(reg, se->base + SE_GENI_FW_REVISION);
+ writel(reg, se->base + SE_GENI_S_FW_REVISION);
+}
+
+/**
+ * geni_load_se_fw() - Load Serial Engine specific firmware.
+ * @se: Pointer to the concerned serial engine.
+ * @fw: Pointer to the firmware structure.
+ * @mode: SE data transfer mode.
+ * @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C).
+ *
+ * Load the protocol firmware into the IRAM of the Serial Engine.
+ *
+ * Return: 0 if successful, otherwise return an error value.
+ */
+static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw,
+ enum geni_se_xfer_mode mode, enum geni_se_protocol_type protocol)
+{
+ const u32 *fw_data, *cfg_val_arr;
+ const u8 *cfg_idx_arr;
+ u32 i, reg_value;
+ int ret;
+ struct se_fw_hdr *hdr;
+
+ hdr = geni_find_protocol_fw(se->dev, fw, protocol);
+ if (!hdr)
+ return -EINVAL;
+
+ fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset));
+ cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset);
+ cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset));
+
+ ret = geni_icc_set_bw(se);
+ if (ret)
+ return ret;
+
+ ret = geni_icc_enable(se);
+ if (ret)
+ return ret;
+
+ ret = geni_se_resources_on(se);
+ if (ret)
+ goto out_icc_disable;
+
+ /*
+ * Disable high-priority interrupts until all currently executing
+ * low-priority interrupts have been fully handled.
+ */
+ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE);
+
+ /* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */
+ geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON);
+
+ /* Let hardware to control common cgc. */
+ geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON);
+
+ /*
+ * Setting individual bits in GENI_OUTPUT_CTRL activates corresponding output lines,
+ * allowing the hardware to drive data as configured.
+ */
+ writel(0x0, se->base + GENI_OUTPUT_CTRL);
+
+ /* Set SCLK and HCLK to program RAM */
+ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
+ writel(0x0, se->base + SE_GENI_CLK_CTRL);
+ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
+
+ /* Enable required clocks for DMA CSR, TX and RX. */
+ reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON |
+ DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
+ geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value);
+
+ /* Let hardware control CGC by default. */
+ writel(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL);
+
+ /* Set version of the configuration register part of firmware. */
+ writel(hdr->cfg_version, se->base + SE_GENI_INIT_CFG_REVISION);
+ writel(hdr->cfg_version, se->base + SE_GENI_S_INIT_CFG_REVISION);
+
+ /* Configure GENI primitive table. */
+ for (i = 0; i < le16_to_cpu(hdr->cfg_size_in_items); i++)
+ writel(cfg_val_arr[i],
+ se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32)));
+
+ /* Configure condition for assertion of RX_RFR_WATERMARK condition. */
+ reg_value = geni_se_get_rx_fifo_depth(se);
+ writel(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG);
+
+ /* Let hardware control CGC */
+ geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK);
+
+ ret = geni_configure_xfer_mode(se, mode);
+ if (ret)
+ goto out_resources_off;
+
+ geni_enable_interrupts(se);
+
+ geni_write_fw_revision(se, le16_to_cpu(hdr->serial_protocol), le16_to_cpu(hdr->fw_version));
+
+ /* Program RAM address space. */
+ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data,
+ le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32));
+
+ /* Put default values on GENI's output pads. */
+ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG);
+
+ /* Toggle SCLK/HCLK from high to low to finalize RAM programming and apply config. */
+ geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
+ geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL);
+ geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
+
+ /* Serial engine DMA interface is enabled. */
+ geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN);
+
+ /* Enable or disable FIFO interface of the serial engine. */
+ if (mode == GENI_SE_FIFO)
+ geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
+ else
+ geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
+
+out_resources_off:
+ geni_se_resources_off(se);
+
+out_icc_disable:
+ geni_icc_disable(se);
+ return ret;
+}
+
+/**
+ * geni_load_se_firmware() - Load firmware for SE based on protocol
+ * @se: Pointer to the concerned serial engine.
+ * @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C).
+ *
+ * Retrieves the firmware name from device properties and sets the transfer mode
+ * (FIFO or GSI DMA) based on device tree configuration. Enforces FIFO mode for
+ * UART protocol due to lack of GSI DMA support. Requests the firmware and loads
+ * it into the SE.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol)
+{
+ const char *fw_name;
+ const struct firmware *fw;
+ enum geni_se_xfer_mode mode = GENI_SE_FIFO;
+ int ret;
+
+ if (protocol >= ARRAY_SIZE(protocol_name)) {
+ dev_err(se->dev, "Invalid geni-se protocol: %d", protocol);
+ return -EINVAL;
+ }
+
+ ret = device_property_read_string(se->wrapper->dev, "firmware-name", &fw_name);
+ if (ret) {
+ dev_err(se->dev, "Failed to read firmware-name property: %d\n", ret);
+ return -EINVAL;
+ }
+
+ if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma"))
+ mode = GENI_GPI_DMA;
+
+ /* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */
+ if (protocol == GENI_SE_UART)
+ mode = GENI_SE_FIFO;
+
+ ret = request_firmware(&fw, fw_name, se->dev);
+ if (ret) {
+ dev_err(se->dev, "Failed to request firmware '%s' for protocol %d: ret: %d\n",
+ fw_name, protocol, ret);
+ return ret;
+ }
+
+ ret = geni_load_se_fw(se, fw, mode, protocol);
+ release_firmware(fw);
+
+ if (ret) {
+ dev_err(se->dev, "Failed to load SE firmware for protocol %d: ret: %d\n",
+ protocol, ret);
+ return ret;
+ }
+
+ dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode: %d\n",
+ protocol_name[protocol], mode);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(geni_load_se_firmware);
+
static int geni_se_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index 2996a3c28ef3..0a984e2579fe 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _LINUX_QCOM_GENI_SE
@@ -36,6 +37,7 @@ enum geni_se_protocol_type {
GENI_SE_I2C,
GENI_SE_I3C,
GENI_SE_SPI_SLAVE,
+ GENI_SE_INVALID_PROTO = 255,
};
struct geni_wrapper;
@@ -531,5 +533,7 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag);
int geni_icc_enable(struct geni_se *se);
int geni_icc_disable(struct geni_se *se);
+
+int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol);
#endif
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 4/6] i2c: qcom-geni: Load i2c qup Firmware from linux side
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
` (2 preceding siblings ...)
2025-08-22 7:26 ` [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 5/6] spi: geni-qcom: Load spi " Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 6/6] serial: qcom-geni: Load UART " Viken Dadhaniya
5 siblings, 0 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
Add provision to load firmware of Serial engine for I2C protocol from
Linux Execution Environment on running on APPS processor.
Acked-by: Andi Shyti <andi.shyti@kernel.org>
Co-developed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
Dependencies:
This patch depends on patch 3 of this series.
v5 -> v6:
- Added Acked-by tag.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-4-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Updated the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-4-quic_vdadhani@quicinc.com/
v3 - >v4:
- Add a patch dependency note.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-8-quic_vdadhani@quicinc.com/
v2 -> v3:
- Load firmware only if the protocol is invalid.
v2 Link: https://lore.kernel.org/linux-arm-msm/20250124105309.295769-7-quic_vdadhani@quicinc.com/
v1 -> v2:
- No change.
v1 Link: https://lore.kernel.org/linux-arm-msm/20241204150326.1470749-6-quic_vdadhani@quicinc.com/
---
---
drivers/i2c/busses/i2c-qcom-geni.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index ff2289b52c84..95a577764d5c 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -870,7 +870,13 @@ static int geni_i2c_probe(struct platform_device *pdev)
goto err_clk;
}
proto = geni_se_read_proto(&gi2c->se);
- if (proto != GENI_SE_I2C) {
+ if (proto == GENI_SE_INVALID_PROTO) {
+ ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C);
+ if (ret) {
+ dev_err_probe(dev, ret, "i2c firmware load failed ret: %d\n", ret);
+ goto err_resources;
+ }
+ } else if (proto != GENI_SE_I2C) {
ret = dev_err_probe(dev, -ENXIO, "Invalid proto %d\n", proto);
goto err_resources;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 5/6] spi: geni-qcom: Load spi qup Firmware from linux side
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
` (3 preceding siblings ...)
2025-08-22 7:26 ` [PATCH v6 4/6] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 6/6] serial: qcom-geni: Load UART " Viken Dadhaniya
5 siblings, 0 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
Add provision to load firmware of Serial engine for SPI protocol from
Linux Execution Environment on running on APPS processor.
Co-developed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
Dependencies:
This patch depends on patch 3 of this series.
v5 -> v6:
- No change.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-5-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Updated the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-5-quic_vdadhani@quicinc.com/
v3 -> v4:
- Add a patch dependency note.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-9-quic_vdadhani@quicinc.com/
v2 -> v3:
- Load firmware only if the protocol is invalid.
v2 Link: https://lore.kernel.org/linux-arm-msm/20250124105309.295769-8-quic_vdadhani@quicinc.com/
v1 -> v2:
- No change.
v1 Link: https://lore.kernel.org/linux-arm-msm/20241204150326.1470749-7-quic_vdadhani@quicinc.com/
---
---
drivers/spi/spi-geni-qcom.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 768d7482102a..a0d8d3425c6c 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -671,6 +671,12 @@ static int spi_geni_init(struct spi_geni_master *mas)
goto out_pm;
}
spi_slv_setup(mas);
+ } else if (proto == GENI_SE_INVALID_PROTO) {
+ ret = geni_load_se_firmware(se, GENI_SE_SPI);
+ if (ret) {
+ dev_err(mas->dev, "spi master firmware load failed ret: %d\n", ret);
+ goto out_pm;
+ }
} else if (proto != GENI_SE_SPI) {
dev_err(mas->dev, "Invalid proto %d\n", proto);
goto out_pm;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v6 6/6] serial: qcom-geni: Load UART qup Firmware from linux side
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
` (4 preceding siblings ...)
2025-08-22 7:26 ` [PATCH v6 5/6] spi: geni-qcom: Load spi " Viken Dadhaniya
@ 2025-08-22 7:26 ` Viken Dadhaniya
5 siblings, 0 replies; 8+ messages in thread
From: Viken Dadhaniya @ 2025-08-22 7:26 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, andersson,
konradybcio, broonie, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: mukesh.savaliya, Viken Dadhaniya
Add provision to load firmware of Serial engine for UART protocol from
Linux Execution Environment on running on APPS processor.
Co-developed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
---
Dependencies:
This patch depends on patch 3 of this series.
v5 -> v6:
- No change.
v5 Link: https://lore.kernel.org/linux-i2c/20250624095102.1587580-6-viken.dadhaniya@oss.qualcomm.com/
v4 -> v5:
- Updated the email domain from 'quic' to 'oss'.
v4 Link: https://lore.kernel.org/all/20250503111029.3583807-6-quic_vdadhani@quicinc.com/
v3 -> v4:
- Add a patch dependency note.
v3 Link: https://lore.kernel.org/linux-arm-msm/20250303124349.3474185-10-quic_vdadhani@quicinc.com/
v2 -> v3:
- Load firmware only if the protocol is invalid.
v2 Link: https://lore.kernel.org/linux-arm-msm/20250124105309.295769-9-quic_vdadhani@quicinc.com/
v1 -> v2:
- No change.
v1 Link: https://lore.kernel.org/linux-arm-msm/20241204150326.1470749-8-quic_vdadhani@quicinc.com/
---
---
drivers/tty/serial/qcom_geni_serial.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 9c7b1cea7cfe..eba225be9b38 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1179,7 +1179,13 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
int ret;
proto = geni_se_read_proto(&port->se);
- if (proto != GENI_SE_UART) {
+ if (proto == GENI_SE_INVALID_PROTO) {
+ ret = geni_load_se_firmware(&port->se, GENI_SE_UART);
+ if (ret) {
+ dev_err(uport->dev, "UART firmware load failed ret: %d\n", ret);
+ return ret;
+ }
+ } else if (proto != GENI_SE_UART) {
dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto);
return -ENXIO;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
2025-08-22 7:26 ` [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
@ 2025-08-23 3:11 ` kernel test robot
0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-08-23 3:11 UTC (permalink / raw)
To: Viken Dadhaniya, andi.shyti, robh, krzk+dt, conor+dt, gregkh,
jirislaby, andersson, konradybcio, broonie, johan+linaro,
dianders, agross, linux-arm-msm, linux-i2c, devicetree,
linux-kernel, linux-serial, linux-spi
Cc: oe-kbuild-all, mukesh.savaliya, Viken Dadhaniya
Hi Viken,
kernel test robot noticed the following build warnings:
[auto build test WARNING on andi-shyti/i2c/i2c-host]
[also build test WARNING on tty/tty-testing tty/tty-next tty/tty-linus broonie-spi/for-next linus/master v6.17-rc2 next-20250822]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Viken-Dadhaniya/dt-bindings-qcom-se-common-Add-QUP-Peripheral-specific-properties-for-I2C-SPI-and-SERIAL-bus/20250822-153051
base: https://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c/i2c-host
patch link: https://lore.kernel.org/r/20250822072651.510027-4-viken.dadhaniya%40oss.qualcomm.com
patch subject: [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
config: sparc64-randconfig-r133-20250823 (https://download.01.org/0day-ci/archive/20250823/202508231007.Lp8v1Xdl-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 8.5.0
reproduce: (https://download.01.org/0day-ci/archive/20250823/202508231007.Lp8v1Xdl-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508231007.Lp8v1Xdl-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast to restricted __le32
drivers/soc/qcom/qcom-geni-se.c:1053:21: sparse: sparse: cast from restricted __le16
drivers/soc/qcom/qcom-geni-se.c:1056:25: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1057:47: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1059:25: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1065:43: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1065:25: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1066:48: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1066:25: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1067:48: sparse: sparse: restricted __le16 degrades to integer
drivers/soc/qcom/qcom-geni-se.c:1067:25: sparse: sparse: restricted __le16 degrades to integer
>> drivers/soc/qcom/qcom-geni-se.c:1238:19: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] l @@ got restricted __le16 [usertype] cfg_version @@
drivers/soc/qcom/qcom-geni-se.c:1238:19: sparse: expected unsigned int [usertype] l
drivers/soc/qcom/qcom-geni-se.c:1238:19: sparse: got restricted __le16 [usertype] cfg_version
drivers/soc/qcom/qcom-geni-se.c:1239:19: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] l @@ got restricted __le16 [usertype] cfg_version @@
drivers/soc/qcom/qcom-geni-se.c:1239:19: sparse: expected unsigned int [usertype] l
drivers/soc/qcom/qcom-geni-se.c:1239:19: sparse: got restricted __le16 [usertype] cfg_version
vim +1238 drivers/soc/qcom/qcom-geni-se.c
1165
1166 /**
1167 * geni_load_se_fw() - Load Serial Engine specific firmware.
1168 * @se: Pointer to the concerned serial engine.
1169 * @fw: Pointer to the firmware structure.
1170 * @mode: SE data transfer mode.
1171 * @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C).
1172 *
1173 * Load the protocol firmware into the IRAM of the Serial Engine.
1174 *
1175 * Return: 0 if successful, otherwise return an error value.
1176 */
1177 static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw,
1178 enum geni_se_xfer_mode mode, enum geni_se_protocol_type protocol)
1179 {
1180 const u32 *fw_data, *cfg_val_arr;
1181 const u8 *cfg_idx_arr;
1182 u32 i, reg_value;
1183 int ret;
1184 struct se_fw_hdr *hdr;
1185
1186 hdr = geni_find_protocol_fw(se->dev, fw, protocol);
1187 if (!hdr)
1188 return -EINVAL;
1189
1190 fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset));
1191 cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset);
1192 cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset));
1193
1194 ret = geni_icc_set_bw(se);
1195 if (ret)
1196 return ret;
1197
1198 ret = geni_icc_enable(se);
1199 if (ret)
1200 return ret;
1201
1202 ret = geni_se_resources_on(se);
1203 if (ret)
1204 goto out_icc_disable;
1205
1206 /*
1207 * Disable high-priority interrupts until all currently executing
1208 * low-priority interrupts have been fully handled.
1209 */
1210 geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE);
1211
1212 /* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */
1213 geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON);
1214
1215 /* Let hardware to control common cgc. */
1216 geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON);
1217
1218 /*
1219 * Setting individual bits in GENI_OUTPUT_CTRL activates corresponding output lines,
1220 * allowing the hardware to drive data as configured.
1221 */
1222 writel(0x0, se->base + GENI_OUTPUT_CTRL);
1223
1224 /* Set SCLK and HCLK to program RAM */
1225 geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
1226 writel(0x0, se->base + SE_GENI_CLK_CTRL);
1227 geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
1228
1229 /* Enable required clocks for DMA CSR, TX and RX. */
1230 reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON |
1231 DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
1232 geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value);
1233
1234 /* Let hardware control CGC by default. */
1235 writel(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL);
1236
1237 /* Set version of the configuration register part of firmware. */
> 1238 writel(hdr->cfg_version, se->base + SE_GENI_INIT_CFG_REVISION);
1239 writel(hdr->cfg_version, se->base + SE_GENI_S_INIT_CFG_REVISION);
1240
1241 /* Configure GENI primitive table. */
1242 for (i = 0; i < le16_to_cpu(hdr->cfg_size_in_items); i++)
1243 writel(cfg_val_arr[i],
1244 se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32)));
1245
1246 /* Configure condition for assertion of RX_RFR_WATERMARK condition. */
1247 reg_value = geni_se_get_rx_fifo_depth(se);
1248 writel(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG);
1249
1250 /* Let hardware control CGC */
1251 geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK);
1252
1253 ret = geni_configure_xfer_mode(se, mode);
1254 if (ret)
1255 goto out_resources_off;
1256
1257 geni_enable_interrupts(se);
1258
1259 geni_write_fw_revision(se, le16_to_cpu(hdr->serial_protocol), le16_to_cpu(hdr->fw_version));
1260
1261 /* Program RAM address space. */
1262 memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data,
1263 le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32));
1264
1265 /* Put default values on GENI's output pads. */
1266 writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG);
1267
1268 /* Toggle SCLK/HCLK from high to low to finalize RAM programming and apply config. */
1269 geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
1270 geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL);
1271 geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
1272
1273 /* Serial engine DMA interface is enabled. */
1274 geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN);
1275
1276 /* Enable or disable FIFO interface of the serial engine. */
1277 if (mode == GENI_SE_FIFO)
1278 geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
1279 else
1280 geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
1281
1282 out_resources_off:
1283 geni_se_resources_off(se);
1284
1285 out_icc_disable:
1286 geni_icc_disable(se);
1287 return ret;
1288 }
1289
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-08-23 3:12 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-22 7:26 [PATCH v6 0/6] Add support to load QUP SE firmware from Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 1/6] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 2/6] soc: qcom: geni-se: Cleanup register defines and update copyright Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 3/6] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
2025-08-23 3:11 ` kernel test robot
2025-08-22 7:26 ` [PATCH v6 4/6] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 5/6] spi: geni-qcom: Load spi " Viken Dadhaniya
2025-08-22 7:26 ` [PATCH v6 6/6] serial: qcom-geni: Load UART " Viken Dadhaniya
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).