* [PATCH v4 0/5] Add support to load QUP SE firmware from
@ 2025-05-03 11:10 Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 1/5] 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; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, 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.
---
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 (5):
dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties
for I2C, SPI, and SERIAL bus
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 | 404 +++++++++++++++++-
drivers/spi/spi-geni-qcom.c | 6 +
drivers/tty/serial/qcom_geni_serial.c | 8 +-
include/linux/soc/qcom/geni-se.h | 31 +-
include/linux/soc/qcom/qup-fw-load.h | 89 ++++
10 files changed, 551 insertions(+), 24 deletions(-)
create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml
create mode 100644 include/linux/soc/qcom/qup-fw-load.h
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
@ 2025-05-03 11:10 ` Viken Dadhaniya
2025-05-06 7:05 ` Krzysztof Kozlowski
2025-05-03 11:10 ` [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, Viken Dadhaniya
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.
Co-developed-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Viken Dadhaniya <quic_vdadhani@quicinc.com>
---
v1 -> v2:
- 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.
v1 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..044eea4bb960
--- /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 <quic_msavaliy@quicinc.com>
+ - Viken Dadhaniya <quic_vdadhani@quicinc.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] 10+ messages in thread
* [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
@ 2025-05-03 11:10 ` Viken Dadhaniya
2025-05-05 13:43 ` kernel test robot
2025-05-03 11:10 ` [PATCH v4 3/5] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, 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 <quic_msavaliy@quicinc.com>
Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Viken Dadhaniya <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 | 404 +++++++++++++++++++++++++--
include/linux/soc/qcom/geni-se.h | 31 +-
include/linux/soc/qcom/qup-fw-load.h | 89 ++++++
3 files changed, 502 insertions(+), 22 deletions(-)
create mode 100644 include/linux/soc/qcom/qup-fw-load.h
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 4cb959106efa..ad9595275a9e 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -1,11 +1,15 @@
// 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) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
/* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */
#define __DISABLE_TRACE_MMIO__
#include <linux/acpi.h>
#include <linux/clk.h>
+#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
@@ -15,6 +19,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/soc/qcom/geni-se.h>
+#include <linux/soc/qcom/qup-fw-load.h>
/**
* DOC: Overview
@@ -80,9 +85,9 @@
* common to all the serial engines and are independent of serial interfaces.
*/
-#define MAX_CLK_PERF_LEVEL 32
-#define MAX_CLKS 2
-
+#define MAX_CLK_PERF_LEVEL 32
+#define MAX_CLKS 2
+#define MAX_PROTOCOL 6
/**
* struct geni_wrapper - Data structure to represent the QUP Wrapper Core
* @dev: Device pointer of the QUP wrapper core
@@ -110,28 +115,23 @@ struct geni_se_desc {
static const char * const icc_path_names[] = {"qup-core", "qup-config",
"qup-memory"};
+static const char * const protocol_name[MAX_PROTOCOL] = { "None", "SPI", "UART",
+ "I2C", "I3C", "SPI SLAVE"};
+
#define QUP_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_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
#define SE_DMA_TX_LEN 0xc3c
#define SE_DMA_TX_IRQ_EN 0xc48
-#define SE_DMA_TX_IRQ_EN_SET 0xc4c
#define SE_DMA_TX_IRQ_EN_CLR 0xc50
#define SE_DMA_TX_LEN_IN 0xc54
#define SE_DMA_TX_MAX_BURST 0xc5c
@@ -140,9 +140,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
#define SE_DMA_RX_ATTR 0xd38
#define SE_DMA_RX_LEN 0xd3c
#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 +177,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)
@@ -220,12 +218,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);
@@ -891,6 +889,376 @@ int geni_icc_disable(struct geni_se *se)
}
EXPORT_SYMBOL_GPL(geni_icc_disable);
+/**
+ * geni_read_elf() - Read an ELF file.
+ * @se: Pointer to the SE resources structure.
+ * @fw: Pointer to the firmware buffer.
+ * @pelfseg: Pointer to the SE-specific ELF header.
+ *
+ * Read the ELF file and output a pointer to the header data, which
+ * contains the firmware data and any other details.
+ *
+ * Return: 0 if successful, otherwise return an error value.
+ */
+static int geni_read_elf(struct geni_se *se, const struct firmware *fw, struct elf_se_hdr **pelfseg)
+{
+ const struct elf32_hdr *ehdr;
+ struct elf32_phdr *phdrs, *phdr;
+ const struct elf_se_hdr *elfseg;
+ const u8 *addr;
+ int i;
+
+ if (!fw || fw->size < sizeof(struct elf32_hdr))
+ return -EINVAL;
+
+ ehdr = (struct elf32_hdr *)fw->data;
+ phdrs = (struct elf32_phdr *)(ehdr + 1);
+
+ if (ehdr->e_phnum < 2)
+ return -EINVAL;
+
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ phdr = &phdrs[i];
+
+ if (fw->size < phdr->p_offset + phdr->p_filesz)
+ return -EINVAL;
+
+ 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 elf_se_hdr))
+ continue;
+
+ addr = fw->data + phdr->p_offset;
+ elfseg = (const struct elf_se_hdr *)addr;
+
+ if (elfseg->magic != MAGIC_NUM_SE || elfseg->version != 1)
+ continue;
+
+ if (phdr->p_filesz < elfseg->fw_offset + elfseg->fw_size_in_items * sizeof(u32) ||
+ phdr->p_filesz < elfseg->cfg_idx_offset + elfseg->cfg_items_size * sizeof(u8) ||
+ phdr->p_filesz < elfseg->cfg_val_offset + elfseg->cfg_items_size * sizeof(u32))
+ continue;
+
+ if (elfseg->serial_protocol != se->protocol)
+ continue;
+
+ *pelfseg = (struct elf_se_hdr *)addr;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+/**
+ * geni_configure_xfer_mode() - Set the transfer mode.
+ * @se: Pointer to a structure representing SE-related resources.
+ *
+ * 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)
+{
+ /* Configure SE FIFO, DMA or GSI mode. */
+ switch (se->mode) {
+ case GENI_GPI_DMA:
+ geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
+ writel_relaxed(0x0, se->base + SE_IRQ_EN);
+ writel_relaxed(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_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
+ se->base + SE_IRQ_EN);
+ writel_relaxed(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_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
+ se->base + SE_IRQ_EN);
+ writel_relaxed(0x0, se->base + SE_GSI_EVENT_EN);
+ break;
+
+ default:
+ dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", se->mode);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * geni_enable_interrupts() - Enable interrupts.
+ * @se: Pointer to a structure representing SE-related resources.
+ *
+ * Enable the required interrupts during the firmware load process.
+ *
+ */
+static void geni_enable_interrupts(struct geni_se *se)
+{
+ u32 reg_value;
+
+ /* Enable required interrupts. */
+ writel_relaxed(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN);
+
+ reg_value = 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_relaxed(reg_value, se->base + SE_GENI_S_IRQ_ENABLE);
+
+ /* DMA mode configuration. */
+ reg_value = RESET_DONE_EN | SBE_EN | DMA_DONE_EN;
+ writel_relaxed(reg_value, se->base + SE_DMA_TX_IRQ_EN_SET);
+ reg_value = FLUSH_DONE_EN | RESET_DONE_EN | SBE_EN | DMA_DONE_EN;
+ writel_relaxed(reg_value, se->base + SE_DMA_RX_IRQ_EN_SET);
+}
+
+/**
+ * geni_write_fw_revision() - Write the firmware revision.
+ * @se: Pointer to a structure representing SE-related resources.
+ * @serial_protocol: serial protocol type.
+ * @fw_version: QUP firmware version.
+ *
+ * Write the firmware revision and protocol into the respective register.
+ *
+ * Return: None.
+ */
+static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version)
+{
+ u32 reg_value;
+
+ reg_value = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol);
+ reg_value |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version);
+
+ writel_relaxed(reg_value, se->base + SE_GENI_FW_REVISION);
+ writel_relaxed(reg_value, se->base + SE_S_FW_REVISION);
+}
+
+/**
+ * geni_load_se_fw() - Load Serial Engine specific firmware.
+ * @se: Pointer to a structure representing SE-related resources.
+ * @fw: Pointer to the firmware structure.
+ *
+ * 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)
+{
+ const u32 *fw_data, *cfg_val_arr;
+ const u8 *cfg_idx_arr;
+ u32 i, reg_value, ramn_cnt;
+ int ret;
+ struct elf_se_hdr *hdr;
+
+ ret = geni_read_elf(se, fw, &hdr);
+ if (ret) {
+ dev_err(se->dev, "ELF parsing failed ret: %d\n", ret);
+ return ret;
+ }
+
+ ramn_cnt = hdr->fw_size_in_items;
+ if (hdr->fw_size_in_items % 2 != 0)
+ ramn_cnt++;
+
+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT)
+ return -EINVAL;
+
+ 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 err;
+
+ ramn_cnt = hdr->fw_size_in_items;
+ if (hdr->fw_size_in_items % 2 != 0)
+ ramn_cnt++;
+
+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT)
+ goto err_resource;
+
+ fw_data = (const u32 *)((u8 *)hdr + hdr->fw_offset);
+ cfg_idx_arr = (const u8 *)hdr + hdr->cfg_idx_offset;
+ cfg_val_arr = (const u32 *)((u8 *)hdr + hdr->cfg_val_offset);
+
+ /* Disable high priority interrupt until current low priority interrupts are 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);
+
+ /* Allows to drive corresponding data according to hardware value. */
+ writel_relaxed(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_relaxed(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_relaxed(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL);
+
+ /* Set version of the configuration register part of firmware. */
+ writel_relaxed(hdr->cfg_version, se->base + SE_GENI_INIT_CFG_REVISION);
+ writel_relaxed(hdr->cfg_version, se->base + SE_GENI_S_INIT_CFG_REVISION);
+
+ /* Configure GENI primitive table. */
+ for (i = 0; i < hdr->cfg_items_size; i++)
+ writel_relaxed(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_relaxed(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);
+ if (ret)
+ goto err_resource;
+
+ geni_enable_interrupts(se);
+
+ geni_write_fw_revision(se, hdr->serial_protocol, hdr->fw_version);
+
+ ramn_cnt = hdr->fw_size_in_items;
+ if (hdr->fw_size_in_items % 2 != 0)
+ ramn_cnt++;
+
+ if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT)
+ goto err_resource;
+
+ /* Program RAM address space. */
+ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, ramn_cnt * sizeof(u32));
+
+ /* Put default values on GENI's output pads. */
+ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG);
+
+ /* High to low SCLK and HCLK to finish RAM. */
+ 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 (se->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);
+
+err_resource:
+ geni_se_resources_off(se);
+err:
+ geni_icc_disable(se);
+ return ret;
+}
+
+/**
+ * qup_fw_load() - Initiate firmware load.
+ * @se: Pointer to a structure representing SE-related resources.
+ * @fw_name: Name of the firmware.
+ *
+ * Load the firmware into a specific SE. Read the associated ELF file,
+ * copy the data into a buffer in kernel space using the request_firmware API, write the
+ * data into the SE's IRAM register, and then free the buffers. Handle firmware loading
+ * and parsing for a specific protocol.
+ *
+ * Return: 0 if successful, otherwise return an error value.
+ */
+static int qup_fw_load(struct geni_se *se, const char *fw_name)
+{
+ int ret;
+ const struct firmware *fw;
+ struct device *dev = se->dev;
+
+ ret = request_firmware(&fw, fw_name, dev);
+ if (ret) {
+ dev_err(dev, "request_firmware failed for %d: %d\n", se->protocol, ret);
+ return ret;
+ }
+
+ ret = geni_load_se_fw(se, fw);
+
+ release_firmware(fw);
+
+ return ret;
+}
+
+/**
+ * geni_load_se_firmware() - Initiate firmware loading.
+ * @se: Serial engine details.
+ * @protocol: Protocol (SPI, I2C, or UART) for which the firmware is to be loaded.
+ *
+ * If the device tree properties are configured to load QUP firmware and the firmware
+ * is not already loaded, start the firmware loading process. If the device tree properties
+ * are not defined, skip loading the firmware, assuming it is already loaded by TZ.
+ *
+ * Return: 0 if successful, otherwise return an error value.
+ */
+int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol)
+{
+ const char *fw_name;
+ int ret;
+
+ if (protocol >= MAX_PROTOCOL) {
+ 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)
+ return -EINVAL;
+
+ se->protocol = protocol;
+
+ if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma"))
+ se->mode = GENI_GPI_DMA;
+ else
+ se->mode = GENI_SE_FIFO;
+
+ /* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */
+ if (protocol == GENI_SE_UART)
+ se->mode = GENI_SE_FIFO;
+
+ ret = qup_fw_load(se, fw_name);
+ if (ret)
+ return ret;
+
+ dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode %d\n",
+ protocol_name[se->protocol], se->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..c6c01c3cf819 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) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#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;
@@ -61,6 +63,8 @@ struct geni_icc_path {
* @num_clk_levels: Number of valid clock levels in clk_perf_tbl
* @clk_perf_tbl: Table of clock frequency input to serial engine clock
* @icc_paths: Array of ICC paths for SE
+ * @mode: Transfer mode se fifo, dma or gsi.
+ * @protocol: Protocol spi or i2c or serial.
*/
struct geni_se {
void __iomem *base;
@@ -70,24 +74,32 @@ struct geni_se {
unsigned int num_clk_levels;
unsigned long *clk_perf_tbl;
struct geni_icc_path icc_paths[3];
+ enum geni_se_xfer_mode mode;
+ enum geni_se_protocol_type protocol;
};
/* Common SE registers */
+#define SE_GENI_INIT_CFG_REVISION 0x0
+#define SE_GENI_S_INIT_CFG_REVISION 0x4
#define GENI_FORCE_DEFAULT_REG 0x20
#define GENI_OUTPUT_CTRL 0x24
+#define SE_GENI_CGC_CTRL 0x28
#define SE_GENI_STATUS 0x40
#define GENI_SER_M_CLK_CFG 0x48
#define GENI_SER_S_CLK_CFG 0x4c
#define GENI_IF_DISABLE_RO 0x64
-#define GENI_FW_REVISION_RO 0x68
+#define SE_GENI_FW_REVISION_RO 0x68
+#define SE_GENI_S_FW_REVISION_RO 0x6c
#define SE_GENI_CLK_SEL 0x7c
#define SE_GENI_CFG_SEQ_START 0x84
+#define SE_GENI_CFG_REG0 0x100
#define SE_GENI_DMA_MODE_EN 0x258
#define SE_GENI_M_CMD0 0x600
#define SE_GENI_M_CMD_CTRL_REG 0x604
#define SE_GENI_M_IRQ_STATUS 0x610
#define SE_GENI_M_IRQ_EN 0x614
#define SE_GENI_M_IRQ_CLEAR 0x618
+#define SE_GENI_S_IRQ_ENABLE 0x644
#define SE_GENI_M_IRQ_EN_SET 0x61c
#define SE_GENI_M_IRQ_EN_CLEAR 0x620
#define SE_GENI_S_CMD0 0x630
@@ -109,13 +121,22 @@ struct geni_se {
#define SE_GENI_S_GP_LENGTH 0x914
#define SE_DMA_TX_IRQ_STAT 0xc40
#define SE_DMA_TX_IRQ_CLR 0xc44
+#define SE_DMA_TX_IRQ_EN_SET 0xc4c
#define SE_DMA_TX_FSM_RST 0xc58
#define SE_DMA_RX_IRQ_STAT 0xd40
#define SE_DMA_RX_IRQ_CLR 0xd44
+#define SE_DMA_RX_IRQ_EN_SET 0xd4c
#define SE_DMA_RX_LEN_IN 0xd54
#define SE_DMA_RX_FSM_RST 0xd58
#define SE_HW_PARAM_0 0xe24
#define SE_HW_PARAM_1 0xe28
+#define SE_DMA_GENERAL_CFG 0xe30
+#define SE_GENI_FW_REVISION 0x1000
+#define SE_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_FORCE_DEFAULT_REG fields */
#define FORCE_DEFAULT BIT(0)
@@ -137,7 +158,7 @@ struct geni_se {
/* GENI_FW_REVISION_RO fields */
#define FW_REV_PROTOCOL_MSK GENMASK(15, 8)
-#define FW_REV_PROTOCOL_SHFT 8
+#define FW_REV_VERSION_MSK GENMASK(7, 0)
/* GENI_CLK_SEL fields */
#define CLK_SEL_MSK GENMASK(2, 0)
@@ -325,9 +346,9 @@ static inline u32 geni_se_read_proto(struct geni_se *se)
{
u32 val;
- val = readl_relaxed(se->base + GENI_FW_REVISION_RO);
+ val = readl_relaxed(se->base + SE_GENI_FW_REVISION_RO);
- return (val & FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT;
+ return FIELD_GET(FW_REV_PROTOCOL_MSK, val);
}
/**
@@ -531,5 +552,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
diff --git a/include/linux/soc/qcom/qup-fw-load.h b/include/linux/soc/qcom/qup-fw-load.h
new file mode 100644
index 000000000000..08d8a22ae514
--- /dev/null
+++ b/include/linux/soc/qcom/qup-fw-load.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _LINUX_QCOM_QUP_FW_LOAD
+#define _LINUX_QCOM_QUP_FW_LOAD
+
+#include <linux/kernel.h>
+
+/*Magic numbers*/
+#define MAGIC_NUM_SE 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)
+
+/* DMA_TX/RX_IRQ_EN fields */
+#define DMA_DONE_EN BIT(0)
+#define SBE_EN BIT(2)
+#define RESET_DONE_EN BIT(3)
+#define FLUSH_DONE_EN BIT(4)
+
+/* GENI_CLK_CTRL fields */
+#define SER_CLK_SEL BIT(0)
+
+/* GENI_DMA_IF_EN fields */
+#define DMA_IF_EN BIT(0)
+
+#define QUPV3_COMMON_CFG 0x120
+#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0)
+
+#define QUPV3_SE_AHB_M_CFG 0x118
+#define AHB_M_CLK_CGC_ON BIT(0)
+
+#define QUPV3_COMMON_CGC_CTRL 0x21C
+#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0)
+
+/* access ports */
+#define geni_setbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) | (_v), _addr)
+#define geni_clrbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) & ~(_v), _addr)
+
+/**
+ * struct elf_se_hdr - firmware configurations
+ *
+ * @magic: set to 'SEFW'
+ * @version: A 32-bit value indicating the structure’s version number
+ * @core_version: QUPV3_HW_VERSION
+ * @serial_protocol: Programmed into GENI_FW_REVISION
+ * @fw_version: Programmed into GENI_FW_REVISION
+ * @cfg_version: Programmed into GENI_INIT_CFG_REVISION
+ * @fw_size_in_items: Number of (uint32_t) GENI_FW_RAM words
+ * @fw_offset: Byte offset of GENI_FW_RAM array
+ * @cfg_items_size: Number of GENI_FW_CFG index/value pairs
+ * @cfg_idx_offset: Byte offset of GENI_FW_CFG index array
+ * @cfg_val_offset: Byte offset of GENI_FW_CFG values array
+ */
+struct elf_se_hdr {
+ u32 magic;
+ u32 version;
+ u32 core_version;
+ u16 serial_protocol;
+ u16 fw_version;
+ u16 cfg_version;
+ u16 fw_size_in_items;
+ u16 fw_offset;
+ u16 cfg_items_size;
+ u16 cfg_idx_offset;
+ u16 cfg_val_offset;
+};
+#endif /* _LINUX_QCOM_QUP_FW_LOAD */
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/5] i2c: qcom-geni: Load i2c qup Firmware from linux side
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
@ 2025-05-03 11:10 ` Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 4/5] spi: geni-qcom: Load spi " Viken Dadhaniya
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, Viken Dadhaniya
Add provision to load firmware of Serial engine for I2C protocol from
Linux Execution Environment on running on APPS processor.
Co-developed-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Viken Dadhaniya <quic_vdadhani@quicinc.com>
---
Dependencies:
This patch depends on patch 2 of this series.
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 ccea575fb783..97be9e468c75 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] 10+ messages in thread
* [PATCH v4 4/5] spi: geni-qcom: Load spi qup Firmware from linux side
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
` (2 preceding siblings ...)
2025-05-03 11:10 ` [PATCH v4 3/5] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
@ 2025-05-03 11:10 ` Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 5/5] serial: qcom-geni: Load UART " Viken Dadhaniya
2025-05-03 11:20 ` [PATCH v4 0/5] Add support to load QUP SE firmware from Konrad Dybcio
5 siblings, 0 replies; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, 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 <quic_msavaliy@quicinc.com>
Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Viken Dadhaniya <quic_vdadhani@quicinc.com>
---
Dependencies:
This patch depends on patch 2 of this series.
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] 10+ messages in thread
* [PATCH v4 5/5] serial: qcom-geni: Load UART qup Firmware from linux side
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
` (3 preceding siblings ...)
2025-05-03 11:10 ` [PATCH v4 4/5] spi: geni-qcom: Load spi " Viken Dadhaniya
@ 2025-05-03 11:10 ` Viken Dadhaniya
2025-05-03 11:20 ` [PATCH v4 0/5] Add support to load QUP SE firmware from Konrad Dybcio
5 siblings, 0 replies; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-03 11:10 UTC (permalink / raw)
To: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk, 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 <quic_msavaliy@quicinc.com>
Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
Signed-off-by: Viken Dadhaniya <quic_vdadhani@quicinc.com>
---
Dependencies:
This patch depends on patch 2 of this series.
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 0293b6210aa6..9f905ae3c127 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1161,7 +1161,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] 10+ messages in thread
* Re: [PATCH v4 0/5] Add support to load QUP SE firmware from
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
` (4 preceding siblings ...)
2025-05-03 11:10 ` [PATCH v4 5/5] serial: qcom-geni: Load UART " Viken Dadhaniya
@ 2025-05-03 11:20 ` Konrad Dybcio
2025-05-06 9:15 ` Viken Dadhaniya
5 siblings, 1 reply; 10+ messages in thread
From: Konrad Dybcio @ 2025-05-03 11:20 UTC (permalink / raw)
To: Viken Dadhaniya, andi.shyti, robh, krzk+dt, conor+dt, gregkh,
jirislaby, broonie, andersson, konradybcio, johan+linaro,
dianders, agross, linux-arm-msm, linux-i2c, devicetree,
linux-kernel, linux-serial, linux-spi
Cc: quic_msavaliy, quic_anupkulk
On 5/3/25 1:10 PM, Viken Dadhaniya wrote:
You sent this series at 1:10 PM and replied to review comments on the
previous revision at 1:11 PM - please refrain from doing that, as
you're effectively stalling your submission because of lingering
unsolved problems that ultimately still need to be solved before
the patches are merged.
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
2025-05-03 11:10 ` [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
@ 2025-05-05 13:43 ` kernel test robot
0 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2025-05-05 13:43 UTC (permalink / raw)
To: Viken Dadhaniya, andi.shyti, robh, krzk+dt, conor+dt, gregkh,
jirislaby, broonie, andersson, konradybcio, johan+linaro,
dianders, agross, linux-arm-msm, linux-i2c, devicetree,
linux-kernel, linux-serial, linux-spi
Cc: oe-kbuild-all, quic_msavaliy, quic_anupkulk, Viken Dadhaniya
Hi Viken,
kernel test robot noticed the following build errors:
[auto build test ERROR on andi-shyti/i2c/i2c-host]
[also build test ERROR on tty/tty-testing tty/tty-next tty/tty-linus broonie-spi/for-next linus/master v6.15-rc5 next-20250505]
[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/20250503-191235
base: https://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c/i2c-host
patch link: https://lore.kernel.org/r/20250503111029.3583807-3-quic_vdadhani%40quicinc.com
patch subject: [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem
config: sparc64-randconfig-002-20250505 (https://download.01.org/0day-ci/archive/20250505/202505052109.5N8caeeW-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250505/202505052109.5N8caeeW-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/202505052109.5N8caeeW-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/tty/serial/qcom_geni_serial.c:18:
include/linux/soc/qcom/geni-se.h: In function 'geni_se_read_proto':
>> include/linux/soc/qcom/geni-se.h:351:16: error: implicit declaration of function 'FIELD_GET' [-Werror=implicit-function-declaration]
351 | return FIELD_GET(FW_REV_PROTOCOL_MSK, val);
| ^~~~~~~~~
cc1: some warnings being treated as errors
--
In file included from drivers/soc/qcom/qcom-geni-se.c:21:
include/linux/soc/qcom/geni-se.h: In function 'geni_se_read_proto':
>> include/linux/soc/qcom/geni-se.h:351:16: error: implicit declaration of function 'FIELD_GET' [-Werror=implicit-function-declaration]
351 | return FIELD_GET(FW_REV_PROTOCOL_MSK, val);
| ^~~~~~~~~
drivers/soc/qcom/qcom-geni-se.c: In function 'geni_write_fw_revision':
>> drivers/soc/qcom/qcom-geni-se.c:1042:21: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
1042 | reg_value = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol);
| ^~~~~~~~~~
cc1: some warnings being treated as errors
vim +/FIELD_GET +351 include/linux/soc/qcom/geni-se.h
338
339 /**
340 * geni_se_read_proto() - Read the protocol configured for a serial engine
341 * @se: Pointer to the concerned serial engine.
342 *
343 * Return: Protocol value as configured in the serial engine.
344 */
345 static inline u32 geni_se_read_proto(struct geni_se *se)
346 {
347 u32 val;
348
349 val = readl_relaxed(se->base + SE_GENI_FW_REVISION_RO);
350
> 351 return FIELD_GET(FW_REV_PROTOCOL_MSK, val);
352 }
353
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus
2025-05-03 11:10 ` [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
@ 2025-05-06 7:05 ` Krzysztof Kozlowski
0 siblings, 0 replies; 10+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-06 7:05 UTC (permalink / raw)
To: Viken Dadhaniya
Cc: andi.shyti, robh, krzk+dt, conor+dt, gregkh, jirislaby, broonie,
andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi, quic_msavaliy, quic_anupkulk
On Sat, May 03, 2025 at 04:40:25PM GMT, Viken Dadhaniya wrote:
> 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.
>
> Co-developed-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
> Signed-off-by: Mukesh Kumar Savaliya <quic_msavaliy@quicinc.com>
> Signed-off-by: Viken Dadhaniya <quic_vdadhani@quicinc.com>
> ---
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/5] Add support to load QUP SE firmware from
2025-05-03 11:20 ` [PATCH v4 0/5] Add support to load QUP SE firmware from Konrad Dybcio
@ 2025-05-06 9:15 ` Viken Dadhaniya
0 siblings, 0 replies; 10+ messages in thread
From: Viken Dadhaniya @ 2025-05-06 9:15 UTC (permalink / raw)
To: Konrad Dybcio, andi.shyti, robh, krzk+dt, conor+dt, gregkh,
jirislaby, andersson, konradybcio, johan+linaro, dianders, agross,
linux-arm-msm, linux-i2c, devicetree, linux-kernel, linux-serial,
linux-spi
Cc: quic_msavaliy, quic_anupkulk
On 5/3/2025 4:50 PM, Konrad Dybcio wrote:
> On 5/3/25 1:10 PM, Viken Dadhaniya wrote:
>
> You sent this series at 1:10 PM and replied to review comments on the
> previous revision at 1:11 PM - please refrain from doing that, as
> you're effectively stalling your submission because of lingering
> unsolved problems that ultimately still need to be solved before
> the patches are merged.
>
> Konrad
Sure, I will take care of it in future patches.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-05-06 9:16 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-03 11:10 [PATCH v4 0/5] Add support to load QUP SE firmware from Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 1/5] dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Viken Dadhaniya
2025-05-06 7:05 ` Krzysztof Kozlowski
2025-05-03 11:10 ` [PATCH v4 2/5] soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem Viken Dadhaniya
2025-05-05 13:43 ` kernel test robot
2025-05-03 11:10 ` [PATCH v4 3/5] i2c: qcom-geni: Load i2c qup Firmware from linux side Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 4/5] spi: geni-qcom: Load spi " Viken Dadhaniya
2025-05-03 11:10 ` [PATCH v4 5/5] serial: qcom-geni: Load UART " Viken Dadhaniya
2025-05-03 11:20 ` [PATCH v4 0/5] Add support to load QUP SE firmware from Konrad Dybcio
2025-05-06 9:15 ` 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).