* [PATCH 3/3] pmdomain: qcom: rpmhpd: Add power domains for Nord SoC
From: Shawn Guo @ 2026-04-14 3:59 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Konrad Dybcio, Kamal Wadhwa, Taniya Das, Bartosz Golaszewski,
Deepti Jaggi, linux-arm-msm, linux-pm, devicetree, linux-kernel,
Shawn Guo
In-Reply-To: <20260414035909.652992-1-shengchao.guo@oss.qualcomm.com>
From: Kamal Wadhwa <kamal.wadhwa@oss.qualcomm.com>
Add RPMh power domains required for Nord SoC. This includes
new definitions for power domains supplying GFX1 and NSP3 subsystem.
Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Kamal Wadhwa <kamal.wadhwa@oss.qualcomm.com>
Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
---
drivers/pmdomain/qcom/rpmhpd.c | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index ba0cf4694435..63120e703923 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -122,6 +122,11 @@ static struct rpmhpd gfx = {
.res_name = "gfx.lvl",
};
+static struct rpmhpd gfx1 = {
+ .pd = { .name = "gfx1", },
+ .res_name = "gfx1.lvl",
+};
+
static struct rpmhpd lcx = {
.pd = { .name = "lcx", },
.res_name = "lcx.lvl",
@@ -217,6 +222,11 @@ static struct rpmhpd nsp2 = {
.res_name = "nsp2.lvl",
};
+static struct rpmhpd nsp3 = {
+ .pd = { .name = "nsp3", },
+ .res_name = "nsp3.lvl",
+};
+
static struct rpmhpd qphy = {
.pd = { .name = "qphy", },
.res_name = "qphy.lvl",
@@ -308,6 +318,30 @@ static const struct rpmhpd_desc sa8775p_desc = {
.num_pds = ARRAY_SIZE(sa8775p_rpmhpds),
};
+/* Nord RPMH powerdomains */
+static struct rpmhpd *nord_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_GFX1] = &gfx1,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MMCX] = &mmcx,
+ [RPMHPD_MMCX_AO] = &mmcx_ao,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_MXC_AO] = &mxc_ao,
+ [RPMHPD_NSP0] = &nsp0,
+ [RPMHPD_NSP1] = &nsp1,
+ [RPMHPD_NSP2] = &nsp2,
+ [RPMHPD_NSP3] = &nsp3,
+};
+
+static const struct rpmhpd_desc nord_desc = {
+ .rpmhpds = nord_rpmhpds,
+ .num_pds = ARRAY_SIZE(nord_rpmhpds),
+};
+
/* SAR2130P RPMH powerdomains */
static struct rpmhpd *sar2130p_rpmhpds[] = {
[RPMHPD_CX] = &cx,
@@ -856,6 +890,7 @@ static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,hawi-rpmhpd", .data = &hawi_desc },
{ .compatible = "qcom,kaanapali-rpmhpd", .data = &kaanapali_desc },
{ .compatible = "qcom,milos-rpmhpd", .data = &milos_desc },
+ { .compatible = "qcom,nord-rpmhpd", .data = &nord_desc },
{ .compatible = "qcom,qcs615-rpmhpd", .data = &qcs615_desc },
{ .compatible = "qcom,qcs8300-rpmhpd", .data = &qcs8300_desc },
{ .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
--
2.43.0
^ permalink raw reply related
* [PATCH 0/2] Add support for MAX20830 PMBUS
From: Alexis Czezar Torreno @ 2026-04-14 4:28 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, Shuah Khan
Cc: linux-hwmon, devicetree, linux-kernel, linux-doc,
Alexis Czezar Torreno
This series adds support for the Analog Devices MAX20830 step-down
switching regulator with PMBus interface.
The MAX20830 provides 2.7V to 16V input, 0.4V to 5.8V output, and up
to 30A output current. It supports monitoring of input/output voltage,
output current, and temperature via PMBus.
Datasheet: https://www.analog.com/en/products/max20830.html
Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
---
Alexis Czezar Torreno (2):
dt-bindings: hwmon: pmbus: add max20830
hwmon: (pmbus/max20830) add driver for max20830
.../bindings/hwmon/pmbus/adi,max20830.yaml | 58 +++++++++++++++++
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/max20830.rst | 48 ++++++++++++++
MAINTAINERS | 9 +++
drivers/hwmon/pmbus/Kconfig | 9 +++
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/max20830.c | 74 ++++++++++++++++++++++
7 files changed, 200 insertions(+)
---
base-commit: fb447217c59a13b2fff22d94de2498c185cd9032
change-id: 20260414-dev_max20830-9460b92cf6aa
Best regards,
--
Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
^ permalink raw reply
* [PATCH 2/2] hwmon: (pmbus/max20830) add driver for max20830
From: Alexis Czezar Torreno @ 2026-04-14 4:28 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, Shuah Khan
Cc: linux-hwmon, devicetree, linux-kernel, linux-doc,
Alexis Czezar Torreno
In-Reply-To: <20260414-dev_max20830-v1-0-210d3f82c571@analog.com>
Add support for MAX20830 step-down DC-DC switching regulator with
PMBus interface. It allows monitoring of input/output voltage,
output current and temperature through the PMBus serial interface.
Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
---
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/max20830.rst | 48 ++++++++++++++++++++++++++
MAINTAINERS | 2 ++
drivers/hwmon/pmbus/Kconfig | 9 +++++
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/max20830.c | 74 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 135 insertions(+)
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 8b655e5d6b68b90c697a52c7bf526e81d370caf7..56f7eb761be76dd627a2f34135abad05203b0582 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -158,6 +158,7 @@ Hardware Monitoring Kernel Drivers
max197
max20730
max20751
+ max20830
max31722
max31730
max31760
diff --git a/Documentation/hwmon/max20830.rst b/Documentation/hwmon/max20830.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b9dffb76059781932d383ed798cecff69e738873
--- /dev/null
+++ b/Documentation/hwmon/max20830.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver max20830
+======================
+
+Supported chips:
+
+ * Analog Devices MAX20830
+
+ Prefix: 'max20830'
+
+ Addresses scanned: -
+
+ Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max20830.pdf
+
+Author:
+
+ - Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+
+
+Description
+-----------
+
+This driver supports hardware monitoring for Analog Devices MAX20830
+Step-Down Switching Regulator with PMBus Interface.
+
+The MAX20830 is a 2.7V to 16V, 30A fully integrated step-down DC-DC switching
+regulator. Through the PMBus interface, the device can monitor input/output
+voltages, output current and temperature.
+
+The driver is a client driver to the core PMBus driver. Please see
+Documentation/hwmon/pmbus.rst for details on PMBus client drivers.
+
+Sysfs entries
+-------------
+
+================= ========================================
+in1_label "vin"
+in1_input Measured input voltage
+in1_alarm Input voltage alarm
+in2_label "vout1"
+in2_input Measured output voltage
+curr1_label "iout1"
+curr1_input Measured output current
+curr1_alarm Output current alarm
+temp1_input Measured temperature
+temp1_alarm Chip temperature alarm
+================= ========================================
diff --git a/MAINTAINERS b/MAINTAINERS
index 031c743e979521a92ed9ac67915c178ce31727bd..d6a6745e2dae29c3b8f80bbe61c54a2f5ecd9f47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15585,6 +15585,8 @@ L: linux-hwmon@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/hwmon/pmbus/adi,max20830.yaml
+F: Documentation/hwmon/max20830.rst
+F: drivers/hwmon/pmbus/max20830.c
MAX2175 SDR TUNER DRIVER
M: Ramesh Shanmugasundaram <rashanmu@gmail.com>
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 8f4bff375ecbc355f5ed3400855c2852ec2aa5ef..987705bf45b75b7b91ccc469247909f3c3f53d77 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -365,6 +365,15 @@ config SENSORS_MAX20751
This driver can also be built as a module. If so, the module will
be called max20751.
+config SENSORS_MAX20830
+ tristate "Analog Devices MAX20830"
+ help
+ If you say yes here you get hardware monitoring support for Analog
+ Devices MAX20830.
+
+ This driver can also be built as a module. If so, the module will
+ be called max20830.
+
config SENSORS_MAX31785
tristate "Maxim MAX31785 and compatibles"
help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 7129b62bc00f8a2e98de14004997752a856dfda2..bc52f930e0825a902a0dd1c9e2b44f2e8d577c35 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SENSORS_MAX16601) += max16601.o
obj-$(CONFIG_SENSORS_MAX17616) += max17616.o
obj-$(CONFIG_SENSORS_MAX20730) += max20730.o
obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
+obj-$(CONFIG_SENSORS_MAX20830) += max20830.o
obj-$(CONFIG_SENSORS_MAX31785) += max31785.o
obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
diff --git a/drivers/hwmon/pmbus/max20830.c b/drivers/hwmon/pmbus/max20830.c
new file mode 100644
index 0000000000000000000000000000000000000000..bcf60fd948e3437f47267747547142704ae96378
--- /dev/null
+++ b/drivers/hwmon/pmbus/max20830.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hardware monitoring driver for Analog Devices MAX20830
+ *
+ * Copyright (C) 2026 Analog Devices, Inc.
+ */
+
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include "pmbus.h"
+
+static struct pmbus_driver_info max20830_info = {
+ .pages = 1,
+ .format[PSC_VOLTAGE_IN] = linear,
+ .format[PSC_VOLTAGE_OUT] = linear,
+ .format[PSC_CURRENT_OUT] = linear,
+ .format[PSC_TEMPERATURE] = linear,
+ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+ PMBUS_HAVE_TEMP |
+ PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+ PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
+};
+
+static int max20830_probe(struct i2c_client *client)
+{
+ u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK))
+ return -ENODEV;
+
+ ret = i2c_smbus_read_i2c_block_data(client, PMBUS_IC_DEVICE_ID,
+ I2C_SMBUS_BLOCK_MAX, buf);
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to read IC_DEVICE_ID\n");
+
+ buf[ret] = '\0';
+ if (ret < 9 || strncmp(buf + 1, "MAX20830", 8))
+ return dev_err_probe(&client->dev, -ENODEV,
+ "Unsupported device: '%s'\n", buf);
+
+ return pmbus_do_probe(client, &max20830_info);
+}
+
+static const struct i2c_device_id max20830_id[] = {
+ {"max20830"},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max20830_id);
+
+static const struct of_device_id max20830_of_match[] = {
+ { .compatible = "adi,max20830" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max20830_of_match);
+
+static struct i2c_driver max20830_driver = {
+ .driver = {
+ .name = "max20830",
+ .of_match_table = max20830_of_match,
+ },
+ .probe = max20830_probe,
+ .id_table = max20830_id,
+};
+
+module_i2c_driver(max20830_driver);
+
+MODULE_AUTHOR("Alexis Czezar Torreno <alexisczezar.torreno@analog.com>");
+MODULE_DESCRIPTION("PMBus driver for Analog Devices MAX20830");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
--
2.34.1
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: hwmon: pmbus: add max20830
From: Alexis Czezar Torreno @ 2026-04-14 4:28 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, Shuah Khan
Cc: linux-hwmon, devicetree, linux-kernel, linux-doc,
Alexis Czezar Torreno
In-Reply-To: <20260414-dev_max20830-v1-0-210d3f82c571@analog.com>
Add device tree documentation for MAX20830 step-down DC-DC switching
regulator with PMBus interface.
Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
---
.../bindings/hwmon/pmbus/adi,max20830.yaml | 58 ++++++++++++++++++++++
MAINTAINERS | 7 +++
2 files changed, 65 insertions(+)
diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/adi,max20830.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/adi,max20830.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b20f3be176615895e70e74bfb2a534d82d124a15
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/pmbus/adi,max20830.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/pmbus/adi,max20830.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices MAX20830 Step-Down Switching Regulator with PMBus
+
+maintainers:
+ - Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+
+description: |
+ The MAX20830 is a fully integrated step-down DC-DC switching regulator with
+ PMBus interface. It provides 2.7V to 16V input, 0.4V to 5.8V adjustable
+ output, and up to 30A output current. It allows monitoring of input/output
+ voltage, output current and temperature through the PMBus serial interface.
+ Datasheet:
+ https://www.analog.com/en/products/max20830.html
+
+properties:
+ compatible:
+ const: adi,max20830
+
+ reg:
+ maxItems: 1
+
+ vddh-supply:
+ description:
+ Phandle to the regulator that provides the VDDH power supply.
+
+ avdd-supply:
+ description:
+ Phandle to the regulator that provides the AVDD power supply.
+
+ ldoin-supply:
+ description:
+ Optional 2.5V to 5.5V LDO input supply.
+
+required:
+ - compatible
+ - reg
+ - vddh-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hwmon@30 {
+ compatible = "adi,max20830";
+ reg = <0x30>;
+ vddh-supply = <&vddh>;
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 0a3991c10ade20dd79cc7d1bf2a1d307ba6bd19d..031c743e979521a92ed9ac67915c178ce31727bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15579,6 +15579,13 @@ F: Documentation/devicetree/bindings/hwmon/pmbus/adi,max17616.yaml
F: Documentation/hwmon/max17616.rst
F: drivers/hwmon/pmbus/max17616.c
+MAX20830 HARDWARE MONITOR DRIVER
+M: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+L: linux-hwmon@vger.kernel.org
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/devicetree/bindings/hwmon/pmbus/adi,max20830.yaml
+
MAX2175 SDR TUNER DRIVER
M: Ramesh Shanmugasundaram <rashanmu@gmail.com>
L: linux-media@vger.kernel.org
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v5 4/5] remoteproc: qcom: pas: Add late attach support for subsystems
From: Jingyi Wang @ 2026-04-14 4:56 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Mathieu Poirier, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Luca Weiss, Bartosz Golaszewski,
Konrad Dybcio, aiqun.yu, tingwei.zhang, trilok.soni, yijie.yang,
linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Gokul Krishna Krishnakumar
In-Reply-To: <adm37MruBfXAjLpZ@baldur>
On 4/11/2026 10:59 AM, Bjorn Andersson wrote:
> On Thu, Apr 09, 2026 at 01:52:27AM -0700, Jingyi Wang wrote:
>> Subsystems can be brought out of reset by entities such as bootloaders.
>> As the irq enablement could be later than subsystem bring up, the state
>> of subsystem should be checked by reading SMP2P bits and performing ping
>> test.
>>
Hi Bjorn,
>
> I still don't understand.
>
> Are you saying that devm_request_threaded_irq() will succeed and then
> calling irq_get_irqchip_state() will not work? Or are you saying that
> SMP2P driver isn't reliable and we're loosing the ready or fatal bits?
>
This says the ready state is getting from irq_get_irqchip_state()
instead of q6v5_ready_interrupt(like what rproc start do)
>
> In the reply to v4 you replied to me with "it's a downstream feature".
> That isn't a reason for performing this extra dance, either downstream
> or upstream.
>
I think the "downtream feature" in v4 means, if getting ready state
from SMP2P bits fail, no more waiting. And this has been removed in
this version.
>> A new qcom_pas_attach() function is introduced. if a crash state is
>> detected for the subsystem, rproc_report_crash() is called. If the
>> subsystem is ready and the ping is successful, it will be marked as
>> "attached". If ready irq is not received, it could be the early boot
>> feature is not supported by other entities. In this case, the state will
>> be marked as RPROC_OFFLINE so that the PAS driver can load the firmware
>> and start the remoteproc.
>>
>> Co-developed-by: Gokul Krishna Krishnakumar <gokul.krishnakumar@oss.qualcomm.com>
>> Signed-off-by: Gokul Krishna Krishnakumar <gokul.krishnakumar@oss.qualcomm.com>
>> Signed-off-by: Jingyi Wang <jingyi.wang@oss.qualcomm.com>
>> ---
>> drivers/remoteproc/qcom_q6v5.c | 69 ++++++++++++++++++++++++++++++++
>> drivers/remoteproc/qcom_q6v5.h | 6 +++
>> drivers/remoteproc/qcom_q6v5_pas.c | 80 ++++++++++++++++++++++++++++++++++++--
>> 3 files changed, 152 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c
>> index 58d5b85e58cd..52247c17c38a 100644
>> --- a/drivers/remoteproc/qcom_q6v5.c
>> +++ b/drivers/remoteproc/qcom_q6v5.c
>> @@ -20,6 +20,7 @@
>>
>> #define Q6V5_LOAD_STATE_MSG_LEN 64
>> #define Q6V5_PANIC_DELAY_MS 200
>> +#define Q6V5_PING_TIMEOUT_MS 500
>
> Changelog says you removed 5 second timeout, but you only removed 4.5
> seconds.
>
EARLY_ATTACH_TIMEOUT_MS has been removed and Q6V5_PING_TIMEOUT_MS is used for
soccp ping-pong.
Thanks,
Jingyi
> Regards,
> Bjorn
>
>>
>> static int q6v5_load_state_toggle(struct qcom_q6v5 *q6v5, bool enable)
>> {
>> @@ -234,6 +235,74 @@ unsigned long qcom_q6v5_panic(struct qcom_q6v5 *q6v5)
>> }
>> EXPORT_SYMBOL_GPL(qcom_q6v5_panic);
>>
>> +static irqreturn_t q6v5_pong_interrupt(int irq, void *data)
>> +{
>> + struct qcom_q6v5 *q6v5 = data;
>> +
>> + complete(&q6v5->ping_done);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +int qcom_q6v5_ping_subsystem(struct qcom_q6v5 *q6v5)
>> +{
>> + int ret;
>> + int ping_failed = 0;
>> +
>> + reinit_completion(&q6v5->ping_done);
>> +
>> + /* Set master kernel Ping bit */
>> + ret = qcom_smem_state_update_bits(q6v5->ping_state,
>> + BIT(q6v5->ping_bit), BIT(q6v5->ping_bit));
>> + if (ret) {
>> + dev_err(q6v5->dev, "Failed to update ping bits\n");
>> + return ret;
>> + }
>> +
>> + ret = wait_for_completion_timeout(&q6v5->ping_done, msecs_to_jiffies(Q6V5_PING_TIMEOUT_MS));
>> + if (!ret) {
>> + ping_failed = -ETIMEDOUT;
>> + dev_err(q6v5->dev, "Failed to get back pong\n");
>> + }
>> +
>> + /* Clear ping bit master kernel */
>> + ret = qcom_smem_state_update_bits(q6v5->ping_state, BIT(q6v5->ping_bit), 0);
>> + if (ret) {
>> + dev_err(q6v5->dev, "Failed to clear master kernel bits\n");
>> + return ret;
>> + }
>> +
>> + return ping_failed;
>> +}
>> +EXPORT_SYMBOL_GPL(qcom_q6v5_ping_subsystem);
>> +
>> +int qcom_q6v5_ping_subsystem_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev)
>> +{
>> + int ret = -ENODEV;
>> +
>> + q6v5->ping_state = devm_qcom_smem_state_get(&pdev->dev, "ping", &q6v5->ping_bit);
>> + if (IS_ERR(q6v5->ping_state)) {
>> + dev_err(&pdev->dev, "Failed to acquire smem state %ld\n",
>> + PTR_ERR(q6v5->ping_state));
>> + return PTR_ERR(q6v5->ping_state);
>> + }
>> +
>> + init_completion(&q6v5->ping_done);
>> +
>> + q6v5->pong_irq = platform_get_irq_byname(pdev, "pong");
>> + if (q6v5->pong_irq < 0)
>> + return q6v5->pong_irq;
>> +
>> + ret = devm_request_threaded_irq(&pdev->dev, q6v5->pong_irq, NULL,
>> + q6v5_pong_interrupt, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
>> + "q6v5 pong", q6v5);
>> + if (ret)
>> + dev_err(&pdev->dev, "Failed to acquire pong IRQ\n");
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(qcom_q6v5_ping_subsystem_init);
>> +
>> /**
>> * qcom_q6v5_init() - initializer of the q6v5 common struct
>> * @q6v5: handle to be initialized
>> diff --git a/drivers/remoteproc/qcom_q6v5.h b/drivers/remoteproc/qcom_q6v5.h
>> index 5a859c41896e..5025ffc4dbe8 100644
>> --- a/drivers/remoteproc/qcom_q6v5.h
>> +++ b/drivers/remoteproc/qcom_q6v5.h
>> @@ -17,22 +17,26 @@ struct qcom_q6v5 {
>> struct rproc *rproc;
>>
>> struct qcom_smem_state *state;
>> + struct qcom_smem_state *ping_state;
>> struct qmp *qmp;
>>
>> struct icc_path *path;
>>
>> unsigned stop_bit;
>> + unsigned int ping_bit;
>>
>> int wdog_irq;
>> int fatal_irq;
>> int ready_irq;
>> int handover_irq;
>> int stop_irq;
>> + int pong_irq;
>>
>> bool handover_issued;
>>
>> struct completion start_done;
>> struct completion stop_done;
>> + struct completion ping_done;
>>
>> int crash_reason;
>>
>> @@ -52,5 +56,7 @@ int qcom_q6v5_unprepare(struct qcom_q6v5 *q6v5);
>> int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5, struct qcom_sysmon *sysmon);
>> int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout);
>> unsigned long qcom_q6v5_panic(struct qcom_q6v5 *q6v5);
>> +int qcom_q6v5_ping_subsystem(struct qcom_q6v5 *q6v5);
>> +int qcom_q6v5_ping_subsystem_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev);
>>
>> #endif
>> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
>> index da27d1d3c9da..34b54cf832d0 100644
>> --- a/drivers/remoteproc/qcom_q6v5_pas.c
>> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
>> @@ -60,6 +60,7 @@ struct qcom_pas_data {
>> int region_assign_count;
>> bool region_assign_shared;
>> int region_assign_vmid;
>> + bool early_boot;
>> };
>>
>> struct qcom_pas {
>> @@ -423,9 +424,15 @@ static int qcom_pas_stop(struct rproc *rproc)
>>
>> qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size);
>>
>> - handover = qcom_q6v5_unprepare(&pas->q6v5);
>> - if (handover)
>> - qcom_pas_handover(&pas->q6v5);
>> + /*
>> + * qcom_q6v5_prepare is not called in qcom_pas_attach, skip unprepare to
>> + * avoid mismatch.
>> + */
>> + if (pas->rproc->state != RPROC_ATTACHED) {
>> + handover = qcom_q6v5_unprepare(&pas->q6v5);
>> + if (handover)
>> + qcom_pas_handover(&pas->q6v5);
>> + }
>>
>> if (pas->smem_host_id)
>> ret = qcom_smem_bust_hwspin_lock_by_host(pas->smem_host_id);
>> @@ -510,6 +517,63 @@ static unsigned long qcom_pas_panic(struct rproc *rproc)
>> return qcom_q6v5_panic(&pas->q6v5);
>> }
>>
>> +static int qcom_pas_attach(struct rproc *rproc)
>> +{
>> + int ret;
>> + struct qcom_pas *pas = rproc->priv;
>> + bool ready_state;
>> + bool crash_state;
>> +
>> + pas->q6v5.running = true;
>> + ret = irq_get_irqchip_state(pas->q6v5.fatal_irq,
>> + IRQCHIP_STATE_LINE_LEVEL, &crash_state);
>> +
>> + if (ret)
>> + goto disable_running;
>> +
>> + if (crash_state) {
>> + dev_err(pas->dev, "Subsystem has crashed before driver probe\n");
>> + rproc_report_crash(rproc, RPROC_FATAL_ERROR);
>> + ret = -EINVAL;
>> + goto disable_running;
>> + }
>> +
>> + ret = irq_get_irqchip_state(pas->q6v5.ready_irq,
>> + IRQCHIP_STATE_LINE_LEVEL, &ready_state);
>> +
>> + if (ret)
>> + goto disable_running;
>> +
>> + if (unlikely(!ready_state)) {
>> + /*
>> + * The bootloader may not support early boot, mark the state as
>> + * RPROC_OFFLINE so that the PAS driver can load the firmware and
>> + * start the remoteproc.
>> + */
>> + dev_err(pas->dev, "Failed to get subsystem ready interrupt\n");
>> + pas->rproc->state = RPROC_OFFLINE;
>> + ret = -EINVAL;
>> + goto disable_running;
>> + }
>> +
>> + ret = qcom_q6v5_ping_subsystem(&pas->q6v5);
>> +
>> + if (ret) {
>> + dev_err(pas->dev, "Failed to ping subsystem, assuming device crashed\n");
>> + rproc_report_crash(rproc, RPROC_FATAL_ERROR);
>> + goto disable_running;
>> + }
>> +
>> + pas->q6v5.handover_issued = true;
>> +
>> + return 0;
>> +
>> +disable_running:
>> + pas->q6v5.running = false;
>> +
>> + return ret;
>> +}
>> +
>> static const struct rproc_ops qcom_pas_ops = {
>> .unprepare = qcom_pas_unprepare,
>> .start = qcom_pas_start,
>> @@ -518,6 +582,7 @@ static const struct rproc_ops qcom_pas_ops = {
>> .parse_fw = qcom_pas_parse_firmware,
>> .load = qcom_pas_load,
>> .panic = qcom_pas_panic,
>> + .attach = qcom_pas_attach,
>> };
>>
>> static const struct rproc_ops qcom_pas_minidump_ops = {
>> @@ -855,6 +920,15 @@ static int qcom_pas_probe(struct platform_device *pdev)
>>
>> pas->pas_ctx->use_tzmem = rproc->has_iommu;
>> pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu;
>> +
>> + if (desc->early_boot) {
>> + ret = qcom_q6v5_ping_subsystem_init(&pas->q6v5, pdev);
>> + if (ret)
>> + dev_warn(&pdev->dev, "Falling back to firmware load\n");
>> + else
>> + pas->rproc->state = RPROC_DETACHED;
>> + }
>> +
>> ret = rproc_add(rproc);
>> if (ret)
>> goto remove_ssr_sysmon;
>>
>> --
>> 2.34.1
>>
^ permalink raw reply
* [PATCH 00/11] media: iris: Add support for glymur platform
From: Vishnu Reddy @ 2026-04-14 4:59 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy, Mukesh Ojha, stable
Glymur is a new generation video codec that supports dual hardware cores
along with additional power domains and clocks.
This series adds platform specific support in the iris driver to handle
the extra cores, power domains, and clock requirements introduced by
glymur. add support for firmware loading through context bank firmware
device.
Patch[11] is dependent on the below patch.
https://lore.kernel.org/all/20260410-glymur_mmcc_dt_config_v2-v3-1-acce9d106e72@oss.qualcomm.com/
v4l2-compliance report for decoder including streaming tests:
v4l2-compliance 1.33.0-5441, 64 bits, 64-bit time_t
v4l2-compliance SHA: 4310f15610f4 2026-01-18 22:09:17
Compliance test for iris_driver device /dev/video0:
Driver Info:
Driver name : iris_driver
Card type : Iris Decoder
Bus info : platform:aa00000.video-codec
Driver version : 7.0.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateful Decoder
Required ioctls:
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 12 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK
test Composing: OK
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
test blocking wait: OK
Test input 0:
Streaming ioctls:
test read/write: OK (Not Supported)
the input file is smaller than 7077888 bytes
Video Capture Multiplanar: Captured 465 buffers
test MMAP (select, REQBUFS): OK
the input file is smaller than 7077888 bytes
Video Capture Multiplanar: Captured 465 buffers
test MMAP (epoll, REQBUFS): OK
the input file is smaller than 7077888 bytes
Video Capture Multiplanar: Captured 465 buffers
test MMAP (select, CREATE_BUFS): OK
the input file is smaller than 7077888 bytes
Video Capture Multiplanar: Captured 465 buffers
test MMAP (epoll, CREATE_BUFS): OK
test USERPTR (select): OK (Not Supported)
test DMABUF: Cannot test, specify --expbuf-device
Total for iris_driver device /dev/video0: 54, Succeeded: 54, Failed: 0, Warnings: 0
v4l2-compliance report for encoder including streaming tests:
v4l2-compliance 1.33.0-5441, 64 bits, 64-bit time_t
v4l2-compliance SHA: 4310f15610f4 2026-01-18 22:09:17
Compliance test for iris_driver device /dev/video1:
Driver Info:
Driver name : iris_driver
Card type : Iris Encoder
Bus info : platform:aa00000.video-codec
Driver version : 7.0.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateful Encoder
Required ioctls:
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video1 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 43 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
test blocking wait: OK
Test input 0:
Streaming ioctls:
test read/write: OK (Not Supported)
Video Capture Multiplanar: Captured 61 buffers
test MMAP (select, REQBUFS): OK
Video Capture Multiplanar: Captured 61 buffers
test MMAP (epoll, REQBUFS): OK
Video Capture Multiplanar: Captured 61 buffers
test MMAP (select, CREATE_BUFS): OK
Video Capture Multiplanar: Captured 61 buffers
test MMAP (epoll, CREATE_BUFS): OK
test USERPTR (select): OK (Not Supported)
test DMABUF: Cannot test, specify --expbuf-device
Total for iris_driver device /dev/video1: 54, Succeeded: 54, Failed: 0, Warnings: 0
Fluster test report:
77/135 while testing JVT-AVC_V1 with
GStreamer-H.264-V4L2-Gst1.0.JVT-AVC_V1
The failing tests are:
- 52 test vectors failed due to interlaced clips: Interlaced decoding
is not supported.
- cabac_mot_fld0_full
- cabac_mot_mbaff0_full
- cabac_mot_picaff0_full
- CABREF3_Sand_D
- CAFI1_SVA_C
- CAMA1_Sony_C
- CAMA1_TOSHIBA_B
- cama1_vtc_c
- cama2_vtc_b
- CAMA3_Sand_E
- cama3_vtc_b
- CAMACI3_Sony_C
- CAMANL1_TOSHIBA_B
- CAMANL2_TOSHIBA_B
- CAMANL3_Sand_E
- CAMASL3_Sony_B
- CAMP_MOT_MBAFF_L30
- CAMP_MOT_MBAFF_L31
- CANLMA2_Sony_C
- CANLMA3_Sony_C
- CAPA1_TOSHIBA_B
- CAPAMA3_Sand_F
- cavlc_mot_fld0_full_B
- cavlc_mot_mbaff0_full_B
- cavlc_mot_picaff0_full_B
- CVCANLMA2_Sony_C
- CVFI1_Sony_D
- CVFI1_SVA_C
- CVFI2_Sony_H
- CVFI2_SVA_C
- CVMA1_Sony_D
- CVMA1_TOSHIBA_B
- CVMANL1_TOSHIBA_B
- CVMANL2_TOSHIBA_B
- CVMAPAQP3_Sony_E
- CVMAQP2_Sony_G
- CVMAQP3_Sony_D
- CVMP_MOT_FLD_L30_B
- CVNLFI1_Sony_C
- CVNLFI2_Sony_H
- CVPA1_TOSHIBA_B
- FI1_Sony_E
- MR6_BT_B
- MR7_BT_B
- MR8_BT_B
- MR9_BT_B
- Sharp_MP_Field_1_B
- Sharp_MP_Field_2_B
- Sharp_MP_Field_3_B
- Sharp_MP_PAFF_1r2
- Sharp_MP_PAFF_2r
- CVMP_MOT_FRM_L31_B
3 test case failed due to unsupported bitstream.
num_slice_groups_minus1 greater than zero is not supported.
- FM1_BT_B
- FM1_FT_E
- FM2_SVA_C
2 test case failed because SP_SLICE type is not supported.
- SP1_BT_A
- sp2_bt_b
1 test case failed due to unsupported profile.
- BA3_SVA_C
131/147 testcases passed while testing JCT-VC-HEVC_V1 with
GStreamer-H.265-V4L2-Gst1.0
10 testcases failed due to unsupported 10 bit format.
- DBLK_A_MAIN10_VIXS_4
- INITQP_B_Main10_Sony_1
- TSUNEQBD_A_MAIN10_Technicolor_2
- WP_A_MAIN10_Toshiba_3
- WP_MAIN10_B_Toshiba_3
- WPP_A_ericsson_MAIN10_2
- WPP_B_ericsson_MAIN10_2
- WPP_C_ericsson_MAIN10_2
- WPP_E_ericsson_MAIN10_2
- WPP_F_ericsson_MAIN10_2
4 testcase failed due to unsupported resolution.
- PICSIZE_A_Bossen_1
- PICSIZE_B_Bossen_1
- WPP_D_ericsson_MAIN10_2
- WPP_D_ericsson_MAIN_2
2 testcase failed due to CRC mismatch.
- VPSSPSPPS_A_MainConcept_1
This fails with software decoder as well. Refer the below link for the
discussion happened for earlier platform.
https://lore.kernel.org/all/63ca375440c4ff2f55ea0aa4e19458f775552d88.camel@ndufresne.ca/
- RAP_A_docomo_6
This was discussed on bug report
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4392
Based on above discussion, the initial error frames need to be dropped in
the firmware or driver. Discussion ongoing with video firmware team on a
way to handle such case. This issue is not specific to this platform, and
its there on other platforms also.
235/305 testcases passed while testing VP9-TEST-VECTORS with GStreamer-VP9-V4L2-Gst1.0
64 testcases failed due to unsupported resolution
- vp90-2-02-size-08x08.webm
- vp90-2-02-size-08x10.webm
- vp90-2-02-size-08x16.webm
- vp90-2-02-size-08x18.webm
- vp90-2-02-size-08x32.webm
- vp90-2-02-size-08x34.webm
- vp90-2-02-size-08x64.webm
- vp90-2-02-size-08x66.webm
- vp90-2-02-size-10x08.webm
- vp90-2-02-size-10x10.webm
- vp90-2-02-size-10x16.webm
- vp90-2-02-size-10x18.webm
- vp90-2-02-size-10x32.webm
- vp90-2-02-size-10x34.webm
- vp90-2-02-size-10x64.webm
- vp90-2-02-size-10x66.webm
- vp90-2-02-size-16x08.webm
- vp90-2-02-size-16x10.webm
- vp90-2-02-size-16x16.webm
- vp90-2-02-size-16x18.webm
- vp90-2-02-size-16x32.webm
- vp90-2-02-size-16x34.webm
- vp90-2-02-size-16x64.webm
- vp90-2-02-size-16x66.webm
- vp90-2-02-size-18x08.webm
- vp90-2-02-size-18x10.webm
- vp90-2-02-size-18x16.webm
- vp90-2-02-size-18x18.webm
- vp90-2-02-size-18x32.webm
- vp90-2-02-size-18x34.webm
- vp90-2-02-size-18x64.webm
- vp90-2-02-size-18x66.webm
- vp90-2-02-size-32x08.webm
- vp90-2-02-size-32x10.webm
- vp90-2-02-size-32x16.webm
- vp90-2-02-size-32x18.webm
- vp90-2-02-size-32x32.webm
- vp90-2-02-size-32x34.webm
- vp90-2-02-size-32x64.webm
- vp90-2-02-size-32x66.webm
- vp90-2-02-size-34x08.webm
- vp90-2-02-size-34x10.webm
- vp90-2-02-size-34x16.webm
- vp90-2-02-size-34x18.webm
- vp90-2-02-size-34x32.webm
- vp90-2-02-size-34x34.webm
- vp90-2-02-size-34x64.webm
- vp90-2-02-size-34x66.webm
- vp90-2-02-size-64x08.webm
- vp90-2-02-size-64x10.webm
- vp90-2-02-size-64x16.webm
- vp90-2-02-size-64x18.webm
- vp90-2-02-size-64x32.webm
- vp90-2-02-size-64x34.webm
- vp90-2-02-size-64x64.webm
- vp90-2-02-size-64x66.webm
- vp90-2-02-size-66x08.webm
- vp90-2-02-size-66x10.webm
- vp90-2-02-size-66x16.webm
- vp90-2-02-size-66x18.webm
- vp90-2-02-size-66x32.webm
- vp90-2-02-size-66x34.webm
- vp90-2-02-size-66x64.webm
- vp90-2-02-size-66x66.webm
2 testcases failed due to unsupported format.
- vp91-2-04-yuv422.webm
- vp91-2-04-yuv444.webm
2 testcase failed due to unsupported resolution after DRC.
- vp90-2-21-resize_inter_320x180_5_1-2.webm
- vp90-2-21-resize_inter_320x180_7_1-2.webm
1 testcase failed with CRC mismatch.
- vp90-2-22-svc_1280x720_3.ivf
This VP9 bitstream contains 20 superframes, and each superframe consists
of three subframes in the following order:
• 180p subframe
• 360p subframe
• 720p subframe
Each superframe is submitted to the driver and firmware as a single input
buffer, with one common timestamp attached to it. For every such input
buffer, the hardware decoder produces three corresponding output buffers,
one for each resolution (180p, 360p, and 720p), and all three output
buffers carry the same timestamp. When these output buffers are returned
to the client (GStreamer, in this case), the first buffer returned is
displayed, while the remaining two buffers are dropped due to having
identical timestamps. As a result, only one frame per superframe is
rendered. Here the expectation of the test result is with 720p, last
decoded frame in each super frame.
Discussion ongoing with firmware team and gst maintainer on how to handle
this case. This is not specific to glymur, and its there for the other
platforms also.
1 testcase failed due to unsupported stream.
- vp90-2-16-intra-only.webm
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
Mukesh Ojha (1):
media: iris: Enable Secure PAS support with IOMMU managed by Linux
Vikash Garodia (2):
media: iris: Add iris vpu bus support and register it with iommu_buses
media: iris: Add helper to create a context bank device on iris vpu bus
Vishnu Reddy (8):
dt-bindings: media: qcom,glymur-iris: Add glymur video codec
media: iris: Add context bank hooks for platform specific initialization
media: iris: Fix VM count passed to firmware
media: iris: Rename clock and power domain macros to use vcodec prefix
media: iris: Add power sequence for Glymur
media: iris: Add support to select core for dual core platforms
media: iris: Add platform data for glymur
arm64: dts: qcom: glymur: Add iris video node
.../bindings/media/qcom,glymur-iris.yaml | 220 +++++++++++++++++++++
arch/arm64/boot/dts/qcom/glymur-crd.dts | 4 +
arch/arm64/boot/dts/qcom/glymur.dtsi | 118 +++++++++++
drivers/iommu/iommu.c | 4 +
drivers/media/platform/qcom/iris/Makefile | 5 +
drivers/media/platform/qcom/iris/iris_common.c | 7 +
drivers/media/platform/qcom/iris/iris_core.h | 4 +
drivers/media/platform/qcom/iris/iris_firmware.c | 71 ++++++-
drivers/media/platform/qcom/iris/iris_hfi_common.h | 1 +
.../platform/qcom/iris/iris_hfi_gen2_command.c | 19 ++
.../platform/qcom/iris/iris_hfi_gen2_defines.h | 1 +
drivers/media/platform/qcom/iris/iris_instance.h | 2 +
.../platform/qcom/iris/iris_platform_common.h | 25 ++-
.../media/platform/qcom/iris/iris_platform_gen1.c | 6 +-
.../media/platform/qcom/iris/iris_platform_gen2.c | 106 +++++++++-
.../platform/qcom/iris/iris_platform_glymur.c | 93 +++++++++
.../platform/qcom/iris/iris_platform_glymur.h | 17 ++
.../platform/qcom/iris/iris_platform_sc7280.h | 10 +-
.../platform/qcom/iris/iris_platform_sm8750.h | 12 +-
drivers/media/platform/qcom/iris/iris_probe.c | 27 ++-
drivers/media/platform/qcom/iris/iris_resources.c | 33 ++++
drivers/media/platform/qcom/iris/iris_resources.h | 1 +
drivers/media/platform/qcom/iris/iris_utils.c | 68 +++++--
drivers/media/platform/qcom/iris/iris_vpu3x.c | 148 ++++++++++++--
drivers/media/platform/qcom/iris/iris_vpu4x.c | 30 +--
drivers/media/platform/qcom/iris/iris_vpu_bus.c | 32 +++
drivers/media/platform/qcom/iris/iris_vpu_common.c | 36 ++--
drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
.../platform/qcom/iris/iris_vpu_register_defines.h | 7 +
include/dt-bindings/media/qcom,glymur-iris.h | 11 ++
include/linux/iris_vpu_bus.h | 13 ++
31 files changed, 1039 insertions(+), 93 deletions(-)
---
base-commit: 1c7cc4904160c6fc6377564140062d68a3dc93a0
change-id: 20260409-glymur-140ab7ca0910
Best regards,
--
Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
^ permalink raw reply
* [PATCH 01/11] dt-bindings: media: qcom,glymur-iris: Add glymur video codec
From: Vishnu Reddy @ 2026-04-14 4:59 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Add device tree binding for the Qualcomm Glymur Iris video codec. Glymur
is a new generation of video IP that introduces a dual-core architecture.
The second core brings its own power domain, clocks, and reset lines,
requiring additional power domains and clocks in the power sequence.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
.../bindings/media/qcom,glymur-iris.yaml | 220 +++++++++++++++++++++
include/dt-bindings/media/qcom,glymur-iris.h | 11 ++
2 files changed, 231 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml b/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml
new file mode 100644
index 000000000000..10ee02cd1a7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml
@@ -0,0 +1,220 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,glymur-iris.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Glymur SoC Iris video encoder and decoder
+
+maintainers:
+ - Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
+
+description:
+ The Iris video processing unit on Qualcomm Glymur SoC is a video encode and
+ decode accelerator.
+
+properties:
+ compatible:
+ const: qcom,glymur-iris
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 9
+
+ clock-names:
+ items:
+ - const: iface
+ - const: core
+ - const: vcodec0_core
+ - const: iface_ctrl
+ - const: core_freerun
+ - const: vcodec0_core_freerun
+ - const: iface1
+ - const: vcodec1_core
+ - const: vcodec1_core_freerun
+
+ dma-coherent: true
+
+ firmware-name:
+ maxItems: 1
+
+ interconnects:
+ maxItems: 2
+
+ interconnect-names:
+ items:
+ - const: cpu-cfg
+ - const: video-mem
+
+ interrupts:
+ maxItems: 1
+
+ iommus:
+ maxItems: 4
+
+ iommu-map:
+ maxItems: 1
+
+ memory-region:
+ maxItems: 1
+
+ operating-points-v2: true
+ opp-table:
+ type: object
+
+ power-domains:
+ maxItems: 5
+
+ power-domain-names:
+ items:
+ - const: venus
+ - const: vcodec0
+ - const: mxc
+ - const: mmcx
+ - const: vcodec1
+
+ resets:
+ maxItems: 6
+
+ reset-names:
+ items:
+ - const: bus0
+ - const: bus_ctrl
+ - const: core
+ - const: vcodec0_core
+ - const: bus1
+ - const: vcodec1_core
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - dma-coherent
+ - interconnects
+ - interconnect-names
+ - interrupts
+ - iommus
+ - memory-region
+ - power-domains
+ - power-domain-names
+ - resets
+ - reset-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/media/qcom,glymur-iris.h>
+ #include <dt-bindings/power/qcom,rpmhpd.h>
+
+ video-codec@aa00000 {
+ compatible = "qcom,glymur-iris";
+ reg = <0x0aa00000 0xf0000>;
+
+ clocks = <&gcc_video_axi0_clk>,
+ <&videocc_mvs0c_clk>,
+ <&videocc_mvs0_clk>,
+ <&gcc_video_axi0c_clk>,
+ <&videocc_mvs0c_freerun_clk>,
+ <&videocc_mvs0_freerun_clk>,
+ <&gcc_video_axi1_clk>,
+ <&videocc_mvs1_clk>,
+ <&videocc_mvs1_freerun_clk>;
+ clock-names = "iface",
+ "core",
+ "vcodec0_core",
+ "iface_ctrl",
+ "core_freerun",
+ "vcodec0_core_freerun",
+ "iface1",
+ "vcodec1_core",
+ "vcodec1_core_freerun";
+
+ dma-coherent;
+
+ interconnects = <&hsc_noc_master_appss_proc &config_noc_slave_venus_cfg>,
+ <&mmss_noc_master_video &mc_virt_slave_ebi1>;
+ interconnect-names = "cpu-cfg",
+ "video-mem";
+
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0x1940 0x0>,
+ <&apps_smmu 0x1943 0x0>,
+ <&apps_smmu 0x1944 0x0>,
+ <&apps_smmu 0x19e0 0x0>;
+
+ iommu-map = <IRIS_FIRMWARE &apps_smmu 0x19e2 0x1>;
+
+ memory-region = <&video_mem>;
+
+ operating-points-v2 = <&iris_opp_table>;
+
+ power-domains = <&videocc_mvs0c_gdsc>,
+ <&videocc_mvs0_gdsc>,
+ <&rpmhpd RPMHPD_MXC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&videocc_mvs1_gdsc>;
+ power-domain-names = "venus",
+ "vcodec0",
+ "mxc",
+ "mmcx",
+ "vcodec1";
+
+ resets = <&gcc_video_axi0_clk_ares>,
+ <&gcc_video_axi0c_clk_ares>,
+ <&videocc_mvs0c_freerun_clk_ares>,
+ <&videocc_mvs0_freerun_clk_ares>,
+ <&gcc_video_axi1_clk_ares>,
+ <&videocc_mvs1_freerun_clk_ares>;
+ reset-names = "bus0",
+ "bus_ctrl",
+ "core",
+ "vcodec0_core",
+ "bus1",
+ "vcodec1_core";
+
+ iris_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-240000000 {
+ opp-hz = /bits/ 64 <240000000 240000000 360000000>;
+ required-opps = <&rpmhpd_opp_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-338000000 {
+ opp-hz = /bits/ 64 <338000000 338000000 507000000>;
+ required-opps = <&rpmhpd_opp_svs>,
+ <&rpmhpd_opp_svs>;
+ };
+
+ opp-366000000 {
+ opp-hz = /bits/ 64 <366000000 366000000 549000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-444000000 {
+ opp-hz = /bits/ 64 <444000000 444000000 666000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_nom>;
+ };
+
+ opp-533333334 {
+ opp-hz = /bits/ 64 <533333334 533333334 800000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_turbo>;
+ };
+
+ opp-655000000 {
+ opp-hz = /bits/ 64 <655000000 655000000 982000000>;
+ required-opps = <&rpmhpd_opp_nom>,
+ <&rpmhpd_opp_turbo_l1>;
+ };
+ };
+ };
diff --git a/include/dt-bindings/media/qcom,glymur-iris.h b/include/dt-bindings/media/qcom,glymur-iris.h
new file mode 100644
index 000000000000..5766db0b9247
--- /dev/null
+++ b/include/dt-bindings/media/qcom,glymur-iris.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_MEDIA_QCOM_GLYMUR_IRIS_H_
+#define _DT_BINDINGS_MEDIA_QCOM_GLYMUR_IRIS_H_
+
+#define IRIS_FIRMWARE 0
+
+#endif
--
2.34.1
^ permalink raw reply related
* [PATCH 02/11] media: iris: Add iris vpu bus support and register it with iommu_buses
From: Vishnu Reddy @ 2026-04-14 4:59 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
From: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Add a dedicated iris VPU bus type and register it into the iommu_buses
list. Iris devices require their own bus so that each device can run its
own dma_configure() logic.
Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/iommu/iommu.c | 4 ++++
drivers/media/platform/qcom/iris/Makefile | 4 ++++
drivers/media/platform/qcom/iris/iris_vpu_bus.c | 32 +++++++++++++++++++++++++
include/linux/iris_vpu_bus.h | 13 ++++++++++
4 files changed, 53 insertions(+)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 61c12ba78206..d8ed6ef70ecd 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -13,6 +13,7 @@
#include <linux/bug.h>
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/iris_vpu_bus.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -179,6 +180,9 @@ static const struct bus_type * const iommu_buses[] = {
#ifdef CONFIG_CDX_BUS
&cdx_bus_type,
#endif
+#if IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)
+ &iris_vpu_bus_type,
+#endif
};
/*
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
index 2abbd3aeb4af..6f4052b98491 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -31,3 +31,7 @@ qcom-iris-objs += iris_platform_gen1.o
endif
obj-$(CONFIG_VIDEO_QCOM_IRIS) += qcom-iris.o
+
+ifdef CONFIG_VIDEO_QCOM_IRIS
+obj-y += iris_vpu_bus.o
+endif
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_bus.c b/drivers/media/platform/qcom/iris/iris_vpu_bus.c
new file mode 100644
index 000000000000..b51bb4b82b0e
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu_bus.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/of_device.h>
+
+#include "iris_platform_common.h"
+
+static int iris_vpu_bus_dma_configure(struct device *dev)
+{
+ const u32 *f_id = dev_get_drvdata(dev);
+
+ if (!f_id)
+ return -ENODEV;
+
+ return of_dma_configure_id(dev, dev->parent->of_node, true, f_id);
+}
+
+const struct bus_type iris_vpu_bus_type = {
+ .name = "iris-vpu-bus",
+ .dma_configure = iris_vpu_bus_dma_configure,
+};
+EXPORT_SYMBOL_GPL(iris_vpu_bus_type);
+
+static int __init iris_vpu_bus_init(void)
+{
+ return bus_register(&iris_vpu_bus_type);
+}
+
+postcore_initcall(iris_vpu_bus_init);
diff --git a/include/linux/iris_vpu_bus.h b/include/linux/iris_vpu_bus.h
new file mode 100644
index 000000000000..5704b226f7d6
--- /dev/null
+++ b/include/linux/iris_vpu_bus.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __IRIS_VPU_BUS_H__
+#define __IRIS_VPU_BUS_H__
+
+#if IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)
+extern const struct bus_type iris_vpu_bus_type;
+#endif
+
+#endif /* __IRIS_VPU_BUS_H__ */
--
2.34.1
^ permalink raw reply related
* [PATCH 03/11] media: iris: Add context bank hooks for platform specific initialization
From: Vishnu Reddy @ 2026-04-14 4:59 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Add init and deinit hooks in the platform data for context bank setup.
These hooks allow platform specific code to initialize and tear down
context banks.
The Glymur platform requires a dedicated firmware context bank device
which is mapped to the firmware stream ID to load the firmware.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
.../platform/qcom/iris/iris_platform_common.h | 2 ++
drivers/media/platform/qcom/iris/iris_probe.c | 23 +++++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 5a489917580e..55ff6137d9a9 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -219,6 +219,8 @@ struct iris_platform_data {
u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type);
const struct vpu_ops *vpu_ops;
void (*set_preset_registers)(struct iris_core *core);
+ int (*init_cb_devs)(struct iris_core *core);
+ void (*deinit_cb_devs)(struct iris_core *core);
const struct icc_info *icc_tbl;
unsigned int icc_tbl_size;
const struct bw_info *bw_tbl_dec;
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index ddaacda523ec..34751912f871 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -142,6 +142,20 @@ static int iris_init_resources(struct iris_core *core)
return iris_init_resets(core);
}
+static int iris_init_cb_devs(struct iris_core *core)
+{
+ if (core->iris_platform_data->init_cb_devs)
+ return core->iris_platform_data->init_cb_devs(core);
+
+ return 0;
+}
+
+static void iris_deinit_cb_devs(struct iris_core *core)
+{
+ if (core->iris_platform_data->deinit_cb_devs)
+ core->iris_platform_data->deinit_cb_devs(core);
+}
+
static int iris_register_video_device(struct iris_core *core, enum domain_type type)
{
struct video_device *vdev;
@@ -193,6 +207,7 @@ static void iris_remove(struct platform_device *pdev)
return;
iris_core_deinit(core);
+ iris_deinit_cb_devs(core);
video_unregister_device(core->vdev_dec);
video_unregister_device(core->vdev_enc);
@@ -259,11 +274,15 @@ static int iris_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = iris_init_cb_devs(core);
+ if (ret)
+ return ret;
+
iris_session_init_caps(core);
ret = v4l2_device_register(dev, &core->v4l2_dev);
if (ret)
- return ret;
+ goto err_deinit_cb;
ret = iris_register_video_device(core, DECODER);
if (ret)
@@ -298,6 +317,8 @@ static int iris_probe(struct platform_device *pdev)
video_unregister_device(core->vdev_dec);
err_v4l2_unreg:
v4l2_device_unregister(&core->v4l2_dev);
+err_deinit_cb:
+ iris_deinit_cb_devs(core);
return ret;
}
--
2.34.1
^ permalink raw reply related
* [PATCH 04/11] media: iris: Add helper to create a context bank device on iris vpu bus
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
From: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Add a helper function to allocate and register context bank (CB) device
on the iris vpu bus. The function ID associated with the CB is specified
from the platform data, allowing the bus dma_configure callback to apply
correct stream ID mapping when device is registered.
Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_resources.c | 33 +++++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_resources.h | 1 +
2 files changed, 34 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c
index 773f6548370a..a25e0f2e9d26 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.c
+++ b/drivers/media/platform/qcom/iris/iris_resources.c
@@ -6,6 +6,7 @@
#include <linux/clk.h>
#include <linux/devfreq.h>
#include <linux/interconnect.h>
+#include <linux/iris_vpu_bus.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
@@ -141,3 +142,35 @@ int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type
return 0;
}
+
+static void iris_release_cb_dev(struct device *dev)
+{
+ kfree(dev);
+}
+
+struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id)
+{
+ struct device *dev;
+ int ret;
+
+ dev = kzalloc_obj(*dev);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->release = iris_release_cb_dev;
+ dev->bus = &iris_vpu_bus_type;
+ dev->parent = core->dev;
+ dev->coherent_dma_mask = core->iris_platform_data->dma_mask;
+ dev->dma_mask = &dev->coherent_dma_mask;
+
+ dev_set_name(dev, "%s", name);
+ dev_set_drvdata(dev, (void *)f_id);
+
+ ret = device_register(dev);
+ if (ret) {
+ put_device(dev);
+ return ERR_PTR(ret);
+ }
+
+ return dev;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
index 6bfbd2dc6db0..4a494627ff23 100644
--- a/drivers/media/platform/qcom/iris/iris_resources.h
+++ b/drivers/media/platform/qcom/iris/iris_resources.h
@@ -15,5 +15,6 @@ int iris_unset_icc_bw(struct iris_core *core);
int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw);
int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type);
int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type);
+struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id);
#endif
--
2.34.1
^ permalink raw reply related
* [PATCH 05/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy, Mukesh Ojha
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
or QHEE), which typically handles IOMMU configuration. This includes
mapping memory regions and device memory resources for remote processors
by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are
later removed during teardown. Additionally, SHM bridge setup is required
to enable memory protection for both remoteproc metadata and its memory
regions.
When the hypervisor is absent, the operating system must perform these
configurations instead.
Support for handling IOMMU and SHM setup in the absence of a hypervisor
is now in place. Extend the Iris driver to enable this functionality on
platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
Additionally, the Iris driver must map the firmware and its required
resources to the firmware SID, which is now specified via iommu-map in
the device tree.
Co-developed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_core.h | 4 ++
drivers/media/platform/qcom/iris/iris_firmware.c | 71 +++++++++++++++++++++---
2 files changed, 66 insertions(+), 9 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
index fb194c967ad4..aa7abef6f0e0 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -34,6 +34,8 @@ enum domain_type {
* struct iris_core - holds core parameters valid for all instances
*
* @dev: reference to device structure
+ * @dev_fw: reference to the context bank device used for firmware load
+ * @ctx_fw: SCM PAS context for authenticated firmware load and shutdown
* @reg_base: IO memory base address
* @irq: iris irq
* @v4l2_dev: a holder for v4l2 device structure
@@ -77,6 +79,8 @@ enum domain_type {
struct iris_core {
struct device *dev;
+ struct device *dev_fw;
+ struct qcom_scm_pas_context *ctx_fw;
void __iomem *reg_base;
int irq;
struct v4l2_device v4l2_dev;
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
index 5f408024e967..93d77996c83f 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.c
+++ b/drivers/media/platform/qcom/iris/iris_firmware.c
@@ -5,6 +5,7 @@
#include <linux/firmware.h>
#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/iommu.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
#include <linux/soc/qcom/mdt_loader.h>
@@ -13,12 +14,15 @@
#include "iris_firmware.h"
#define MAX_FIRMWARE_NAME_SIZE 128
+#define IRIS_FW_START_ADDR 0
static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
{
+ struct device *dev = core->dev_fw ? core->dev_fw : core->dev;
u32 pas_id = core->iris_platform_data->pas_id;
const struct firmware *firmware = NULL;
- struct device *dev = core->dev;
+ struct qcom_scm_pas_context *ctx_fw;
+ struct iommu_domain *domain;
struct resource res;
phys_addr_t mem_phys;
size_t res_size;
@@ -29,13 +33,17 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
return -EINVAL;
- ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
+ ret = of_reserved_mem_region_to_resource(core->dev->of_node, 0, &res);
if (ret)
return ret;
mem_phys = res.start;
res_size = resource_size(&res);
+ ctx_fw = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size);
+ if (IS_ERR(ctx_fw))
+ return PTR_ERR(ctx_fw);
+
ret = request_firmware(&firmware, fw_name, dev);
if (ret)
return ret;
@@ -52,9 +60,27 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
goto err_release_fw;
}
- ret = qcom_mdt_load(dev, firmware, fw_name,
- pas_id, mem_virt, mem_phys, res_size, NULL);
+ ctx_fw->use_tzmem = !!core->dev_fw;
+ ret = qcom_mdt_pas_load(ctx_fw, firmware, fw_name, mem_virt, NULL);
+ if (ret)
+ goto err_mem_unmap;
+
+ if (ctx_fw->use_tzmem) {
+ domain = iommu_get_domain_for_dev(core->dev_fw);
+ if (!domain) {
+ ret = -ENODEV;
+ goto err_mem_unmap;
+ }
+
+ ret = iommu_map(domain, IRIS_FW_START_ADDR, mem_phys, res_size,
+ IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
+ if (ret)
+ goto err_mem_unmap;
+ }
+ core->ctx_fw = ctx_fw;
+
+err_mem_unmap:
memunmap(mem_virt);
err_release_fw:
release_firmware(firmware);
@@ -62,6 +88,19 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
return ret;
}
+static void iris_fw_iommu_unmap(struct iris_core *core)
+{
+ bool use_tzmem = core->ctx_fw->use_tzmem;
+ struct iommu_domain *domain;
+
+ if (!use_tzmem)
+ return;
+
+ domain = iommu_get_domain_for_dev(core->dev_fw);
+ if (domain)
+ iommu_unmap(domain, IRIS_FW_START_ADDR, core->ctx_fw->mem_size);
+}
+
int iris_fw_load(struct iris_core *core)
{
const struct tz_cp_config *cp_config;
@@ -79,10 +118,10 @@ int iris_fw_load(struct iris_core *core)
return -ENOMEM;
}
- ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id);
+ ret = qcom_scm_pas_prepare_and_auth_reset(core->ctx_fw);
if (ret) {
dev_err(core->dev, "auth and reset failed: %d\n", ret);
- return ret;
+ goto err_unmap;
}
for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) {
@@ -93,17 +132,31 @@ int iris_fw_load(struct iris_core *core)
cp_config->cp_nonpixel_size);
if (ret) {
dev_err(core->dev, "qcom_scm_mem_protect_video_var failed: %d\n", ret);
- qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
- return ret;
+ goto err_pas_shutdown;
}
}
+ return 0;
+
+err_pas_shutdown:
+ qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
+err_unmap:
+ iris_fw_iommu_unmap(core);
+
return ret;
}
int iris_fw_unload(struct iris_core *core)
{
- return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
+ int ret;
+
+ ret = qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
+ if (ret)
+ return ret;
+
+ iris_fw_iommu_unmap(core);
+
+ return ret;
}
int iris_set_hw_state(struct iris_core *core, bool resume)
--
2.34.1
^ permalink raw reply related
* [PATCH 06/11] media: iris: Fix VM count passed to firmware
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy, stable
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
On Glymur, firmware interprets the value written to CPU_CS_SCIACMDARG3 as
the number of virtual machines (VMs) and internally adds 1 to it. Writing
1 causes firmware to treat it as 2 VMs. Since only one VM is required,
remove this write to leave the register at its reset value of 0. This does
not affect other platforms as only Glymur firmware uses this register,
earlier platform firmwares ignore it.
Fixes: abf5bac63f68a ("media: iris: implement the boot sequence of the firmware")
Cc: stable@vger.kernel.org
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_vpu_common.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index 548e5f1727fd..bfd1e762c38e 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -78,7 +78,6 @@ int iris_vpu_boot_firmware(struct iris_core *core)
iris_vpu_setup_ucregion_memory_map(core);
writel(ctrl_init, core->reg_base + CTRL_INIT);
- writel(0x1, core->reg_base + CPU_CS_SCIACMDARG3);
while (!ctrl_status && count < max_tries) {
ctrl_status = readl(core->reg_base + CTRL_STATUS);
--
2.34.1
^ permalink raw reply related
* [PATCH 07/11] media: iris: Rename clock and power domain macros to use vcodec prefix
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
The current clock and power domain enum names are too generic. Rename
them with a vcodec prefix to make the names more meaningful and to easily
accommodate vcodec1 enums for the secondary core in the following patches.
This patch only renames the macros and does not introduce any functional
changes.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
.../platform/qcom/iris/iris_platform_common.h | 12 ++++----
.../media/platform/qcom/iris/iris_platform_gen1.c | 6 ++--
.../media/platform/qcom/iris/iris_platform_gen2.c | 6 ++--
.../platform/qcom/iris/iris_platform_sc7280.h | 10 +++----
.../platform/qcom/iris/iris_platform_sm8750.h | 12 ++++----
drivers/media/platform/qcom/iris/iris_vpu3x.c | 25 ++++++++--------
drivers/media/platform/qcom/iris/iris_vpu4x.c | 30 ++++++++++---------
drivers/media/platform/qcom/iris/iris_vpu_common.c | 35 +++++++++++-----------
8 files changed, 70 insertions(+), 66 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 55ff6137d9a9..30e9d4d288c6 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -49,14 +49,14 @@ extern const struct iris_platform_data sm8650_data;
extern const struct iris_platform_data sm8750_data;
enum platform_clk_type {
- IRIS_AXI_CLK, /* AXI0 in case of platforms with multiple AXI clocks */
+ IRIS_AXI_VCODEC_CLK,
IRIS_CTRL_CLK,
IRIS_AHB_CLK,
- IRIS_HW_CLK,
- IRIS_HW_AHB_CLK,
- IRIS_AXI1_CLK,
+ IRIS_VCODEC_CLK,
+ IRIS_VCODEC_AHB_CLK,
+ IRIS_AXI_CTRL_CLK,
IRIS_CTRL_FREERUN_CLK,
- IRIS_HW_FREERUN_CLK,
+ IRIS_VCODEC_FREERUN_CLK,
IRIS_BSE_HW_CLK,
IRIS_VPP0_HW_CLK,
IRIS_VPP1_HW_CLK,
@@ -206,7 +206,7 @@ struct icc_vote_data {
enum platform_pm_domain_type {
IRIS_CTRL_POWER_DOMAIN,
- IRIS_HW_POWER_DOMAIN,
+ IRIS_VCODEC_POWER_DOMAIN,
IRIS_VPP0_HW_POWER_DOMAIN,
IRIS_VPP1_HW_POWER_DOMAIN,
IRIS_APV_HW_POWER_DOMAIN,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
index df8e6bf9430e..be6a631f8ede 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c
@@ -284,9 +284,9 @@ static const char * const sm8250_pmdomain_table[] = { "venus", "vcodec0" };
static const char * const sm8250_opp_pd_table[] = { "mx" };
static const struct platform_clk_data sm8250_clk_table[] = {
- {IRIS_AXI_CLK, "iface" },
- {IRIS_CTRL_CLK, "core" },
- {IRIS_HW_CLK, "vcodec0_core" },
+ {IRIS_AXI_VCODEC_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_VCODEC_CLK, "vcodec0_core" },
};
static const char * const sm8250_opp_clk_table[] = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index 5da90d47f9c6..47c6b650f0b4 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -780,9 +780,9 @@ static const char * const sm8550_pmdomain_table[] = { "venus", "vcodec0" };
static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx" };
static const struct platform_clk_data sm8550_clk_table[] = {
- {IRIS_AXI_CLK, "iface" },
- {IRIS_CTRL_CLK, "core" },
- {IRIS_HW_CLK, "vcodec0_core" },
+ {IRIS_AXI_VCODEC_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_VCODEC_CLK, "vcodec0_core" },
};
static const char * const sm8550_opp_clk_table[] = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sc7280.h b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h
index 0ec8f334df67..6b783e524b81 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sc7280.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h
@@ -16,11 +16,11 @@ static const struct bw_info sc7280_bw_table_dec[] = {
static const char * const sc7280_opp_pd_table[] = { "cx" };
static const struct platform_clk_data sc7280_clk_table[] = {
- {IRIS_CTRL_CLK, "core" },
- {IRIS_AXI_CLK, "iface" },
- {IRIS_AHB_CLK, "bus" },
- {IRIS_HW_CLK, "vcodec_core" },
- {IRIS_HW_AHB_CLK, "vcodec_bus" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_AXI_VCODEC_CLK, "iface" },
+ {IRIS_AHB_CLK, "bus" },
+ {IRIS_VCODEC_CLK, "vcodec_core" },
+ {IRIS_VCODEC_AHB_CLK, "vcodec_bus" },
};
static const char * const sc7280_opp_clk_table[] = {
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8750.h b/drivers/media/platform/qcom/iris/iris_platform_sm8750.h
index 719056656a5b..f843f13251c5 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8750.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8750.h
@@ -11,12 +11,12 @@ static const char * const sm8750_clk_reset_table[] = {
};
static const struct platform_clk_data sm8750_clk_table[] = {
- {IRIS_AXI_CLK, "iface" },
- {IRIS_CTRL_CLK, "core" },
- {IRIS_HW_CLK, "vcodec0_core" },
- {IRIS_AXI1_CLK, "iface1" },
- {IRIS_CTRL_FREERUN_CLK, "core_freerun" },
- {IRIS_HW_FREERUN_CLK, "vcodec0_core_freerun" },
+ {IRIS_AXI_VCODEC_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_VCODEC_CLK, "vcodec0_core" },
+ {IRIS_AXI_CTRL_CLK, "iface1" },
+ {IRIS_CTRL_FREERUN_CLK, "core_freerun" },
+ {IRIS_VCODEC_FREERUN_CLK, "vcodec0_core_freerun" },
};
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index fe4423b951b1..1f0a3a47d87f 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -209,7 +209,7 @@ static int iris_vpu33_power_off_controller(struct iris_core *core)
disable_power:
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
return 0;
}
@@ -218,36 +218,37 @@ static int iris_vpu35_power_on_hw(struct iris_core *core)
{
int ret;
- ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ ret = iris_enable_power_domains(core,
+ core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
if (ret)
return ret;
- ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_VCODEC_CLK);
if (ret)
goto err_disable_power;
- ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_FREERUN_CLK);
if (ret)
goto err_disable_axi_clk;
- ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_CLK);
if (ret)
goto err_disable_hw_free_clk;
- ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN], true);
if (ret)
goto err_disable_hw_clk;
return 0;
err_disable_hw_clk:
- iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_CLK);
err_disable_hw_free_clk:
- iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_FREERUN_CLK);
err_disable_axi_clk:
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
err_disable_power:
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
return ret;
}
@@ -256,8 +257,8 @@ static void iris_vpu35_power_off_hw(struct iris_core *core)
{
iris_vpu33_power_off_hardware(core);
- iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
}
const struct vpu_ops iris_vpu3_ops = {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c
index a8db02ce5c5e..4082d331d2f3 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu4x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c
@@ -27,7 +27,8 @@ static int iris_vpu4x_genpd_set_hwmode(struct iris_core *core, bool hw_mode, u32
{
int ret;
- ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], hw_mode);
+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN],
+ hw_mode);
if (ret)
return ret;
@@ -63,7 +64,7 @@ static int iris_vpu4x_genpd_set_hwmode(struct iris_core *core, bool hw_mode, u32
dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VPP0_HW_POWER_DOMAIN],
!hw_mode);
restore_hw_domain_mode:
- dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], !hw_mode);
+ dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN], !hw_mode);
return ret;
}
@@ -162,15 +163,15 @@ static int iris_vpu4x_enable_hardware_clocks(struct iris_core *core, u32 efuse_v
{
int ret;
- ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_VCODEC_CLK);
if (ret)
return ret;
- ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_FREERUN_CLK);
if (ret)
goto disable_axi_clock;
- ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_CLK);
if (ret)
goto disable_hw_free_run_clock;
@@ -198,11 +199,11 @@ static int iris_vpu4x_enable_hardware_clocks(struct iris_core *core, u32 efuse_v
disable_bse_hw_clock:
iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
disable_hw_clock:
- iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_CLK);
disable_hw_free_run_clock:
- iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_FREERUN_CLK);
disable_axi_clock:
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
return ret;
}
@@ -216,9 +217,9 @@ static void iris_vpu4x_disable_hardware_clocks(struct iris_core *core, u32 efuse
iris_disable_unprepare_clock(core, IRIS_VPP0_HW_CLK);
iris_disable_unprepare_clock(core, IRIS_BSE_HW_CLK);
- iris_disable_unprepare_clock(core, IRIS_HW_CLK);
- iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
}
static int iris_vpu4x_power_on_hardware(struct iris_core *core)
@@ -226,7 +227,8 @@ static int iris_vpu4x_power_on_hardware(struct iris_core *core)
u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR);
int ret;
- ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ ret = iris_enable_power_domains(core,
+ core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
if (ret)
return ret;
@@ -278,7 +280,7 @@ static int iris_vpu4x_power_on_hardware(struct iris_core *core)
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs
[IRIS_VPP0_HW_POWER_DOMAIN]);
disable_hw_power_domain:
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
return ret;
}
@@ -356,7 +358,7 @@ static void iris_vpu4x_power_off_hardware(struct iris_core *core)
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs
[IRIS_VPP0_HW_POWER_DOMAIN]);
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
}
const struct vpu_ops iris_vpu4x_ops = {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index bfd1e762c38e..006fd3ffc752 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -213,7 +213,7 @@ int iris_vpu_power_off_controller(struct iris_core *core)
disable_power:
iris_disable_unprepare_clock(core, IRIS_AHB_CLK);
iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
return 0;
@@ -221,10 +221,10 @@ int iris_vpu_power_off_controller(struct iris_core *core)
void iris_vpu_power_off_hw(struct iris_core *core)
{
- dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false);
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
- iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
- iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+ dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN], false);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_AHB_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_CLK);
}
void iris_vpu_power_off(struct iris_core *core)
@@ -251,7 +251,7 @@ int iris_vpu_power_on_controller(struct iris_core *core)
if (ret)
goto err_disable_power;
- ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_VCODEC_CLK);
if (ret)
goto err_disable_power;
@@ -268,7 +268,7 @@ int iris_vpu_power_on_controller(struct iris_core *core)
err_disable_ctrl_clock:
iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
err_disable_axi_clock:
- iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
err_disable_power:
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
@@ -279,30 +279,31 @@ int iris_vpu_power_on_hw(struct iris_core *core)
{
int ret;
- ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ ret = iris_enable_power_domains(core,
+ core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
if (ret)
return ret;
- ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_CLK);
if (ret)
goto err_disable_power;
- ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC_AHB_CLK);
if (ret && ret != -ENOENT)
goto err_disable_hw_clock;
- ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN], true);
if (ret)
goto err_disable_hw_ahb_clock;
return 0;
err_disable_hw_ahb_clock:
- iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_AHB_CLK);
err_disable_hw_clock:
- iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC_CLK);
err_disable_power:
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC_POWER_DOMAIN]);
return ret;
}
@@ -362,7 +363,7 @@ int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core)
disable_power:
iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
- iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_CTRL_CLK);
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
@@ -379,7 +380,7 @@ int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core)
if (ret)
return ret;
- ret = iris_prepare_enable_clock(core, IRIS_AXI1_CLK);
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_CTRL_CLK);
if (ret)
goto err_disable_power;
@@ -396,7 +397,7 @@ int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core)
err_disable_ctrl_free_clk:
iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
err_disable_axi1_clk:
- iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_CTRL_CLK);
err_disable_power:
iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
--
2.34.1
^ permalink raw reply related
* [PATCH 08/11] media: iris: Add power sequence for Glymur
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Add power sequence hooks for controller, vcodec and vcodec1. reuse the
existing code where ever is possible. add vcodec1 power on and off code
separately which has different power domains and clocks.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
.../platform/qcom/iris/iris_platform_common.h | 9 ++
drivers/media/platform/qcom/iris/iris_vpu3x.c | 123 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
.../platform/qcom/iris/iris_vpu_register_defines.h | 7 ++
4 files changed, 140 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index 30e9d4d288c6..e3c1aff770dd 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -61,6 +61,9 @@ enum platform_clk_type {
IRIS_VPP0_HW_CLK,
IRIS_VPP1_HW_CLK,
IRIS_APV_HW_CLK,
+ IRIS_AXI_VCODEC1_CLK,
+ IRIS_VCODEC1_CLK,
+ IRIS_VCODEC1_FREERUN_CLK,
};
struct platform_clk_data {
@@ -208,6 +211,12 @@ enum platform_pm_domain_type {
IRIS_CTRL_POWER_DOMAIN,
IRIS_VCODEC_POWER_DOMAIN,
IRIS_VPP0_HW_POWER_DOMAIN,
+ /*
+ * On Glymur, vcodec1 power domain is at the same index in pd_devs[]
+ * as IRIS_VPP0_HW_POWER_DOMAIN. Alias it so that the Glymur power
+ * domain table is indexed correctly.
+ */
+ IRIS_VCODEC1_POWER_DOMAIN = IRIS_VPP0_HW_POWER_DOMAIN,
IRIS_VPP1_HW_POWER_DOMAIN,
IRIS_APV_HW_POWER_DOMAIN,
};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index 1f0a3a47d87f..3f269f242b36 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -27,6 +27,16 @@ static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core)
return pwr_status ? false : true;
}
+static bool iris_vpu36_hw1_power_collapsed(struct iris_core *core)
+{
+ u32 value, pwr_status;
+
+ value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
+ pwr_status = value & BIT(4);
+
+ return pwr_status ? false : true;
+}
+
static void iris_vpu3_power_off_hardware(struct iris_core *core)
{
u32 reg_val = 0, value, i;
@@ -261,6 +271,111 @@ static void iris_vpu35_power_off_hw(struct iris_core *core)
iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC_CLK);
}
+static int iris_vpu36_power_on_hw1(struct iris_core *core)
+{
+ int ret;
+
+ ret = iris_enable_power_domains(core,
+ core->pmdomain_tbl->pd_devs[IRIS_VCODEC1_POWER_DOMAIN]);
+ if (ret)
+ return ret;
+
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_VCODEC1_CLK);
+ if (ret)
+ goto err_disable_hw1_power;
+
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC1_FREERUN_CLK);
+ if (ret)
+ goto err_disable_axi1_clk;
+
+ ret = iris_prepare_enable_clock(core, IRIS_VCODEC1_CLK);
+ if (ret)
+ goto err_disable_hw1_free_clk;
+
+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC1_POWER_DOMAIN], true);
+ if (ret)
+ goto err_disable_hw1_clk;
+
+ return 0;
+
+err_disable_hw1_clk:
+ iris_disable_unprepare_clock(core, IRIS_VCODEC1_CLK);
+err_disable_hw1_free_clk:
+ iris_disable_unprepare_clock(core, IRIS_VCODEC1_FREERUN_CLK);
+err_disable_axi1_clk:
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC1_CLK);
+err_disable_hw1_power:
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC1_POWER_DOMAIN]);
+
+ return ret;
+}
+
+static int iris_vpu36_power_on_hw(struct iris_core *core)
+{
+ int ret;
+
+ ret = iris_vpu35_power_on_hw(core);
+ if (ret)
+ return ret;
+
+ ret = iris_vpu36_power_on_hw1(core);
+ if (ret)
+ goto err_power_off_hw;
+
+ return 0;
+
+err_power_off_hw:
+ iris_vpu35_power_off_hw(core);
+
+ return ret;
+}
+
+static void iris_vpu36_power_off_hw1(struct iris_core *core)
+{
+ u32 value, i;
+ int ret;
+
+ if (iris_vpu36_hw1_power_collapsed(core))
+ goto disable_power;
+
+ value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+ if (value)
+ writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+
+ for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
+ ret = readl_poll_timeout(core->reg_base + VCODEC1_SS_IDLE_STATUSN + 4 * i,
+ value, value & DMA_NOC_IDLE, 2000, 20000);
+ if (ret)
+ goto disable_power;
+ }
+
+ writel(REQ_VCODEC1_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS,
+ value, value & NOC_LPI_VCODEC1_STATUS_DONE, 2000, 20000);
+ if (ret)
+ goto disable_power;
+
+ writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ writel(VCODEC1_BRIDGE_SW_RESET | VCODEC1_BRIDGE_HW_RESET_DISABLE, core->reg_base +
+ CPU_CS_AHB_BRIDGE_SYNC_RESET);
+ writel(VCODEC1_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+ writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+
+disable_power:
+ dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_VCODEC1_POWER_DOMAIN], false);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC1_CLK);
+ iris_disable_unprepare_clock(core, IRIS_VCODEC1_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_VCODEC1_CLK);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_VCODEC1_POWER_DOMAIN]);
+}
+
+static void iris_vpu36_power_off_hw(struct iris_core *core)
+{
+ iris_vpu35_power_off_hw(core);
+ iris_vpu36_power_off_hw1(core);
+}
+
const struct vpu_ops iris_vpu3_ops = {
.power_off_hw = iris_vpu3_power_off_hardware,
.power_on_hw = iris_vpu_power_on_hw,
@@ -285,3 +400,11 @@ const struct vpu_ops iris_vpu35_ops = {
.program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
.calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
};
+
+const struct vpu_ops iris_vpu36_ops = {
+ .power_off_hw = iris_vpu36_power_off_hw,
+ .power_on_hw = iris_vpu36_power_on_hw,
+ .power_off_controller = iris_vpu35_vpu4x_power_off_controller,
+ .power_on_controller = iris_vpu35_vpu4x_power_on_controller,
+ .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
+};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index f6dffc613b82..99e75fb4b10d 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -12,6 +12,7 @@ extern const struct vpu_ops iris_vpu2_ops;
extern const struct vpu_ops iris_vpu3_ops;
extern const struct vpu_ops iris_vpu33_ops;
extern const struct vpu_ops iris_vpu35_ops;
+extern const struct vpu_ops iris_vpu36_ops;
extern const struct vpu_ops iris_vpu4x_ops;
struct vpu_ops {
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h
index 72168b9ffa73..37f234484f1b 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h
@@ -7,6 +7,7 @@
#define __IRIS_VPU_REGISTER_DEFINES_H__
#define VCODEC_BASE_OFFS 0x00000000
+#define VCODEC1_BASE_OFFS 0x00040000
#define AON_MVP_NOC_RESET 0x0001F000
#define CPU_BASE_OFFS 0x000A0000
#define WRAPPER_BASE_OFFS 0x000B0000
@@ -14,6 +15,8 @@
#define AON_BASE_OFFS 0x000E0000
#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
+#define VCODEC1_SS_IDLE_STATUSN (VCODEC1_BASE_OFFS + 0x70)
+#define DMA_NOC_IDLE BIT(22)
#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
@@ -35,6 +38,8 @@
#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
#define CORE_BRIDGE_SW_RESET BIT(0)
#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
+#define VCODEC1_BRIDGE_SW_RESET BIT(2)
+#define VCODEC1_BRIDGE_HW_RESET_DISABLE BIT(3)
#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
@@ -52,11 +57,13 @@
#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
#define REQ_POWER_DOWN_PREP BIT(0)
+#define REQ_VCODEC1_POWER_DOWN_PREP BIT(1)
#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */
#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */
#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */
+#define NOC_LPI_VCODEC1_STATUS_DONE BIT(8)
#define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78)
#define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS + 0x80)
--
2.34.1
^ permalink raw reply related
* [PATCH 09/11] media: iris: Add support to select core for dual core platforms
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Select the hardware core (vcodec) for a session, based on load when the
platform supports dual vcodec cores. Assign the session to vcodec if its
MBPF/MBPS capacity allows it, otherwise assign to vcodec1. Communicate
the selected vcodec core to firmware using new HFI_PROP_CORE_ID property.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_common.c | 7 +++
drivers/media/platform/qcom/iris/iris_hfi_common.h | 1 +
.../platform/qcom/iris/iris_hfi_gen2_command.c | 19 ++++++
.../platform/qcom/iris/iris_hfi_gen2_defines.h | 1 +
drivers/media/platform/qcom/iris/iris_instance.h | 2 +
.../platform/qcom/iris/iris_platform_common.h | 1 +
drivers/media/platform/qcom/iris/iris_utils.c | 68 +++++++++++++++++-----
7 files changed, 83 insertions(+), 16 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_common.c b/drivers/media/platform/qcom/iris/iris_common.c
index 7f1c7fe144f7..e31d4c988c55 100644
--- a/drivers/media/platform/qcom/iris/iris_common.c
+++ b/drivers/media/platform/qcom/iris/iris_common.c
@@ -49,11 +49,18 @@ void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
int iris_process_streamon_input(struct iris_inst *inst)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ bool dual_core = inst->core->iris_platform_data->dual_core;
enum iris_inst_sub_state set_sub_state = 0;
int ret;
iris_scale_power(inst);
+ if (dual_core) {
+ ret = hfi_ops->session_set_core_id(inst, inst->core_id);
+ if (ret)
+ return ret;
+ }
+
ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (ret)
return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h
index 3edb5ae582b4..fbaf852a6b99 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -124,6 +124,7 @@ struct iris_hfi_command_ops {
int (*session_drain)(struct iris_inst *inst, u32 plane);
int (*session_resume_drain)(struct iris_inst *inst, u32 plane);
int (*session_close)(struct iris_inst *inst);
+ int (*session_set_core_id)(struct iris_inst *inst, u32 core_id);
};
struct iris_hfi_response_ops {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 30bfd90d423b..9d9fae587297 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -1300,6 +1300,24 @@ static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct i
inst_hfi_gen2->packet->size);
}
+static int iris_hfi_gen2_set_core_id(struct iris_inst *inst, u32 core_id)
+{
+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+ u32 payload = core_id;
+
+ iris_hfi_gen2_packet_session_command(inst,
+ HFI_PROP_CORE_ID,
+ HFI_HOST_FLAGS_NONE,
+ HFI_PORT_NONE,
+ inst->session_id,
+ HFI_PAYLOAD_U32,
+ &payload,
+ sizeof(u32));
+
+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
+ inst_hfi_gen2->packet->size);
+}
+
static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
.sys_init = iris_hfi_gen2_sys_init,
.sys_image_version = iris_hfi_gen2_sys_image_version,
@@ -1317,6 +1335,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
.session_drain = iris_hfi_gen2_session_drain,
.session_resume_drain = iris_hfi_gen2_session_resume_drain,
.session_close = iris_hfi_gen2_session_close,
+ .session_set_core_id = iris_hfi_gen2_set_core_id,
};
void iris_hfi_gen2_command_ops_init(struct iris_core *core)
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index cecf771c55dd..1926a5344427 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -56,6 +56,7 @@
#define HFI_PROP_BUFFER_HOST_MAX_COUNT 0x03000123
#define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT 0x03000124
#define HFI_PROP_PIC_ORDER_CNT_TYPE 0x03000128
+#define HFI_PROP_CORE_ID 0x030001A9
enum hfi_rate_control {
HFI_RC_VBR_CFR = 0x00000000,
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
index 16965150f427..dd341ca5be57 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -37,6 +37,7 @@ struct iris_fmt {
*
* @list: used for attach an instance to the core
* @core: pointer to core structure
+ * @core_id: specifies the hardware core on which the session runs
* @session_id: id of current video session
* @ctx_q_lock: lock to serialize queues related ioctls
* @lock: lock to seralise forward and reverse threads
@@ -79,6 +80,7 @@ struct iris_fmt {
struct iris_inst {
struct list_head list;
struct iris_core *core;
+ u32 core_id;
u32 session_id;
struct mutex ctx_q_lock;/* lock to serialize queues related ioctls */
struct mutex lock; /* lock to serialize forward and reverse threads */
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index e3c1aff770dd..aeb70f54be10 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -258,6 +258,7 @@ struct iris_platform_data {
const struct tz_cp_config *tz_cp_config_data;
u32 tz_cp_config_data_size;
u32 core_arch;
+ bool dual_core;
u32 hw_response_timeout;
struct ubwc_config_data *ubwc_config;
u32 num_vpp_pipe;
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c
index cfc5b576ec56..38ede9f76d0b 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -90,18 +90,51 @@ struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id)
return NULL;
}
-int iris_check_core_mbpf(struct iris_inst *inst)
+static u32 iris_get_mbps(struct iris_inst *inst)
{
- struct iris_core *core = inst->core;
- struct iris_inst *instance;
- u32 total_mbpf = 0;
+ u32 fps = max(inst->frame_rate, inst->operating_rate);
+
+ return iris_get_mbpf(inst) * fps;
+}
+
+static void iris_get_core_load(struct iris_core *core, u32 *core_load, bool mbpf)
+{
+ bool dual_core = core->iris_platform_data->dual_core;
+ struct iris_inst *inst;
+ u32 load;
mutex_lock(&core->lock);
- list_for_each_entry(instance, &core->instances, list)
- total_mbpf += iris_get_mbpf(instance);
+ list_for_each_entry(inst, &core->instances, list) {
+ if (mbpf)
+ load = iris_get_mbpf(inst);
+ else
+ load = iris_get_mbps(inst);
+
+ if (inst->core_id == BIT(0))
+ core_load[0] += load;
+ else if (dual_core && inst->core_id == BIT(1))
+ core_load[1] += load;
+ }
mutex_unlock(&core->lock);
+}
- if (total_mbpf > core->iris_platform_data->max_core_mbpf)
+int iris_check_core_mbpf(struct iris_inst *inst)
+{
+ struct iris_core *core = inst->core;
+ u32 max_core_mbpf = core->iris_platform_data->max_core_mbpf;
+ bool dual_core = core->iris_platform_data->dual_core;
+ u32 core_mbpf[2] = {0, 0}, new_mbpf;
+
+ inst->core_id = 0;
+ iris_get_core_load(core, core_mbpf, true);
+ new_mbpf = iris_get_mbpf(inst);
+
+ if (core_mbpf[0] + new_mbpf <= max_core_mbpf)
+ inst->core_id = BIT(0);
+ else if (dual_core && core_mbpf[1] + new_mbpf <= max_core_mbpf)
+ inst->core_id = BIT(1);
+
+ if (!inst->core_id)
return -ENOMEM;
return 0;
@@ -110,17 +143,20 @@ int iris_check_core_mbpf(struct iris_inst *inst)
int iris_check_core_mbps(struct iris_inst *inst)
{
struct iris_core *core = inst->core;
- struct iris_inst *instance;
- u32 total_mbps = 0, fps = 0;
+ u32 max_core_mbps = core->iris_platform_data->max_core_mbps;
+ bool dual_core = core->iris_platform_data->dual_core;
+ u32 core_mbps[2] = {0, 0}, new_mbps;
- mutex_lock(&core->lock);
- list_for_each_entry(instance, &core->instances, list) {
- fps = max(instance->frame_rate, instance->operating_rate);
- total_mbps += iris_get_mbpf(instance) * fps;
- }
- mutex_unlock(&core->lock);
+ inst->core_id = 0;
+ iris_get_core_load(core, core_mbps, false);
+ new_mbps = iris_get_mbps(inst);
+
+ if (core_mbps[0] + new_mbps <= max_core_mbps)
+ inst->core_id = BIT(0);
+ else if (dual_core && core_mbps[1] + new_mbps <= max_core_mbps)
+ inst->core_id = BIT(1);
- if (total_mbps > core->iris_platform_data->max_core_mbps)
+ if (!inst->core_id)
return -ENOMEM;
return 0;
--
2.34.1
^ permalink raw reply related
* [PATCH 10/11] media: iris: Add platform data for glymur
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Add glymur platform data by reusing most of the SM8550 definitions.
Move configuration that differs in a per-SoC platform specific data.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/Makefile | 1 +
.../platform/qcom/iris/iris_platform_common.h | 1 +
.../media/platform/qcom/iris/iris_platform_gen2.c | 100 +++++++++++++++++++++
.../platform/qcom/iris/iris_platform_glymur.c | 93 +++++++++++++++++++
.../platform/qcom/iris/iris_platform_glymur.h | 17 ++++
drivers/media/platform/qcom/iris/iris_probe.c | 4 +
6 files changed, 216 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
index 6f4052b98491..677513c7c045 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -11,6 +11,7 @@ qcom-iris-objs += iris_buffer.o \
iris_hfi_gen2_response.o \
iris_hfi_queue.o \
iris_platform_gen2.o \
+ iris_platform_glymur.o \
iris_power.o \
iris_probe.o \
iris_resources.o \
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index aeb70f54be10..a279ea462ee6 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -41,6 +41,7 @@ enum pipe_type {
PIPE_4 = 4,
};
+extern const struct iris_platform_data glymur_data;
extern const struct iris_platform_data qcs8300_data;
extern const struct iris_platform_data sc7280_data;
extern const struct iris_platform_data sm8250_data;
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index 47c6b650f0b4..fa2115092be8 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -12,6 +12,7 @@
#include "iris_vpu_buffer.h"
#include "iris_vpu_common.h"
+#include "iris_platform_glymur.h"
#include "iris_platform_qcs8300.h"
#include "iris_platform_sm8650.h"
#include "iris_platform_sm8750.h"
@@ -921,6 +922,105 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = {
BUF_SCRATCH_2,
};
+const struct iris_platform_data glymur_data = {
+ .get_instance = iris_hfi_gen2_get_instance,
+ .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
+ .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .get_vpu_buffer_size = iris_vpu_buf_size,
+ .vpu_ops = &iris_vpu36_ops,
+ .set_preset_registers = iris_set_sm8550_preset_registers,
+ .init_cb_devs = glymur_init_cb_devs,
+ .deinit_cb_devs = glymur_deinit_cb_devs,
+ .icc_tbl = sm8550_icc_table,
+ .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table),
+ .clk_rst_tbl = glymur_clk_reset_table,
+ .clk_rst_tbl_size = ARRAY_SIZE(glymur_clk_reset_table),
+ .bw_tbl_dec = sm8550_bw_table_dec,
+ .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec),
+ .pmdomain_tbl = glymur_pmdomain_table,
+ .pmdomain_tbl_size = ARRAY_SIZE(glymur_pmdomain_table),
+ .opp_pd_tbl = sm8550_opp_pd_table,
+ .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table),
+ .clk_tbl = glymur_clk_table,
+ .clk_tbl_size = ARRAY_SIZE(glymur_clk_table),
+ .opp_clk_tbl = glymur_opp_clk_table,
+ /* Upper bound of DMA address range */
+ .dma_mask = 0xffe00000 - 1,
+ .fwname = "qcom/vpu/vpu36_p4_s7.mbn",
+ .pas_id = IRIS_PAS_ID,
+ .dual_core = true,
+ .inst_iris_fmts = platform_fmts_sm8550_dec,
+ .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec),
+ .inst_caps = &platform_inst_cap_sm8550,
+ .inst_fw_caps_dec = inst_fw_cap_sm8550_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
+ .tz_cp_config_data = tz_cp_config_glymur,
+ .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_glymur),
+ .core_arch = VIDEO_ARCH_LX,
+ .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
+ .ubwc_config = &ubwc_config_sm8550,
+ .num_vpp_pipe = 4,
+ .max_session_count = 16,
+ .max_core_mbpf = NUM_MBS_8K * 2,
+ .max_core_mbps = ((8192 * 4320) / 256) * 60,
+ .dec_input_config_params_default =
+ sm8550_vdec_input_config_params_default,
+ .dec_input_config_params_default_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
+ .dec_input_config_params_hevc =
+ sm8550_vdec_input_config_param_hevc,
+ .dec_input_config_params_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
+ .dec_input_config_params_vp9 =
+ sm8550_vdec_input_config_param_vp9,
+ .dec_input_config_params_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
+ .dec_input_config_params_av1 =
+ sm8550_vdec_input_config_param_av1,
+ .dec_input_config_params_av1_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_av1),
+ .dec_output_config_params =
+ sm8550_vdec_output_config_params,
+ .dec_output_config_params_size =
+ ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
+ .dec_input_prop = sm8550_vdec_subscribe_input_properties,
+ .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
+ .dec_output_prop_avc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
+ .dec_output_prop_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
+ .dec_output_prop_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
+ .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1,
+ .dec_output_prop_av1_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1),
+
+ .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
+ .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl,
+ .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl),
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
+};
+
const struct iris_platform_data sm8550_data = {
.get_instance = iris_hfi_gen2_get_instance,
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_glymur.c b/drivers/media/platform/qcom/iris/iris_platform_glymur.c
new file mode 100644
index 000000000000..64b150db9f73
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_glymur.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/media/qcom,glymur-iris.h>
+#include "iris_core.h"
+#include "iris_platform_common.h"
+#include "iris_platform_glymur.h"
+
+#define VIDEO_REGION_SECURE_FW_REGION_ID 0
+#define VIDEO_REGION_VM0_SECURE_NP_ID 1
+#define VIDEO_REGION_VM0_NONSECURE_NP_ID 5
+
+const struct platform_clk_data glymur_clk_table[] = {
+ {IRIS_AXI_VCODEC_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_VCODEC_CLK, "vcodec0_core" },
+ {IRIS_AXI_CTRL_CLK, "iface_ctrl" },
+ {IRIS_CTRL_FREERUN_CLK, "core_freerun" },
+ {IRIS_VCODEC_FREERUN_CLK, "vcodec0_core_freerun" },
+ {IRIS_AXI_VCODEC1_CLK, "iface1" },
+ {IRIS_VCODEC1_CLK, "vcodec1_core" },
+ {IRIS_VCODEC1_FREERUN_CLK, "vcodec1_core_freerun" },
+};
+
+const char * const glymur_clk_reset_table[] = {
+ "bus0",
+ "bus_ctrl",
+ "core",
+ "vcodec0_core",
+ "bus1",
+ "vcodec1_core",
+};
+
+const char * const glymur_opp_clk_table[] = {
+ "vcodec0_core",
+ "vcodec1_core",
+ "core",
+ NULL,
+};
+
+const char * const glymur_pmdomain_table[] = {
+ "venus",
+ "vcodec0",
+ "vcodec1",
+};
+
+const struct tz_cp_config tz_cp_config_glymur[] = {
+ {
+ .cp_start = VIDEO_REGION_SECURE_FW_REGION_ID,
+ .cp_size = 0,
+ .cp_nonpixel_start = 0,
+ .cp_nonpixel_size = 0x1000000,
+ },
+ {
+ .cp_start = VIDEO_REGION_VM0_SECURE_NP_ID,
+ .cp_size = 0,
+ .cp_nonpixel_start = 0x1000000,
+ .cp_nonpixel_size = 0x24800000,
+ },
+ {
+ .cp_start = VIDEO_REGION_VM0_NONSECURE_NP_ID,
+ .cp_size = 0,
+ .cp_nonpixel_start = 0x25800000,
+ .cp_nonpixel_size = 0xda600000,
+ },
+};
+
+int glymur_init_cb_devs(struct iris_core *core)
+{
+ const u32 f_id = IRIS_FIRMWARE;
+ struct device *dev;
+
+ dev = iris_create_cb_dev(core, "iris_firmware", &f_id);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+
+ if (device_iommu_mapped(dev))
+ core->dev_fw = dev;
+ else
+ device_unregister(dev);
+
+ return 0;
+}
+
+void glymur_deinit_cb_devs(struct iris_core *core)
+{
+ if (core->dev_fw)
+ device_unregister(core->dev_fw);
+
+ core->dev_fw = NULL;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_platform_glymur.h b/drivers/media/platform/qcom/iris/iris_platform_glymur.h
new file mode 100644
index 000000000000..03c83922f0d9
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_glymur.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __IRIS_PLATFORM_GLYMUR_H__
+#define __IRIS_PLATFORM_GLYMUR_H__
+
+extern const struct platform_clk_data glymur_clk_table[9];
+extern const char * const glymur_clk_reset_table[6];
+extern const char * const glymur_opp_clk_table[4];
+extern const char * const glymur_pmdomain_table[3];
+extern const struct tz_cp_config tz_cp_config_glymur[3];
+int glymur_init_cb_devs(struct iris_core *core);
+void glymur_deinit_cb_devs(struct iris_core *core);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index 34751912f871..53869d9113d5 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -369,6 +369,10 @@ static const struct dev_pm_ops iris_pm_ops = {
};
static const struct of_device_id iris_dt_match[] = {
+ {
+ .compatible = "qcom,glymur-iris",
+ .data = &glymur_data,
+ },
{
.compatible = "qcom,qcs8300-iris",
.data = &qcs8300_data,
--
2.34.1
^ permalink raw reply related
* [PATCH 11/11] arm64: dts: qcom: glymur: Add iris video node
From: Vishnu Reddy @ 2026-04-14 5:00 UTC (permalink / raw)
To: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu,
Vishnu Reddy
In-Reply-To: <20260414-glymur-v1-0-7d3d1cf57b16@oss.qualcomm.com>
Add iris video codec to glymur SoC, which comes with significantly
different powering up sequence than previous plaforms, thus different
clocks and resets.
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/glymur-crd.dts | 4 ++
arch/arm64/boot/dts/qcom/glymur.dtsi | 118 ++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts
index 35aaf09e4e2b..cbc9856956ff 100644
--- a/arch/arm64/boot/dts/qcom/glymur-crd.dts
+++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts
@@ -255,6 +255,10 @@ &mdss_dp3_phy {
status = "okay";
};
+&iris {
+ status = "okay";
+};
+
&pmh0110_f_e0_gpios {
misc_3p3_reg_en: misc-3p3-reg-en-state {
pins = "gpio6";
diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi
index f23cf81ddb77..e139b2d2e33e 100644
--- a/arch/arm64/boot/dts/qcom/glymur.dtsi
+++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -13,6 +13,7 @@
#include <dt-bindings/interconnect/qcom,glymur-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/media/qcom,glymur-iris.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/power/qcom-rpmpd.h>
@@ -4163,6 +4164,123 @@ usb_mp: usb@a400000 {
status = "disabled";
};
+ iris: video-codec@aa00000 {
+ compatible = "qcom,glymur-iris";
+ reg = <0x0 0xaa00000 0x0 0xf0000>;
+
+ clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+ <&videocc VIDEO_CC_MVS0C_CLK>,
+ <&videocc VIDEO_CC_MVS0_CLK>,
+ <&gcc GCC_VIDEO_AXI0C_CLK>,
+ <&videocc VIDEO_CC_MVS0C_FREERUN_CLK>,
+ <&videocc VIDEO_CC_MVS0_FREERUN_CLK>,
+ <&gcc GCC_VIDEO_AXI1_CLK>,
+ <&videocc VIDEO_CC_MVS1_CLK>,
+ <&videocc VIDEO_CC_MVS1_FREERUN_CLK>;
+ clock-names = "iface",
+ "core",
+ "vcodec0_core",
+ "iface_ctrl",
+ "core_freerun",
+ "vcodec0_core_freerun",
+ "iface1",
+ "vcodec1_core",
+ "vcodec1_core_freerun";
+
+ dma-coherent;
+
+ interconnects = <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+ <&mmss_noc MASTER_VIDEO QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "cpu-cfg",
+ "video-mem";
+
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0x1940 0x0>,
+ <&apps_smmu 0x1943 0x0>,
+ <&apps_smmu 0x1944 0x0>,
+ <&apps_smmu 0x19e0 0x0>;
+
+ iommu-map = <IRIS_FIRMWARE &apps_smmu 0x19e2 0x1>;
+
+ memory-region = <&video_mem>;
+
+ operating-points-v2 = <&iris_opp_table>;
+
+ power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+ <&videocc VIDEO_CC_MVS0_GDSC>,
+ <&rpmhpd RPMHPD_MXC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&videocc VIDEO_CC_MVS1_GDSC>;
+ power-domain-names = "venus",
+ "vcodec0",
+ "mxc",
+ "mmcx",
+ "vcodec1";
+
+ resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>,
+ <&gcc GCC_VIDEO_AXI0C_CLK_ARES>,
+ <&videocc VIDEO_CC_MVS0C_FREERUN_CLK_ARES>,
+ <&videocc VIDEO_CC_MVS0_FREERUN_CLK_ARES>,
+ <&gcc GCC_VIDEO_AXI1_CLK_ARES>,
+ <&videocc VIDEO_CC_MVS1_FREERUN_CLK_ARES>;
+ reset-names = "bus0",
+ "bus_ctrl",
+ "core",
+ "vcodec0_core",
+ "bus1",
+ "vcodec1_core";
+
+ /*
+ * IRIS firmware is signed by vendors, only
+ * enable on boards where the proper signed firmware
+ * is available.
+ */
+ status = "disabled";
+
+ iris_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-240000000 {
+ opp-hz = /bits/ 64 <240000000 240000000 360000000>;
+ required-opps = <&rpmhpd_opp_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-338000000 {
+ opp-hz = /bits/ 64 <338000000 338000000 507000000>;
+ required-opps = <&rpmhpd_opp_svs>,
+ <&rpmhpd_opp_svs>;
+ };
+
+ opp-366000000 {
+ opp-hz = /bits/ 64 <366000000 366000000 549000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-444000000 {
+ opp-hz = /bits/ 64 <444000000 444000000 666000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_nom>;
+ };
+
+ opp-533333334 {
+ opp-hz = /bits/ 64 <533333334 533333334 800000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>,
+ <&rpmhpd_opp_turbo>;
+ };
+
+ opp-655000000 {
+ opp-hz = /bits/ 64 <655000000 655000000 982000000>;
+ required-opps = <&rpmhpd_opp_nom>,
+ <&rpmhpd_opp_turbo_l1>;
+ };
+ };
+ };
+
mdss: display-subsystem@ae00000 {
compatible = "qcom,glymur-mdss";
reg = <0x0 0x0ae00000 0x0 0x1000>;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v5 4/5] remoteproc: qcom: pas: Add late attach support for subsystems
From: Jingyi Wang @ 2026-04-14 5:01 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Mathieu Poirier, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Manivannan Sadhasivam, Luca Weiss, Bartosz Golaszewski,
Konrad Dybcio, aiqun.yu, tingwei.zhang, trilok.soni, yijie.yang,
linux-arm-msm, linux-remoteproc, devicetree, linux-kernel,
Gokul Krishna Krishnakumar
In-Reply-To: <adm56u_cDoKnuPob@baldur>
On 4/11/2026 11:04 AM, Bjorn Andersson wrote:
> On Thu, Apr 09, 2026 at 01:52:27AM -0700, Jingyi Wang wrote:
> [..]
>> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
>> index da27d1d3c9da..34b54cf832d0 100644
>> --- a/drivers/remoteproc/qcom_q6v5_pas.c
>> +++ b/drivers/remoteproc/qcom_q6v5_pas.c
>> @@ -60,6 +60,7 @@ struct qcom_pas_data {
>> int region_assign_count;
>> bool region_assign_shared;
>> int region_assign_vmid;
>> + bool early_boot;
>> };
>>
>> struct qcom_pas {
>> @@ -423,9 +424,15 @@ static int qcom_pas_stop(struct rproc *rproc)
>>
>> qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size);
>>
>> - handover = qcom_q6v5_unprepare(&pas->q6v5);
>> - if (handover)
>> - qcom_pas_handover(&pas->q6v5);
>> + /*
>> + * qcom_q6v5_prepare is not called in qcom_pas_attach, skip unprepare to
>> + * avoid mismatch.
>
> Can you confirm that no load_state should be sent to AOSS for SoCCP?
> (I.e. from the skipped qcom_q6v5_prepare())
>
> Regards,
> Bjorn
load_state send qmp to the subsystem, we checked from code level that
current downstream SoCCP do nothing with this now, I will double confirm
it from subsystem side.
Thanks,
Jingyi
^ permalink raw reply
* Re: [PATCH v7 0/8] Add support for handling PCIe M.2 Key E connectors in devicetree
From: Chen-Yu Tsai @ 2026-04-14 5:03 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Manivannan Sadhasivam, Rob Herring, Greg Kroah-Hartman,
Jiri Slaby, Nathan Chancellor, Nicolas Schier, Hans de Goede,
Ilpo Järvinen, Mark Pearson, Derek J. Clark,
Krzysztof Kozlowski, Conor Dooley, Marcel Holtmann,
Luiz Augusto von Dentz, Bartosz Golaszewski, Andy Shevchenko,
Bartosz Golaszewski, linux-serial, linux-kernel, linux-kbuild,
platform-driver-x86, linux-pci, devicetree, linux-arm-msm,
linux-bluetooth, linux-pm, Stephan Gerhold, Dmitry Baryshkov,
linux-acpi, Hans de Goede, Bartosz Golaszewski
In-Reply-To: <eeytuhqpgdz4do4tgtbmfntub2femtyq7bij7svhodpyjwaylx@j3gmvq2a2zqc>
On Tue, Apr 14, 2026 at 12:08 AM Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> [Resending as my previous reply got bounced]
>
> On Mon, Apr 13, 2026 at 07:33:12PM +0530, Manivannan Sadhasivam wrote:
> > On Mon, Apr 13, 2026 at 03:54:59PM +0800, Chen-Yu Tsai wrote:
> > > Hi,
> > >
> > > On Thu, Mar 26, 2026 at 01:36:28PM +0530, Manivannan Sadhasivam wrote:
> > > > Hi,
> > > >
> > > > This series is the continuation of the series [1] that added the initial support
> > > > for the PCIe M.2 connectors. This series extends it by adding support for Key E
> > > > connectors. These connectors are used to connect the Wireless Connectivity
> > > > devices such as WiFi, BT, NFC and GNSS devices to the host machine over
> > > > interfaces such as PCIe/SDIO, USB/UART and NFC. This series adds support for
> > > > connectors that expose PCIe interface for WiFi and UART interface for BT. Other
> > > > interfaces are left for future improvements.
> > >
> > > Thanks for working on this. I started playing with it now that it is in
> > > -next. The PCIe part works fine. I'm looking into how to fit the pwrseq
> > >
> > > A couple questions:
> > >
> > > - Given that this connector actually represents two devices, how do I
> > > say I want the BT part to be a wakeup source, but not the WiFi part?
> > > Does wakeup-source even work at this point?
> > >
> >
> > You can't use the DT property since the devices are not described in DT
> > statically. But you can still use the per-device 'wakeup' sysfs knob to enable
> > wakeup.
I see. I think not being able to specify generic properties for the devices
on the connector is going to be a bit problematic. Another use case I have
requires specifying a bounce buffer / SWIOTLB for the PCIe WiFi card. The
PCIe controller does not have an IOMMU behind it.
> > > - Are there plans to do the SDIO part?
> > >
> >
> > No, not at the moment. Feel free to take it up if you have the hardware and
> > motivation :)
Ack. I think I still need to figure out what the plan is after mmc-pwrseq
is deprecated.
> > > - The matching done in the M.2 connector driver for pwrseq_get() seems a
> > > bit naive. It simply checks if the remote device in the OF graph is
> > > the same as the requesting device.
> > >
> > > I think this would run into issues with USB hubs. If I have a USB hub
> > > and two M.2 connectors, with both connectors connected to the same
> > > hub, pwrseq_get() is going to always return only one of the instances.
> > > This is because the USB hub has one device node with multiple OF graph
> > > ports.
> > >
> >
> > Yeah, this is a known limitation. I'm trying to improve this part now and have
> > the WIP commits here: https://github.com/Mani-Sadhasivam/linux/tree/pwrseq-bt-en-fixes
> >
> > Once the merge window closes, I'll submit these.
I couldn't tell which commit would help with this.
In my head I think we would need to extend pwrseq_get() to add something
like an index parameter that the provider is free to interpret. The M.2
connector driver could interpret it as the USB port number on the remote
end.
Thanks
ChenYu
^ permalink raw reply
* Re: [PATCH v5 4/5] remoteproc: qcom: pas: Add late attach support for subsystems
From: Jingyi Wang @ 2026-04-14 5:08 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Manivannan Sadhasivam,
Luca Weiss, Bartosz Golaszewski, Konrad Dybcio
Cc: aiqun.yu, tingwei.zhang, trilok.soni, yijie.yang, linux-arm-msm,
linux-remoteproc, devicetree, linux-kernel,
Gokul Krishna Krishnakumar
In-Reply-To: <ca268d5a-f55b-4f6f-ad35-1f856446c261@oss.qualcomm.com>
On 4/11/2026 2:04 PM, Jie Gan wrote:
>
>
> On 4/9/2026 4:52 PM, Jingyi Wang wrote:
<...>
>> static const struct rproc_ops qcom_pas_ops = {
>> .unprepare = qcom_pas_unprepare,
>> .start = qcom_pas_start,
>> @@ -518,6 +582,7 @@ static const struct rproc_ops qcom_pas_ops = {
>> .parse_fw = qcom_pas_parse_firmware,
>> .load = qcom_pas_load,
>> .panic = qcom_pas_panic,
>> + .attach = qcom_pas_attach,
>
> Possible issue in the future here. The kaanapali_soccp_resource does not set minidump_id, so this is not triggered today, but it is a latent bug for any future device that sets both early_boot and minidump_id.
>
> qcom_pas_attach is added to qcom_pas_ops but not to qcom_pas_minidump_ops. When a device with minidump_id set uses the minidump ops table, the .attach pointer is NULL. rproc_attach_device() checks if (rproc->ops->attach) before calling it, so the attach callback is silently skipped. For a device with early_boot = true and minidump_id != 0, the state is set to RPROC_DETACHED in probe, but the attach logic (crash check, ready check, ping) is never executed, leaving the subsystem in an inconsistent state.
>
> Thanks,
> Jie
>
ACK, we can add qcom_pas_attach to minidumps_ops in next version.
Thanks,
Jingyi
>> };
>> static const struct rproc_ops qcom_pas_minidump_ops = {
>> @@ -855,6 +920,15 @@ static int qcom_pas_probe(struct platform_device *pdev)
>> pas->pas_ctx->use_tzmem = rproc->has_iommu;
>> pas->dtb_pas_ctx->use_tzmem = rproc->has_iommu;
>> +
>> + if (desc->early_boot) {
>> + ret = qcom_q6v5_ping_subsystem_init(&pas->q6v5, pdev);
>> + if (ret)
>> + dev_warn(&pdev->dev, "Falling back to firmware load\n");
>> + else
>> + pas->rproc->state = RPROC_DETACHED;
>> + }
>> +
>> ret = rproc_add(rproc);
>> if (ret)
>> goto remove_ssr_sysmon;
>>
>
^ permalink raw reply
* Re: [PATCH v1] arm64: dts: qcom: lemans: Enable DISPLAY-PORT
From: Kumar Anurag Singh @ 2026-04-14 5:41 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <579913ed-4fc9-4eee-9093-13b1f701e018@oss.qualcomm.com>
On 4/13/2026 2:14 PM, Konrad Dybcio wrote:
> On 4/13/26 6:37 AM, Kumar Anurag wrote:
>> Add dailinks for DISPLAY-PORT to enable audio functionality
>> on edp0.
> "DisplayPort"
>
> The commit title is misleading.
>
We will change the commit title :
From: arm64: dts: qcom: lemans: Enable DISPLAY-PORT
to : arm64: dts: qcom: lemans: Enable audio playback over DisplayPort
> [...]
>
>> + dp0-dai-link {
>> + link-name = "DisplayPort0 Playback";
>> +
>> + cpu {
>> + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>;
>> + };
>> +
>> + codec {
>> + sound-dai = <&mdss0_dp0>;
>> + };
> 'co'dec < 'cp'u, please re-sort
>
> Konrad
In the other Dai links the cpu is before codec and hence we maintain the
same order in dp0 dai link too.
Same pattern is observed in DTS of all qcom platforms.
Thanks & Regards
Anurag
^ permalink raw reply
* Re: [PATCH 2/2] pwm: pxa: Add optional bus clock
From: Yixun Lan @ 2026-04-14 6:04 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Duje Mihanović, linux-pwm, devicetree, linux-kernel,
linux-riscv, spacemit
In-Reply-To: <adyq-Uckwwe9uACA@monoceros>
Hi Uwe,
On 10:38 Mon 13 Apr , Uwe Kleine-König wrote:
> Hello,
>
> On Thu, Apr 09, 2026 at 12:45:12AM +0000, Yixun Lan wrote:
> > Add one secondary optional bus clock for the PWM PXA driver, also keep it
> > compatible with old single clock.
> >
> > The SpacemiT K3 SoC require one bus clock for PWM controller, acquire
>
> s/one/a/ ?
>
Ok
> > and enable it during probe phase.
> >
> > Signed-off-by: Yixun Lan <dlan@kernel.org>
> > ---
> > drivers/pwm/pwm-pxa.c | 8 +++++++-
> > 1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
> > index 0f5bdb0e395e..2ace31405c2d 100644
> > --- a/drivers/pwm/pwm-pxa.c
> > +++ b/drivers/pwm/pwm-pxa.c
> > @@ -53,6 +53,7 @@ struct pxa_pwm_chip {
> > struct device *dev;
> >
> > struct clk *clk;
> > + struct clk *bus_clk;
> > void __iomem *mmio_base;
> > };
> >
> > @@ -177,7 +178,12 @@ static int pwm_probe(struct platform_device *pdev)
> > return PTR_ERR(chip);
> > pc = to_pxa_pwm_chip(chip);
> >
> > - pc->clk = devm_clk_get(dev, NULL);
> > + pc->bus_clk = devm_clk_get_optional_enabled(dev, "bus");
> > + if (IS_ERR(pc->bus_clk))
> > + return dev_err_probe(dev, PTR_ERR(pc->bus_clk), "Failed to get bus clock\n");
> > +
> > + /* Get named func clk if bus clock is valid */
> > + pc->clk = devm_clk_get(dev, pc->bus_clk ? "func" : NULL);
>
> A local variable for bus_clk would be sufficient.
>
Ok, will do
> I'm not sure, but I think passing "func" unconditionally to
> devm_clk_get() would also work fine.
Passing "func" unconditionally, will break old compatibles(not k3-pwm), as only
one clocks property is provided, but no clock-names property
--
Yixun Lan (dlan)
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: arm: cpus: Add compatible qcom,oryon-1-5
From: Krzysztof Kozlowski @ 2026-04-14 6:23 UTC (permalink / raw)
To: Shawn Guo
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bartosz Golaszewski, Deepti Jaggi, linux-arm-msm,
devicetree, linux-kernel
In-Reply-To: <ad2WsFuUjtcjZ1wU@QCOM-aGQu4IUr3Y>
On 14/04/2026 03:21, Shawn Guo wrote:
> On Mon, Apr 13, 2026 at 06:08:49PM +0200, Krzysztof Kozlowski wrote:
>> On 13/04/2026 16:34, Shawn Guo wrote:
>>> In short, there will be Nord DTS using the binding coming, and I do not
>>
>> Maybe there will, maybe there will not.
>>
>>> think posting them at the same time should be a requirement.
>>
>> Well, it is a requirement as I explained previously, said that
>> *multiple* times on the mailing list, documented expectations in
>> mentioned/linked email threads.
>
> To be honest, I can only read the following from mentioned email
> threads.
>
> - Binding and DTS should be organized in separate series per subsystem
> - DTS should reference binding series by a lore link
>
>
The links told explicitly to organize series per subsystem/maintainer.
Who is the subsystem here?
These are what I'm trying to do, and I'm not just posting DTS
> simultaneously. I do not really read the requirement of posting
> binding and DTS using it simultaneously from the email threads.
>
> Taking a step back, even if the requirement is mentioned in an email
> thread like this one, I'm not sure it's the correct or well received
> way to define a requirement. And that might be why you had to keep
> repeating yourself.
>
>> It's also documented in submitting
>> patches in DT (although not with that strong wording).
>
> Either I'm blind or reading the wrong document. I failed to find
> the requirement of posting binding and DTS using it simultaneously
> in Documentation/devicetree/bindings/submitting-patches.rst. Could you
> point it out explicitly?
Rule 8.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v8 1/2] dt-bindings: i2c: loongson,ls2x: Add ls2k0300-i2c compatible
From: Binbin Zhou @ 2026-04-14 6:25 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Wolfram Sang, Andy Shevchenko,
linux-i2c
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, Binbin Zhou,
Conor Dooley
In-Reply-To: <cover.1776135865.git.zhoubinbin@loongson.cn>
Add "loongson,ls2k0300-i2c" dedicated compatible for representing I2C of
Loongson-2K0300 chip, because its HW integration is quiet different from
others.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml b/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
index 67882ec6e06a..ee09c6d9c5f0 100644
--- a/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
@@ -16,6 +16,7 @@ properties:
compatible:
enum:
- loongson,ls2k-i2c
+ - loongson,ls2k0300-i2c
- loongson,ls7a-i2c
reg:
@@ -24,6 +25,9 @@ properties:
interrupts:
maxItems: 1
+ clocks:
+ maxItems: 1
+
required:
- compatible
- reg
--
2.52.0
^ permalink raw reply related
* [PATCH v8 0/2] i2c: Add Loongson-2K0300 I2C controller support
From: Binbin Zhou @ 2026-04-14 6:25 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andi Shyti, Wolfram Sang, Andy Shevchenko,
linux-i2c
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, Binbin Zhou
Hi all:
This patch set describes the I2C controller integrated the
Loongson-2K0300 chip.
It has a significantly different design from the previous I2C
controller(i2c-ls2x), such as support for master-slave transfer mode,
and DMA transfers (implementation in progress), etc. Therefore, we try
to name it i2c-ls2x-v2.
Thanks.
======
V8:
Patch (2/2):
- Since the physical unit is specific, revert the change made in v7
to replace `MHz` with `mhz`.
Link to V7:
https://lore.kernel.org/all/cover.1775900045.git.zhoubinbin@loongson.cn/
V7:
- Add Reviewed-by tag from Huacai & Andy, thanks.
Patch (2/2):
- Add the REGMAP_MMIO Kconfig dependency;
- parent_rate_MHz -> parent_rate_mhz to avoid CamelCase.
Link to V6:
https://lore.kernel.org/all/cover.1773991081.git.zhoubinbin@loongson.cn/
V6:
- Rebase on linux-i2c/i2c-next;
Patch (2/2):
- Update comment;
- Use regmap_get_device();
Link to V5:
https://lore.kernel.org/all/cover.1773142933.git.zhoubinbin@loongson.cn/
V5:
- Rebase on linux-i2c/i2c-next;
Patch (2/2):
- Add time.h header file;
- Add the `MHz` suffix to `parent_rate` and `freq`;
- Define an iterator within the for loop, with its type being
`unsigned int`;
- Use dev_err_probe() in loongson2_i2c_adjust_bus_speed();
- i2c_adapter_set_node()->device_set_node().
Link to V4:
https://lore.kernel.org/all/cover.1772714348.git.zhoubinbin@loongson.cn/
V4:
- Rebase on linux-i2c/i2c-next;
Patch (2/2):
- The parent_rate parameter type should be `unsigned long`;
- Drop fallthrough and add missing break;
- device_set_node()->i2c_adapter_set_node();
- Use i2c_parse_fw_timings();
- Use i2c_t.bus_freq_hz instead of priv->speed;
- Sperate loongson2_i2c_handle_read() into loongson2_i2c_handle_read()
and loongson2_i2c_handle_rx_done().
Link to V3:
https://lore.kernel.org/all/cover.1772001073.git.zhoubinbin@loongson.cn/
V3:
- Rebase on linux-i2c/i2c-next;
Patch (2/2):
- Reorder header file follow IWYU principle;
- Better indentation and coding style;
- Use generic macro definitions;
- Amend *all* struct data types;
- Correct unreasonable variable type definitions;
- Refact loongson2_i2c_isr_error();
- of_property_read_u32()->device_property_read_u32();
- Remove meaningless blank lines and output.
Link to V2:
https://lore.kernel.org/all/cover.1769476820.git.zhoubinbin@loongson.cn/
V2:
Patch (1/2):
- Add Acked-by tag from Conor, thanks.
Patch (2/2):
- Reorder the definitions of read() and write();
- Adjust the calculation method for bus speed.
Link to V1:
https://lore.kernel.org/all/cover.1763018288.git.zhoubinbin@loongson.cn/
Binbin Zhou (2):
dt-bindings: i2c: loongson,ls2x: Add ls2k0300-i2c compatible
i2c: ls2x-v2: Add driver for Loongson-2K0300 I2C controller
.../bindings/i2c/loongson,ls2x-i2c.yaml | 4 +
MAINTAINERS | 1 +
drivers/i2c/busses/Kconfig | 11 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ls2x-v2.c | 544 ++++++++++++++++++
5 files changed, 561 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-ls2x-v2.c
base-commit: 8fc326e15895c9f0403e6243dd4ad468b10aab3d
--
2.52.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox