* Re: [PATCH 2/4] drm/bridge: display-connector: Fix I2C adapter resource leak
From: Luca Ceresoli @ 2026-07-17 20:06 UTC (permalink / raw)
To: Laurent Pinchart, Luca Ceresoli
Cc: Johan Hovold, dri-devel, devicetree, Thuan Nguyen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Andrzej Hajda, Neil Armstrong, Robert Foss,
Jonas Karlman, Jernej Skrabec, linux-renesas-soc, stable
In-Reply-To: <20260717182802.GD1889304@killaraus.ideasonboard.com>
Hi Laurent,
On Fri Jul 17, 2026 at 8:28 PM CEST, Laurent Pinchart wrote:
> On Fri, Jul 17, 2026 at 05:21:11PM +0200, Luca Ceresoli wrote:
>> On Fri Jul 17, 2026 at 5:03 PM CEST, Johan Hovold wrote:
>> > On Mon, Jul 06, 2026 at 12:35:40AM +0300, Laurent Pinchart wrote:
>> >> If the probe function returns an error after getting the I2C adapter for
>> >> DDC, the reference to the adapter is never released. Fix it by releasing
>> >> it in the bridge .destroy() handler.
>> >>
>> >> There is no need to test the ddc pointer with !IS_ERR(), as
>> >> of_get_i2c_adapter_by_node() returns NULL on error.
>> >
>> > I stumbled over this this morning as well and posted a fix here (which
>> > releases the adapter on driver unbind as is currently done):
>> >
>> > https://lore.kernel.org/lkml/20260717085716.1619275-1-johan@kernel.org/
>> >
>> >> Fixes: 6de79dd3a920 ("drm/bridge: display-connector: add ddc-en gpio support")
>> >
>> > I believe this issue was first introduced by commit 2e2bf3a5584d
>> > ("drm/bridge: display-connector: add DP support") a few releases
>> > earlier.
>> >
>> >> Cc: stable@vger.kernel.org
>> >> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>> >
>> > Reviewed-by: Johan Hovold <johan@kernel.org>
>>
>> While Johan's patch has the benefit of putting the i2c adapter at remove
>> time (as opposed to destroy time, which is potentially a long time later),
>> it is also more complex. So I'd say this patch is fine.
>
> In this case putting the I2C adapter early is probably fine, but in
> general I really prefer reference-counting and releasing references at
> destroy time. This ensures that the resources stay available if they
> need to be accessed between .remove() and destruction (for instance in a
> .release() handler following a close() or munmap() from userspace). I
> think late release should be the default, as it's safer, and early
> release should be carefully reviewed when it's required.
Makes sense indeed.
Thanks for the clarification.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: mmc: Add post-power-off-delay-ms property
From: Judith Mendez @ 2026-07-17 20:10 UTC (permalink / raw)
To: Ulf Hansson
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-mmc, devicetree, linux-kernel
In-Reply-To: <CAPx+jO-a3+mv2msL+12Ag-xs33es2+Wxbr_uKRMY3rbN7eL-cw@mail.gmail.com>
Hi Ulf,
On 7/17/26 5:21 AM, Ulf Hansson wrote:
> On Fri, Jul 17, 2026 at 1:26 AM Judith Mendez <jm@ti.com> wrote:
>>
>> Add post-power-off-delay-ms property to MMC controller common.
>>
>> This property shall be used to specify delay if needed after
>> deasserting power during MMC power cycles.
>
> Please clarify with some additional information from the cover-letter,
> like "specify custom delays after MMC power off to work around
> hardware issues such as slow RC circuites on MMC VDD rails."
>
>>
>> Signed-off-by: Judith Mendez <jm@ti.com>
>> ---
>> .../devicetree/bindings/mmc/mmc-controller-common.yaml | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
>> index 3d7195e9461c3..3ff68d32a308f 100644
>> --- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
>> +++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
>> @@ -275,6 +275,14 @@ properties:
>> not available.
>> default: 10
>>
>> + post-power-off-delay-ms:
>
> For mmc-pwrseq-simple we already have "power-off-delay-us", perhaps
> better to re-use that name instead.
>
>> + description:
>> + The presence of this property indicates that the card requires a
>> + delay (in milliseconds) after power off before the next power on.
>
> Again, maybe something to indicate this is specific like "specify
> custom delays after MMC power off to work around
> hardware issues such as slow RC circuites on MMC VDD rails."
>
>> + $ref: /schemas/types.yaml#/definitions/uint32
>> + minimum: 0
>> + maximum: 10000
>
> Are the above limits needed at all?
I would like to keep the limits from minimum 1ms to 10000ms just because
likely someone will go ahead and add a huge delay and wonder why their
board just crashed. I think 10000ms or 10s is large enough, what do you
think?
...
^ permalink raw reply
* [PATCH v10 0/2] iio: health: add MAX86150 ECG and PPG biosensor driver
From: Md Shofiqul Islam @ 2026-07-17 20:11 UTC (permalink / raw)
To: linux-iio
Cc: Md Shofiqul Islam, jic23, devicetree, robh, krzk+dt, conor+dt,
andriy.shevchenko, u.kleine-koenig, joshua.crofts1, nuno.sa,
Michael.Hennerich, dlechner, linux, linux-kernel
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7047 bytes --]
Sorry for the long gap since v9. Between then and now the driver's
buffer implementation was rewritten from the kfifo-based design onto
the standard IIO hardware-trigger and triggered-buffer framework, and
I read through every open comment from every reviewer before sending
this rather than sending again too quickly.
I used AI assistance (Claude, Sonnet 5) while working through this, for
understanding kernel conventions and cross-checking against subsystem
patterns; that's disclosed via Assisted-by: Claude:claude-sonnet-5 tags
on both patches per Documentation/process/coding-assistants.rst, and
the design decisions and responsibility for what's here are mine.
Both patches now build and link cleanly (make M=drivers/iio/health),
checkpatch.pl reports 0 errors/0 warnings, and pahole confirms the
driver's private struct is 56 bytes/1 cacheline with only the expected
padding for timestamp alignment.
Testing: booted a kernel with this driver under virtme-ng/QEMU against
an i2c-stub device. Confirmed: probe correctly aborts with -ENODEV on
a part-ID mismatch (stub registers default to 0) and correctly binds
once the stub's PART_ID register is preset to 0x1E; the resulting
IIO device exposes the expected in_intensity_red_raw/in_intensity_ir_raw/
in_voltage_raw channels; direct reads on those channels time out
cleanly through the IIO_DEV_ACQUIRE_DIRECT_MODE()/regmap_read_poll_timeout()
path (i2c-stub never asserts PPG_RDY, so a ~25ms ETIMEDOUT is expected,
not a hang or crash); and module removal runs devm cleanup correctly
(SYS_CTRL read back with SHDN set after unbind, clean rmmod).
Not tested: i2c-stub has no interrupt line, so the actual
interrupt-driven path (max86150_trigger_enable(), the threaded
max86150_trigger_handler() FIFO drain, and buffer enable/disable) was
not exercised. That's the part of this series with the most new logic
and I don't have real hardware on hand to test it against; flagging
this explicitly rather than implying full coverage.
Changes since v9:
- Rewrote the buffer implementation around devm_iio_trigger_alloc() +
devm_iio_triggered_buffer_setup() instead of the kfifo buffer and
manual postenable/predisable pair. The hard-irq handler now only
reads and clears INT_STATUS1 before calling iio_trigger_poll();
the threaded trigger handler does the FIFO drain. This relies on
the trigger core's own attach/detach synchronization instead of an
explicit iio_buffer_enabled() guard or synchronize_irq(), which the
old design needed to avoid a NULL active_scan_mask race on teardown
(Sashiko, both HIGH severity findings)
- Clear the stale A_FULL status bit before arming INT_ENABLE1, and
clear stale PPG_RDY before polling in the direct-read path; both
prevent a previously-latched flag from firing against garbage state
(Sashiko HIGH; Joshua)
- Use iio_get_time_ns(indio_dev) instead of ktime_get_ns() so
timestamps respect the configured IIO clock source (Sashiko MEDIUM)
- Zero the scan buffer before each push so disabled channels don't
leak stale data (Sashiko LOW)
- Added array_size.h, err.h, types.h; added a blank line before the
iio/ include group (Andy Shevchenko, Joshua)
- Dropped the free-standing FIFO_A_FULL_VAL/PPG_SR_100HZ/ADC_RGE_16384
single-value defines; inlined the FIFO threshold at its point of use
with an explanatory comment, and listed the full set of PPG_SR
(naming the single-/double-pulse variants) and PPG_ADC_RGE register
values instead of just the one in use (Jonathan Cameron)
- Removed the unneeded __aligned(IIO_DMA_MINALIGN) on the plain I2C
FIFO read buffer -- that alignment is for the IIO DMA buffer path,
not a bounce-buffer requirement I2C opts into (Jonathan Cameron)
- Switched read_raw() to IIO_DEV_ACQUIRE_DIRECT_MODE()/
IIO_DEV_ACQUIRE_FAILED(), with the read logic pulled into a
max86150_do_read_raw() helper (Jonathan Cameron)
- Dropped irq_get_trigger_type(): the device has no register to
reconfigure interrupt polarity or type, so IRQF_ONESHOT alone is
sufficient (Jonathan Cameron)
- Checked max86150_powerdown()'s regmap calls and log failures with
dev_warn(); fixed it to use regmap_set_bits() instead of a plain
regmap_write() for the shutdown bit so it no longer clobbers the
rest of SYS_CTRL (Joshua)
- Added blank lines between each regmap write + error-check block for
readability (Joshua)
- Declared the FIFO-drain loop variable at point of use (Joshua)
- Added a datasheet-referenced comment and blank line around the
SYS_RESET self-clear delay (Joshua)
- Moved the sample_period_ns assignment next to the PPG_CONFIG1 write
it's derived from, instead of sitting among unrelated LED_PA writes
(Jonathan Cameron)
- Trimmed the redundant "get/" from regulator failure messages, since
devm_regulator_get_enable() is a single combined call (Joshua)
- Fixed the MAINTAINERS entry to sort alphabetically among the other
MAX-prefixed entries (Sashiko LOW)
- Removed the Kconfig paragraph describing the driver's channels
instead of the hardware (Joshua)
- Added the avdd-supply and vref-supply properties and renamed
vled-supply to leds-supply, to cover all four independent supply
rails in the datasheet power tree (found while re-verifying the
binding against the driver)
- Fixed the DT binding example's interrupt flag from
IRQ_TYPE_EDGE_FALLING to IRQ_TYPE_LEVEL_LOW to match the driver's
actual level-triggered interrupt handling
- Fixed .validate_trigger in iio_info to iio_validate_own_trigger();
the previous iio_trigger_validate_own_device() has its arguments in
the opposite order and belongs on iio_trigger_ops.validate_device,
where it's used correctly. Caught by actually building the module,
not just reading the diff.
- Threaded this series properly with git send-email --thread this
time (Andy Shevchenko, Krzysztof Kozlowski)
- Added Nuno Sá, Michael Hennerich and David Lechner to Cc, per
scripts/get_maintainer.pl -- this is an Analog Devices part and I'd
missed CCing ADI's own IIO maintainers on every version so far
- Part-ID mismatch now aborts probe with dev_err_probe(dev, -ENODEV,
...) instead of logging and continuing. This goes beyond the
dev_info() vs dev_warn() log-level question raised in review: a
mismatched part ID means we're either talking to the wrong device or
something on the bus is wrong, and running chip_init() writes
against an unverified chip seemed like the riskier default (Joshua)
Md Shofiqul Islam (2):
dt-bindings: iio: health: add adi,max86150
iio: health: add MAX86150 ECG and PPG biosensor driver
.../bindings/iio/health/adi,max86150.yaml | 78 ++
MAINTAINERS | 7 +
drivers/iio/health/Kconfig | 13 +
drivers/iio/health/Makefile | 1 +
drivers/iio/health/max86150.c | 691 ++++++++++++++++++
5 files changed, 790 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
create mode 100644 drivers/iio/health/max86150.c
--
2.51.1
^ permalink raw reply
* [PATCH v10 1/2] dt-bindings: iio: health: add adi,max86150
From: Md Shofiqul Islam @ 2026-07-17 20:11 UTC (permalink / raw)
To: linux-iio
Cc: Md Shofiqul Islam, jic23, devicetree, robh, krzk+dt, conor+dt,
andriy.shevchenko, u.kleine-koenig, joshua.crofts1, nuno.sa,
Michael.Hennerich, dlechner, linux, linux-kernel
In-Reply-To: <20260717201138.1078019-1-shofiqtest@gmail.com>
Add the Device Tree binding schema for the Analog Devices MAX86150
integrated biosensor, which combines two photoplethysmography (PPG)
channels (Red LED and IR LED) and one electrocardiogram (ECG) channel
in a single I2C device. Samples are buffered in a 32-entry hardware
FIFO with a configurable almost-full interrupt.
The device requires four independent supply rails per the datasheet
power tree: digital core (vdd), analog core (avdd), ECG reference
(vref), and LED anode (leds).
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
---
.../bindings/iio/health/adi,max86150.yaml | 78 +++++++++++++++++++
MAINTAINERS | 6 ++
2 files changed, 84 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
diff --git a/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml b/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
new file mode 100644
index 0000000000000..da2ff9b0ada2b
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/health/adi,max86150.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices MAX86150 ECG and PPG Biosensor
+
+maintainers:
+ - Md Shofiqul Islam <shofiqtest@gmail.com>
+
+description: |
+ The MAX86150 is an integrated biosensor SoC that combines:
+ - Two PPG (photoplethysmography) channels: Red LED and IR LED,
+ for heart rate and blood-oxygen saturation (SpO2) measurement.
+ - One ECG (electrocardiogram) channel for biopotential recording.
+
+ The device communicates over I2C at up to 400 kHz and raises an
+ active-low interrupt when the 32-entry hardware FIFO reaches its
+ configurable almost-full threshold.
+
+ Datasheet:
+ https://www.analog.com/media/en/technical-documentation/data-sheets/MAX86150.pdf
+
+properties:
+ compatible:
+ const: adi,max86150
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+ description: |
+ Active-low interrupt line. Asserted when the FIFO almost-full
+ threshold is reached or when a new PPG sample is ready.
+
+ vdd-supply:
+ description: Digital core power supply (1.8 V).
+
+ avdd-supply:
+ description: Analog core power supply (1.8 V).
+
+ vref-supply:
+ description: ECG reference voltage supply.
+
+ leds-supply:
+ description: LED anode supply, typically 3.3 V.
+
+required:
+ - compatible
+ - reg
+ - vdd-supply
+ - avdd-supply
+ - vref-supply
+ - leds-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ heart-rate@5e {
+ compatible = "adi,max86150";
+ reg = <0x5e>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&vdd_1v8>;
+ avdd-supply = <&vdd_1v8>;
+ vref-supply = <&vdd_1v8>;
+ leds-supply = <&vdd_3v3>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 3115538ce8291..189385966de82 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15705,6 +15705,12 @@ S: Orphan
F: Documentation/hwmon/max6650.rst
F: drivers/hwmon/max6650.c
+MAX86150 ECG AND PPG BIOSENSOR DRIVER
+M: Md Shofiqul Islam <shofiqtest@gmail.com>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
+
MAX9286 QUAD GMSL DESERIALIZER DRIVER
M: Jacopo Mondi <jacopo+renesas@jmondi.org>
M: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
--
2.51.1
^ permalink raw reply related
* [PATCH v10 2/2] iio: health: add MAX86150 ECG and PPG biosensor driver
From: Md Shofiqul Islam @ 2026-07-17 20:11 UTC (permalink / raw)
To: linux-iio
Cc: Md Shofiqul Islam, jic23, devicetree, robh, krzk+dt, conor+dt,
andriy.shevchenko, u.kleine-koenig, joshua.crofts1, nuno.sa,
Michael.Hennerich, dlechner, linux, linux-kernel
In-Reply-To: <20260717201138.1078019-1-shofiqtest@gmail.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 24309 bytes --]
Add a new IIO driver for the Analog Devices MAX86150 integrated
biosensor, which combines two PPG optical channels (Red/IR LED) and
one ECG biopotential channel in a single I2C device.
The device has a 32-entry hardware FIFO with a configurable almost-full
interrupt. The driver uses the standard IIO hardware-trigger and
triggered-buffer framework: a hard-irq handler reads and clears
INT_STATUS1 to de-assert the line before calling iio_trigger_poll(),
and the threaded trigger handler drains the FIFO and pushes samples,
with timestamps back-calculated from the interrupt arrival time by one
sample_period_ns per step. Relying on the trigger core's own
attach/detach synchronization avoids the need for an explicit
iio_buffer_enabled() guard or synchronize_irq() in the interrupt path.
Key implementation details:
- Part ID register (0xFF) verified against 0x1E on probe; mismatched
devices are rejected with -ENODEV so the driver cannot bind to the
wrong hardware
- Stale A_FULL and PPG_RDY status bits are cleared before arming the
interrupt or polling for a sample, so a previously-latched flag
cannot fire the handler against garbage state
- 24-bit FIFO words decoded directly from the raw byte buffer
- regmap_set_bits() / regmap_clear_bits() for single-direction writes
- Device remains in shutdown between captures to suppress LED current
- vdd, avdd, vref and leds regulators required per the datasheet power
tree
- iio_get_time_ns() used for timestamps so they respect the IIO
device's configured clock source
- A_FULL status bit used to detect FIFO exactly full (wr_ptr == rd_ptr
with OVF_COUNTER == 0) so valid samples are not silently dropped
- No IRQ trigger-type override: the device has no register to
reconfigure interrupt polarity or type, so IRQF_ONESHOT with
whatever type firmware provides is sufficient
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Suggested-by: Joshua Crofts <joshua.crofts1@gmail.com>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
---
MAINTAINERS | 1 +
drivers/iio/health/Kconfig | 13 +
drivers/iio/health/Makefile | 1 +
drivers/iio/health/max86150.c | 691 ++++++++++++++++++++++++++++++++++
4 files changed, 706 insertions(+)
create mode 100644 drivers/iio/health/max86150.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 189385966de82..5e266c03bda6f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15710,6 +15710,7 @@ M: Md Shofiqul Islam <shofiqtest@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
+F: drivers/iio/health/max86150.c
MAX9286 QUAD GMSL DESERIALIZER DRIVER
M: Jacopo Mondi <jacopo+renesas@jmondi.org>
diff --git a/drivers/iio/health/Kconfig b/drivers/iio/health/Kconfig
index a89f3abf11f4a..7438cdfe4238f 100644
--- a/drivers/iio/health/Kconfig
+++ b/drivers/iio/health/Kconfig
@@ -62,4 +62,17 @@ config MAX30102
endmenu
+config MAX86150
+ tristate "MAX86150 ECG and PPG biosensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select REGMAP_I2C
+ help
+ Say Y here to enable support for the Maxim MAX86150 combined
+ ECG and photoplethysmography (PPG) biosensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called max86150.
+
endmenu
diff --git a/drivers/iio/health/Makefile b/drivers/iio/health/Makefile
index 9108171122588..04fc73c584449 100644
--- a/drivers/iio/health/Makefile
+++ b/drivers/iio/health/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_AFE4403) += afe4403.o
obj-$(CONFIG_AFE4404) += afe4404.o
obj-$(CONFIG_MAX30100) += max30100.o
obj-$(CONFIG_MAX30102) += max30102.o
+obj-$(CONFIG_MAX86150) += max86150.o
diff --git a/drivers/iio/health/max86150.c b/drivers/iio/health/max86150.c
new file mode 100644
index 0000000000000..47d96570a95fc
--- /dev/null
+++ b/drivers/iio/health/max86150.c
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MAX86150 combined ECG and PPG biosensor driver
+ *
+ * Copyright (C) 2026 Md Shofiqul Islam <shofiqtest@gmail.com>
+ *
+ * The MAX86150 integrates two PPG optical channels (Red/IR LED) and one
+ * ECG biopotential channel in a single I2C device. Data is captured
+ * through a 32-entry hardware FIFO with a configurable almost-full
+ * interrupt, making it well-suited for continuous monitoring with a
+ * low-power host.
+ *
+ * Datasheet:
+ * https://www.analog.com/media/en/technical-documentation/data-sheets/MAX86150.pdf
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/device/devres.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define MAX86150_REG_INT_STATUS1 0x00
+#define MAX86150_REG_INT_STATUS2 0x01
+#define MAX86150_REG_INT_ENABLE1 0x02
+#define MAX86150_REG_INT_ENABLE2 0x03
+#define MAX86150_REG_FIFO_WR_PTR 0x04
+#define MAX86150_REG_OVF_COUNTER 0x05
+#define MAX86150_REG_FIFO_RD_PTR 0x06
+#define MAX86150_REG_FIFO_DATA 0x07
+#define MAX86150_REG_FIFO_CONFIG 0x08
+#define MAX86150_REG_FIFO_DCTRL1 0x09
+#define MAX86150_REG_FIFO_DCTRL2 0x0A
+#define MAX86150_REG_SYS_CTRL 0x0D
+#define MAX86150_REG_PPG_CONFIG1 0x10
+#define MAX86150_REG_PPG_CONFIG2 0x11
+#define MAX86150_REG_LED1_PA 0x14
+#define MAX86150_REG_LED2_PA 0x15
+#define MAX86150_REG_ECG_CONFIG1 0x3C
+#define MAX86150_REG_ECG_CONFIG3 0x3E
+#define MAX86150_REG_PART_ID 0xFF
+
+#define MAX86150_PART_ID_VAL 0x1E
+
+#define MAX86150_INT_A_FULL BIT(7)
+#define MAX86150_INT_PPG_RDY BIT(6)
+
+#define MAX86150_SYS_SHDN BIT(1)
+#define MAX86150_SYS_RESET BIT(0)
+
+#define MAX86150_FIFO_SMP_AVE GENMASK(7, 5)
+#define MAX86150_FIFO_ROLLOVER_EN BIT(4)
+#define MAX86150_FIFO_A_FULL GENMASK(3, 0)
+
+#define MAX86150_FD_NONE 0x0
+#define MAX86150_FD_LED1 0x1
+#define MAX86150_FD_LED2 0x2
+#define MAX86150_FD_ECG 0x9
+#define MAX86150_FIFO_FD1 GENMASK(3, 0)
+#define MAX86150_FIFO_FD2 GENMASK(7, 4)
+#define MAX86150_FIFO_FD3 GENMASK(3, 0)
+#define MAX86150_FIFO_FD4 GENMASK(7, 4)
+
+#define MAX86150_PPG_ADC_RGE GENMASK(7, 6)
+#define MAX86150_PPG_SR GENMASK(5, 1)
+
+/* PPG ADC full-scale range (ADC_RGE field of PPG_CONFIG1) */
+#define MAX86150_PPG_ADC_RGE_4096 0 /* 4096 nA */
+#define MAX86150_PPG_ADC_RGE_8192 1 /* 8192 nA */
+#define MAX86150_PPG_ADC_RGE_16384 2 /* 16384 nA */
+#define MAX86150_PPG_ADC_RGE_32768 3 /* 32768 nA */
+
+/* PPG sample rate (SR field of PPG_CONFIG1) - single-pulse variants */
+#define MAX86150_PPG_SR_SP_10HZ 0
+#define MAX86150_PPG_SR_SP_20HZ 1
+#define MAX86150_PPG_SR_SP_50HZ 2
+#define MAX86150_PPG_SR_SP_84HZ 3
+#define MAX86150_PPG_SR_SP_100HZ 4
+#define MAX86150_PPG_SR_SP_200HZ 5
+#define MAX86150_PPG_SR_SP_400HZ 6
+#define MAX86150_PPG_SR_SP_800HZ 7
+#define MAX86150_PPG_SR_SP_1000HZ 8
+#define MAX86150_PPG_SR_SP_1600HZ 9
+#define MAX86150_PPG_SR_SP_3200HZ 10
+/* Double-pulse variants (two LED pulses averaged per sample) */
+#define MAX86150_PPG_SR_DP_10HZ 11
+#define MAX86150_PPG_SR_DP_20HZ 12
+#define MAX86150_PPG_SR_DP_50HZ 13
+#define MAX86150_PPG_SR_DP_84HZ 14
+#define MAX86150_PPG_SR_DP_100HZ 15
+#define MAX86150_PPG_SR_DP_200HZ 16
+#define MAX86150_PPG_SR_DP_400HZ 17
+#define MAX86150_PPG_SR_DP_800HZ 18
+#define MAX86150_PPG_SR_DP_1000HZ 19
+#define MAX86150_PPG_SR_DP_1600HZ 20
+#define MAX86150_PPG_SR_DP_3200HZ 21
+
+/* LED pulse amplitude: 0x00 = 0 mA, step ~0.8 mA, 0x3F ~= 50 mA, 0xFF ~= 200 mA */
+
+#define MAX86150_FIFO_DEPTH 32
+#define MAX86150_BYTES_PER_SLOT 3
+#define MAX86150_NUM_SLOTS 3
+#define MAX86150_SAMPLE_BYTES (MAX86150_NUM_SLOTS * MAX86150_BYTES_PER_SLOT)
+
+/* Samples available in the FIFO when the A_FULL interrupt fires */
+#define MAX86150_FIFO_A_FULL_SAMPLES 17
+
+#define MAX86150_LED_PA_DEFAULT 0x3F
+
+enum max86150_scan_idx {
+ MAX86150_IDX_PPG_RED,
+ MAX86150_IDX_PPG_IR,
+ MAX86150_IDX_ECG,
+ MAX86150_IDX_TS,
+};
+
+/**
+ * struct max86150_data - driver private state
+ * @regmap: register map for this device
+ * @trig: IIO hardware trigger backed by the device interrupt line
+ * @sample_period_ns: sample period in nanoseconds (set from configured rate)
+ * @fifo_raw: scratch buffer for regmap_noinc_read() FIFO bursts; kept
+ * in struct (heap) rather than on the stack, since stack
+ * memory isn't guaranteed DMA-safe (e.g. CONFIG_VMAP_STACK)
+ * and some I2C host controllers DMA the read buffer
+ * @scan: IIO push buffer; channels[] packed per active_scan_mask,
+ * with a trailing aligned_s64 slot for the timestamp
+ */
+struct max86150_data {
+ struct regmap *regmap;
+ struct iio_trigger *trig;
+ u32 sample_period_ns;
+ u8 fifo_raw[MAX86150_SAMPLE_BYTES];
+ IIO_DECLARE_DMA_BUFFER_WITH_TS(s32, scan, MAX86150_NUM_SLOTS);
+};
+
+static const struct iio_chan_spec max86150_channels[] = {
+ {
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_RED,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = MAX86150_IDX_PPG_RED,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 19,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ },
+ {
+ .type = IIO_INTENSITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_LIGHT_IR,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = MAX86150_IDX_PPG_IR,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 19,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = MAX86150_IDX_ECG,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 18,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(MAX86150_IDX_TS),
+};
+
+static const struct regmap_config max86150_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX86150_REG_PART_ID,
+};
+
+static int max86150_read_one_sample(struct max86150_data *data,
+ u32 *ppg_red, u32 *ppg_ir, s32 *ecg)
+{
+ int ret;
+
+ ret = regmap_noinc_read(data->regmap, MAX86150_REG_FIFO_DATA,
+ data->fifo_raw, MAX86150_SAMPLE_BYTES);
+ if (ret)
+ return ret;
+
+ *ppg_red = (data->fifo_raw[0] & 0x07) << 16 |
+ data->fifo_raw[1] << 8 | data->fifo_raw[2];
+ *ppg_ir = (data->fifo_raw[3] & 0x07) << 16 |
+ data->fifo_raw[4] << 8 | data->fifo_raw[5];
+ *ecg = sign_extend32((data->fifo_raw[6] & 0x03) << 16 |
+ data->fifo_raw[7] << 8 | data->fifo_raw[8], 17);
+ return 0;
+}
+
+/*
+ * Take the device out of shutdown, reset the FIFO pointers, wait for the
+ * first PPG sample, and read it back. Always returns the device to
+ * shutdown before returning, whether or not the read succeeded.
+ */
+static int max86150_do_read_raw(struct max86150_data *data,
+ u32 *ppg_red, u32 *ppg_ir, s32 *ecg)
+{
+ unsigned int ppg_rdy_status;
+ int ret;
+
+ ret = regmap_clear_bits(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_SHDN);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_WR_PTR, 0);
+ if (ret)
+ goto out_shdn;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_OVF_COUNTER, 0);
+ if (ret)
+ goto out_shdn;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_RD_PTR, 0);
+ if (ret)
+ goto out_shdn;
+
+ /*
+ * Clear stale PPG_RDY from a previous session; reading
+ * INT_STATUS1 de-asserts any pending flags so the poll
+ * below waits for a genuinely new sample.
+ */
+ ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1,
+ &ppg_rdy_status);
+ if (ret)
+ goto out_shdn;
+
+ /*
+ * Poll PPG_RDY rather than sleeping a fixed interval — the
+ * internal oscillator may start slower than nominal. 25 ms
+ * covers more than two 100 Hz sample periods.
+ */
+ ret = regmap_read_poll_timeout(data->regmap,
+ MAX86150_REG_INT_STATUS1,
+ ppg_rdy_status,
+ ppg_rdy_status & MAX86150_INT_PPG_RDY,
+ 1000, 25000);
+ if (ret)
+ goto out_shdn;
+
+ ret = max86150_read_one_sample(data, ppg_red, ppg_ir, ecg);
+
+out_shdn:
+ regmap_set_bits(data->regmap, MAX86150_REG_SYS_CTRL, MAX86150_SYS_SHDN);
+ return ret;
+}
+
+static int max86150_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct max86150_data *data = iio_priv(indio_dev);
+ u32 ppg_red, ppg_ir;
+ s32 ecg;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW: {
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ ret = max86150_do_read_raw(data, &ppg_red, &ppg_ir, &ecg);
+ if (ret)
+ return ret;
+
+ switch (chan->scan_index) {
+ case MAX86150_IDX_PPG_RED:
+ *val = ppg_red;
+ break;
+ case MAX86150_IDX_PPG_IR:
+ *val = ppg_ir;
+ break;
+ case MAX86150_IDX_ECG:
+ *val = ecg;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return IIO_VAL_INT;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info max86150_iio_info = {
+ .read_raw = max86150_read_raw,
+ .validate_trigger = iio_validate_own_trigger,
+};
+
+static int max86150_trigger_disable(struct max86150_data *data)
+{
+ int ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_INT_ENABLE1, 0);
+ if (ret)
+ return ret;
+ return regmap_set_bits(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_SHDN);
+}
+
+static int max86150_trigger_enable(struct max86150_data *data)
+{
+ unsigned int dummy;
+ int ret;
+
+ ret = regmap_clear_bits(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_SHDN);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_WR_PTR, 0);
+ if (ret)
+ goto err_shdn;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_OVF_COUNTER, 0);
+ if (ret)
+ goto err_shdn;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_RD_PTR, 0);
+ if (ret)
+ goto err_shdn;
+
+ /*
+ * Clear a stale A_FULL latched from before this trigger was enabled;
+ * otherwise arming INT_ENABLE1 below fires the handler immediately
+ * against a FIFO state that was never actually seen as full.
+ */
+ ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1, &dummy);
+ if (ret)
+ goto err_shdn;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_INT_ENABLE1,
+ MAX86150_INT_A_FULL);
+ if (ret)
+ goto err_shdn;
+ return 0;
+
+err_shdn:
+ regmap_set_bits(data->regmap, MAX86150_REG_SYS_CTRL, MAX86150_SYS_SHDN);
+ return ret;
+}
+
+static int max86150_set_trigger_state(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct max86150_data *data = iio_priv(indio_dev);
+
+ if (state)
+ return max86150_trigger_enable(data);
+ return max86150_trigger_disable(data);
+}
+
+static const struct iio_trigger_ops max86150_trigger_ops = {
+ .set_trigger_state = max86150_set_trigger_state,
+ .validate_device = iio_trigger_validate_own_device,
+};
+
+/*
+ * Threaded IRQ handler: reads and clears INT_STATUS1 to de-assert the
+ * hardware interrupt line BEFORE iio_trigger_poll() re-enables it. This
+ * prevents an IRQ storm on level-triggered lines where the line would
+ * remain asserted until max86150_trigger_handler() ran later in its own
+ * kthread — after IRQF_ONESHOT had already unmasked the IRQ.
+ */
+static irqreturn_t max86150_irq_handler(int irq, void *private)
+{
+ struct iio_trigger *trig = private;
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct max86150_data *data = iio_priv(indio_dev);
+ unsigned int status;
+ int ret;
+
+ ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1, &status);
+ if (ret || !(status & MAX86150_INT_A_FULL))
+ return IRQ_NONE;
+
+ iio_trigger_poll(trig);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t max86150_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *idev = pf->indio_dev;
+ struct max86150_data *data = iio_priv(idev);
+ unsigned int wr_ptr, rd_ptr, ovf, n_avail;
+ u32 ppg_red, ppg_ir;
+ s32 ecg;
+ s64 t_drain = 0;
+ int ret;
+
+ /*
+ * INT_STATUS1 was already read (and the interrupt de-asserted) by
+ * max86150_irq_handler(). Read only the FIFO pointers here.
+ */
+ ret = regmap_read(data->regmap, MAX86150_REG_FIFO_WR_PTR, &wr_ptr);
+ if (ret)
+ goto done;
+ ret = regmap_read(data->regmap, MAX86150_REG_FIFO_RD_PTR, &rd_ptr);
+ if (ret)
+ goto done;
+ ret = regmap_read(data->regmap, MAX86150_REG_OVF_COUNTER, &ovf);
+ if (ret)
+ goto done;
+
+ if (ovf > 0) {
+ n_avail = MAX86150_FIFO_DEPTH;
+ t_drain = iio_get_time_ns(idev);
+ } else {
+ n_avail = (wr_ptr - rd_ptr) & (MAX86150_FIFO_DEPTH - 1);
+ /*
+ * wr_ptr == rd_ptr with no overflow means either empty or
+ * exactly 32 slots filled (pointer wrapped). Since this
+ * handler is only called when A_FULL fired, the FIFO must
+ * be full — treat as 32 available.
+ */
+ if (n_avail == 0)
+ n_avail = MAX86150_FIFO_DEPTH;
+ }
+
+ for (unsigned int i = 0; i < n_avail; i++) {
+ unsigned int j = 0;
+ s64 ts;
+
+ if (ovf > 0)
+ ts = t_drain -
+ (s64)(n_avail - 1 - i) * data->sample_period_ns;
+ else
+ ts = pf->timestamp +
+ ((s64)i - (MAX86150_FIFO_A_FULL_SAMPLES - 1)) *
+ data->sample_period_ns;
+
+ ret = max86150_read_one_sample(data, &ppg_red, &ppg_ir, &ecg);
+ if (ret)
+ break;
+
+ memset(data->scan, 0, sizeof(data->scan));
+
+ if (test_bit(MAX86150_IDX_PPG_RED, idev->active_scan_mask))
+ data->scan[j++] = ppg_red;
+ if (test_bit(MAX86150_IDX_PPG_IR, idev->active_scan_mask))
+ data->scan[j++] = ppg_ir;
+ if (test_bit(MAX86150_IDX_ECG, idev->active_scan_mask))
+ data->scan[j++] = ecg;
+
+ iio_push_to_buffers_with_timestamp(idev, data->scan, ts);
+ }
+
+done:
+ iio_trigger_notify_done(idev->trig);
+ return IRQ_HANDLED;
+}
+
+static void max86150_powerdown(void *arg)
+{
+ struct max86150_data *data = arg;
+ struct device *dev = regmap_get_device(data->regmap);
+ int ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_INT_ENABLE1, 0);
+ if (ret)
+ dev_warn(dev, "Failed to disable interrupts: %d\n", ret);
+
+ ret = regmap_set_bits(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_SHDN);
+ if (ret)
+ dev_warn(dev, "Failed to shut down device: %d\n", ret);
+}
+
+static int max86150_chip_init(struct max86150_data *data)
+{
+ int ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_RESET);
+ if (ret)
+ return ret;
+
+ /* SYS_RESET self-clears within 1 ms (datasheet SYS_CTRL register) */
+ fsleep(10 * USEC_PER_MSEC);
+
+ /*
+ * FIFO_A_FULL holds (FIFO depth - samples available), i.e. how many
+ * free slots remain when the interrupt should fire.
+ */
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_CONFIG,
+ MAX86150_FIFO_ROLLOVER_EN |
+ FIELD_PREP(MAX86150_FIFO_A_FULL,
+ MAX86150_FIFO_DEPTH -
+ MAX86150_FIFO_A_FULL_SAMPLES));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_DCTRL1,
+ FIELD_PREP(MAX86150_FIFO_FD1, MAX86150_FD_LED1) |
+ FIELD_PREP(MAX86150_FIFO_FD2, MAX86150_FD_LED2));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_FIFO_DCTRL2,
+ FIELD_PREP(MAX86150_FIFO_FD3, MAX86150_FD_ECG) |
+ FIELD_PREP(MAX86150_FIFO_FD4, MAX86150_FD_NONE));
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_PPG_CONFIG1,
+ FIELD_PREP(MAX86150_PPG_ADC_RGE,
+ MAX86150_PPG_ADC_RGE_16384) |
+ FIELD_PREP(MAX86150_PPG_SR,
+ MAX86150_PPG_SR_SP_100HZ));
+ if (ret)
+ return ret;
+
+ data->sample_period_ns = 10000000; /* matches MAX86150_PPG_SR_SP_100HZ above */
+
+ ret = regmap_write(data->regmap, MAX86150_REG_LED1_PA,
+ MAX86150_LED_PA_DEFAULT);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, MAX86150_REG_LED2_PA,
+ MAX86150_LED_PA_DEFAULT);
+ if (ret)
+ return ret;
+
+ return regmap_write(data->regmap, MAX86150_REG_SYS_CTRL,
+ MAX86150_SYS_SHDN);
+}
+
+static int max86150_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct iio_dev *indio_dev;
+ struct max86150_data *data;
+ unsigned int part_id;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+
+ ret = devm_regulator_get_enable(dev, "vdd");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable vdd supply\n");
+
+ ret = devm_regulator_get_enable(dev, "avdd");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable avdd supply\n");
+
+ ret = devm_regulator_get_enable(dev, "vref");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable vref supply\n");
+
+ ret = devm_regulator_get_enable(dev, "leds");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable leds supply\n");
+
+ data->regmap = devm_regmap_init_i2c(client, &max86150_regmap_config);
+ if (IS_ERR(data->regmap))
+ return dev_err_probe(dev, PTR_ERR(data->regmap),
+ "Failed to init regmap\n");
+
+ ret = regmap_read(data->regmap, MAX86150_REG_PART_ID, &part_id);
+ if (ret)
+ return dev_err_probe(dev, ret, "Cannot read part ID\n");
+
+ if (part_id != MAX86150_PART_ID_VAL)
+ return dev_err_probe(dev, -ENODEV,
+ "Unexpected part ID 0x%02x (expected 0x%02x)\n",
+ part_id, MAX86150_PART_ID_VAL);
+
+ ret = max86150_chip_init(data);
+ if (ret)
+ return dev_err_probe(dev, ret, "Chip initialisation failed\n");
+
+ ret = devm_add_action_or_reset(dev, max86150_powerdown, data);
+ if (ret)
+ return ret;
+
+ indio_dev->name = "max86150";
+ indio_dev->channels = max86150_channels;
+ indio_dev->num_channels = ARRAY_SIZE(max86150_channels);
+ indio_dev->info = &max86150_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ if (client->irq > 0) {
+ data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
+ indio_dev->name,
+ iio_device_id(indio_dev));
+ if (!data->trig)
+ return -ENOMEM;
+
+ data->trig->ops = &max86150_trigger_ops;
+ iio_trigger_set_drvdata(data->trig, indio_dev);
+
+ /*
+ * The device only ever drives an active-low interrupt line;
+ * there is no register to reconfigure its polarity or type,
+ * so the trigger type from firmware needs no help here.
+ */
+ ret = devm_request_threaded_irq(dev, client->irq,
+ NULL,
+ max86150_irq_handler,
+ IRQF_ONESHOT,
+ "max86150", data->trig);
+ if (ret)
+ return ret;
+
+ ret = devm_iio_trigger_register(dev, data->trig);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to register trigger\n");
+ }
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+ iio_pollfunc_store_time,
+ max86150_trigger_handler,
+ NULL);
+ if (ret)
+ return ret;
+
+ /*
+ * Set the default trigger AFTER buffer setup succeeds. Setting it
+ * before would leak the iio_trigger_get() reference if buffer setup
+ * failed: INDIO_BUFFER_TRIGGERED is not set on that path so
+ * iio_device_release() skips iio_trigger_put().
+ */
+ if (data->trig)
+ indio_dev->trig = iio_trigger_get(data->trig);
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct i2c_device_id max86150_id[] = {
+ { "max86150" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max86150_id);
+
+static const struct of_device_id max86150_of_match[] = {
+ { .compatible = "adi,max86150" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max86150_of_match);
+
+static struct i2c_driver max86150_driver = {
+ .driver = {
+ .name = "max86150",
+ .of_match_table = max86150_of_match,
+ },
+ .probe = max86150_probe,
+ .id_table = max86150_id,
+};
+module_i2c_driver(max86150_driver);
+
+MODULE_AUTHOR("Md Shofiqul Islam <shofiqtest@gmail.com>");
+MODULE_DESCRIPTION("MAX86150 ECG and PPG biosensor driver");
+MODULE_LICENSE("GPL");
--
2.51.1
^ permalink raw reply related
* [PATCH v2 1/1] dt-bindings: soc: imx-iomuxc-gpr: allow bridge@18 as child node
From: Frank.Li @ 2026-07-17 20:15 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
Peng Fan,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
open list
Cc: imx
From: Frank Li <Frank.Li@nxp.com>
The legacy i.MX6SX (>15 year) SoC imx-iomuxc-gpr contains one LDB_CTRL
register. Allow the LVDS Display Bridge(LDB) child node under
imx-iomuxc-gpr.
Fix below CHECK_DTBS warnings:
arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dtb: syscon@20e4000 (fsl,imx6sx-iomuxc-gpr): '#address-cells', '#size-cells', 'bridge@18' do not match any of the regexes: '^ipu[12]_csi[01]_mux$', '^pinctrl-[0-9]+$
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change in v2
- remove status = "disabled" at example
---
.../bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
index 721a67e84c137..e1fbdc7e4e057 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -47,10 +47,21 @@ properties:
reg:
maxItems: 1
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 1
+
mux-controller:
type: object
$ref: /schemas/mux/reg-mux.yaml
+ bridge@18:
+ type: object
+ $ref: /schemas/display/bridge/fsl,ldb.yaml#
+ unevaluatedProperties: false
+
patternProperties:
"^ipu[12]_csi[01]_mux$":
type: object
@@ -67,6 +78,18 @@ allOf:
patternProperties:
'^ipu[12]_csi[01]_mux$': false
+ - if:
+ properties:
+ compatible:
+ not:
+ contains:
+ const: fsl,imx6sx-iomuxc-gpr
+ then:
+ properties:
+ bridge@18: false
+ '#address-cells': false
+ '#size-cells': false
+
additionalProperties: false
required:
@@ -87,4 +110,39 @@ examples:
};
};
+ - |
+ #include <dt-bindings/clock/imx6sx-clock.h>
+
+ syscon@20e4000 {
+ compatible = "fsl,imx6sx-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon", "simple-mfd";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x020e4000 0x4000>;
+
+ bridge@18 {
+ compatible = "fsl,imx6sx-ldb";
+ reg = <0x18 0x4>;
+ clocks = <&clks IMX6SX_CLK_LDB_DI0>;
+ clock-names = "ldb";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ };
+ };
+ };
+ };
+ };
...
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v10 1/2] dt-bindings: iio: health: add adi,max86150
From: sashiko-bot @ 2026-07-17 20:20 UTC (permalink / raw)
To: Md Shofiqul Islam; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260717201138.1078019-2-shofiqtest@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `interrupts` property is missing from the `required` list.
--
--- Patch [1]: [PATCH v10 1/2] dt-bindings: iio: health: add adi,max86150 ---
commit 6596564838aa000e36be829746bacd2e720d88d8
Author: Md Shofiqul Islam <shofiqtest@gmail.com>
dt-bindings: iio: health: add adi,max86150
This commit adds the Device Tree binding schema for the Analog Devices
MAX86150 integrated biosensor. It outlines the configuration for the
I2C device, including supply rails and a configurable interrupt for
the hardware FIFO.
> diff --git a/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml b/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
> new file mode 100644
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/health/adi,max86150.yaml
[ ... ]
> +required:
> + - compatible
> + - reg
> + - vdd-supply
> + - avdd-supply
> + - vref-supply
> + - leds-supply
[Severity: Medium]
Should the interrupts property be included in this required list?
The commit message notes that the device raises an interrupt when the
hardware FIFO reaches its almost-full threshold. If the interrupts
property is omitted from the required list, device trees without it
will incorrectly pass schema validation, potentially leading to
runtime failures where the driver cannot receive interrupts to drain
the buffer.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717201138.1078019-1-shofiqtest@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v10 2/2] iio: health: add MAX86150 ECG and PPG biosensor driver
From: sashiko-bot @ 2026-07-17 20:30 UTC (permalink / raw)
To: Md Shofiqul Islam; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260717201138.1078019-3-shofiqtest@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The driver uses hallucinated locking macros causing a build failure, and omits the mandatory lock release.
- [High] The I2C read buffer `fifo_raw` is not cacheline aligned, violating DMA API requirements.
- [High] The threaded IRQ handler incorrectly calls a hardirq-only IIO trigger poll function.
- [Low] The i2c_device_id array is missing named initializers.
--
--- Patch [2]: [PATCH v10 2/2] iio: health: add MAX86150 ECG and PPG biosensor driver ---
commit b6c51e5d5e6b5f625bd2546556d36647cd05b62e
Author: Md Shofiqul Islam <shofiqtest@gmail.com>
iio: health: add MAX86150 ECG and PPG biosensor driver
This commit adds a new IIO driver for the Analog Devices MAX86150
combined ECG and PPG biosensor. It supports hardware FIFO captures via
a threaded trigger handler.
> diff --git a/drivers/iio/health/max86150.c b/drivers/iio/health/max86150.c
> new file mode 100644
> index 0000000000000..47d96570a95fc
> --- /dev/null
> +++ b/drivers/iio/health/max86150.c
[ ... ]
> +struct max86150_data {
> + struct regmap *regmap;
> + struct iio_trigger *trig;
> + u32 sample_period_ns;
> + u8 fifo_raw[MAX86150_SAMPLE_BYTES];
[Severity: High]
Since this array is the target of regmap_noinc_read() and some I2C host
controllers use DMA for bulk reads, should this buffer be cacheline aligned?
Sharing a cacheline with sample_period_ns and trig can lead to silent
corruption if the CPU accesses them concurrently during a DMA transfer.
> + IIO_DECLARE_DMA_BUFFER_WITH_TS(s32, scan, MAX86150_NUM_SLOTS);
> +};
[ ... ]
> +static int max86150_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct max86150_data *data = iio_priv(indio_dev);
> + u32 ppg_red, ppg_ir;
> + s32 ecg;
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW: {
> + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
> +
> + if (IIO_DEV_ACQUIRE_FAILED(claim))
> + return -EBUSY;
[Severity: High]
Do the IIO_DEV_ACQUIRE_DIRECT_MODE and IIO_DEV_ACQUIRE_FAILED macros
exist in the IIO framework? If these are replaced with the standard
iio_device_claim_direct() function, does this function also need
corresponding iio_device_release_direct() calls on its return paths to
prevent deadlocking the IIO device state?
> +
> + ret = max86150_do_read_raw(data, &ppg_red, &ppg_ir, &ecg);
[ ... ]
> +static irqreturn_t max86150_irq_handler(int irq, void *private)
> +{
> + struct iio_trigger *trig = private;
> + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> + struct max86150_data *data = iio_priv(indio_dev);
> + unsigned int status;
> + int ret;
> +
> + ret = regmap_read(data->regmap, MAX86150_REG_INT_STATUS1, &status);
> + if (ret || !(status & MAX86150_INT_A_FULL))
> + return IRQ_NONE;
> +
> + iio_trigger_poll(trig);
[Severity: High]
Since this handler is registered as the thread_fn in devm_request_threaded_irq
with a NULL hardirq handler, does calling iio_trigger_poll() here violate
locking rules? iio_trigger_poll() expects to run in hardirq context. Should
this use iio_trigger_poll_nested() instead?
> + return IRQ_HANDLED;
> +}
[ ... ]
> +static const struct i2c_device_id max86150_id[] = {
> + { "max86150" },
[Severity: Low]
Does the I2C subsystem API require initialized arrays of type
struct i2c_device_id to use named initializers? Using named initializers
such as { .name = "max86150" } ensures compliance with subsystem guidelines.
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, max86150_id);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717201138.1078019-1-shofiqtest@gmail.com?part=2
^ permalink raw reply
* [PATCH v7] arm64: dts: s32g: Add GPR syscon region
From: Jared Kangas @ 2026-07-17 20:33 UTC (permalink / raw)
To: Chester Lin, Matthias Brugger, Ghennadi Procopciuc,
NXP S32 Linux Team, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, imx, devicetree, linux-kernel, Dan Carpenter,
Jared Kangas, Dan Carpenter
From: Dan Carpenter <error27@gmail.com>
Add the GPR syscon region for the s32 chipset.
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
[jkangas@redhat.com: GPR syscon resized from 0x3000 to 0x100]
Tested-by: Jared Kangas <jkangas@redhat.com>
Signed-off-by: Jared Kangas <jkangas@redhat.com>
---
Revision of Dan's v6 patch based on discussion in [1] to avoid a panic
when reading the debugfs regmap's registers file.
[1]: https://lore.kernel.org/all/aej2X2Gp-UI3Vmvo@rh-jkangas-kernel/
v7: Shrink gpr size from 0x3000 -> 0x100, add 'arm64:' prefix to subject
v6: no change
v5: no change
v4: no change
v3: no change
v2: Remove #address-cells and #size-cells
---
arch/arm64/boot/dts/freescale/s32g2.dtsi | 6 ++++++
arch/arm64/boot/dts/freescale/s32g3.dtsi | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 809019ea0e299..81280ec6b07a9 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -325,6 +325,11 @@ usdhc0-200mhz-grp4 {
};
};
+ gpr: syscon@4007c000 {
+ compatible = "nxp,s32g2-gpr", "syscon";
+ reg = <0x4007c000 0x100>;
+ };
+
ocotp: nvmem@400a4000 {
compatible = "nxp,s32g2-ocotp";
reg = <0x400a4000 0x400>;
@@ -795,6 +800,7 @@ gmac0: ethernet@4033c000 {
compatible = "nxp,s32g2-dwmac";
reg = <0x4033c000 0x2000>, /* gmac IP */
<0x4007c004 0x4>; /* GMAC_0_CTRL_STS */
+ nxp,phy-sel = <&gpr 0x4>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
index 22e80fc03f9c7..da35083a5e0e5 100644
--- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -383,6 +383,11 @@ usdhc0-200mhz-grp4 {
};
};
+ gpr: syscon@4007c000 {
+ compatible = "nxp,s32g3-gpr", "syscon";
+ reg = <0x4007c000 0x100>;
+ };
+
ocotp: nvmem@400a4000 {
compatible = "nxp,s32g3-ocotp", "nxp,s32g2-ocotp";
reg = <0x400a4000 0x400>;
@@ -874,6 +879,7 @@ gmac0: ethernet@4033c000 {
compatible = "nxp,s32g2-dwmac";
reg = <0x4033c000 0x2000>, /* gmac IP */
<0x4007c004 0x4>; /* GMAC_0_CTRL_STS */
+ nxp,phy-sel = <&gpr 0x4>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
---
base-commit: fce2dfa773ced15f27dd27cd0b482a7473cdcf2a
change-id: 20260717-upstream-s32g-gpr-syscon-75f926f868d4
Best regards,
--
Jared Kangas <jkangas@redhat.com>
^ permalink raw reply related
* [PATCH v2 0/9] drm/msm: Support for Eliza GPU
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Konrad Dybcio, Dmitry Baryshkov,
Krzysztof Kozlowski, Gaurav Kohli
Adreno 722 found in Eliza chipset belongs to the A7x Gen1 family. It is
derived from A730 and shares the same IP-level configurations: HWCG
registers, protected registers, GBIF CX registers and gmu_cgc_mode.
Major differences include smaller cache/core counts, 1MB GMEM, no
Concurrent Binning & LPAC support. Some of the peripheral blocks like
RSCC are from A740 that resulted in updates to RSC layout.
The first few patches that updates driver and dt binding docs are for
Rob Clark and the remaining devicetree bits are for Bjorn to pick up.
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
Changes in v2:
- Add a new patch for GPU passive cooling
- Rename firmwares to gen717*
- Capture trailers
- Link to v1: https://lore.kernel.org/r/20260705-eliza-gpu-v1-0-c9f1354dbd29@oss.qualcomm.com
---
Abel Vesa (1):
arm64: dts: qcom: eliza: Add GPU SMMU node
Akhil P Oommen (2):
drm/msm/a6xx: Rename GBIF_CX_CONFIG to a A6XX- variant register
dt-bindings: arm-smmu: Document GPU SMMU for Eliza SoC
Gaurav Kohli (1):
arm64: dts: qcom: eliza: Add GPU cooling
Puranam V G Tejaswi (5):
drm/msm/a6xx: Fix RBBM_CLOCK_CNTL3_TP0 value in a730_hwcg
drm/msm/a6xx: Add Adreno 722 support
dt-bindings: display/msm: Document Adreno 722 GPU and GMU
arm64: dts: qcom: eliza: Add GPU nodes
arm64: dts: qcom: eliza-mtp: Enable Adreno A722 GPU
.../devicetree/bindings/display/msm/gmu.yaml | 1 +
.../devicetree/bindings/display/msm/gpu.yaml | 1 +
.../devicetree/bindings/iommu/arm,smmu.yaml | 2 +
arch/arm64/boot/dts/qcom/eliza-mtp.dts | 8 +
arch/arm64/boot/dts/qcom/eliza.dtsi | 209 +++++++++-
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 38 +-
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 17 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 81 +++-
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 5 +
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 2 +-
.../gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h | 428 +++++++++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 +
drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 2 +-
14 files changed, 773 insertions(+), 30 deletions(-)
---
base-commit: a9498e40e3e314ade387d3ab0d5cb14f0f3aa1ad
change-id: 20260704-eliza-gpu-eccf1946cb3c
prerequisite-message-id: <20260609-b4-eliza_mm_cc_v6-v6-0-17df09e5940c@oss.qualcomm.com>
prerequisite-patch-id: ecae5e45a33a79ec3f500e3f318e3a0129fddfb7
prerequisite-patch-id: 19fe32e5af810250eef42dab488c982ef70c055c
prerequisite-patch-id: 60dde5421adbc86f355b4899bedd0d7a1a0c4e5e
prerequisite-patch-id: 58c9dbb18795c662ea22c3a82b07d6465f604e08
prerequisite-patch-id: 0c6e220ecf2b42776f990ea5b98ba4ee97d229ee
prerequisite-patch-id: 0e0bed1091d12c102e2542b1c2931f61a543f2b0
prerequisite-patch-id: c0f22b4ff0bb79935848dde50c524f6063011ebb
Best regards,
--
Akhil P Oommen <akhilpo@oss.qualcomm.com>
^ permalink raw reply
* [PATCH v2 1/9] drm/msm/a6xx: Fix RBBM_CLOCK_CNTL3_TP0 value in a730_hwcg
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Konrad Dybcio
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
The RBBM_CLOCK_CNTL3_TP0 entry in a730_hwcg has bits[19:16] set to 2
(clock gating enabled for that TP0 stage). As per the latest
recommendation, clear this nibble to disable clock gating for this
particular stage.
Fixes: 9588d2f860a4 ("drm/msm/a6xx: Add A730 support")
Signed-off-by: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 3e6f409d13a2..a98d550b72d0 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -1199,7 +1199,7 @@ static const struct adreno_reglist a730_hwcg[] = {
{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
- { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+ { REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22220222 },
{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
--
2.54.0
^ permalink raw reply related
* [PATCH v2 2/9] drm/msm/a6xx: Rename GBIF_CX_CONFIG to a A6XX- variant register
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Dmitry Baryshkov, Konrad Dybcio
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
The GBIF_CX_CONFIG register exists on GPUs prior to A8XX (it is used on
A722, for example), so it should be tagged as an A6XX variant to match
the register spec. Widen its variant range from "A8XX-" to "A6XX-" in the
register XML and rename the generated macro accordingly at all existing
usage sites.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 2 +-
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 2 +-
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 2 +-
drivers/gpu/drm/msm/registers/adreno/a6xx.xml | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index a98d550b72d0..4b68416e4d05 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -2180,7 +2180,7 @@ static const struct adreno_reglist a840_gbif[] = {
{ REG_A6XX_GBIF_QSB_SIDE1, 0x00071e20 },
{ REG_A6XX_GBIF_QSB_SIDE2, 0x00071e20 },
{ REG_A6XX_GBIF_QSB_SIDE3, 0x00071e20 },
- { REG_A8XX_GBIF_CX_CONFIG, 0x20023000 },
+ { REG_A6XX_GBIF_CX_CONFIG, 0x20023000 },
{ },
};
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 2e5d7b53a0c3..4a3c8dc8bb88 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -1032,7 +1032,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
gpu_write(gpu, gbif_cx[i].offset, gbif_cx[i].value);
if (adreno_is_a8xx(adreno_gpu)) {
- gpu_write(gpu, REG_A8XX_GBIF_CX_CONFIG, 0x20023000);
+ gpu_write(gpu, REG_A6XX_GBIF_CX_CONFIG, 0x20023000);
gmu_write(gmu, REG_A6XX_GMU_MRC_GBIF_QOS_CTRL, 0x33);
}
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index 9e44fd1ae634..6a75bfb6cec1 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -228,7 +228,7 @@ static void a8xx_set_hwcg(struct msm_gpu *gpu, bool state)
* GMU enables clk gating in GBIF during boot up. So,
* override that here when hwcg feature is disabled
*/
- gpu_rmw(gpu, REG_A8XX_GBIF_CX_CONFIG, BIT(0), 0);
+ gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, BIT(0), 0);
}
}
diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
index 3349c01646e1..69dd0446f8d2 100644
--- a/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
+++ b/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
@@ -1268,7 +1268,7 @@ by a particular renderpass/blit.
<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1" variants="A6XX"/>
<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2" variants="A6XX"/>
- <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A8XX-"/>
+ <reg32 offset="0x3c00" name="GBIF_CX_CONFIG" variants="A6XX-"/>
<reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
<reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
<reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>
--
2.54.0
^ permalink raw reply related
* [PATCH v2 3/9] drm/msm/a6xx: Add Adreno 722 support
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Add support for Adreno A722, a member of the GEN1 A7xx family. It is
derived from A730 and shares the same IP-level configurations: HWCG
registers, protected registers, GBIF CX registers and gmu_cgc_mode.
Major differences include lower cache/core counts, 1MB GMEM, no
Concurrent Binning & LPAC support. Some of the peripheral blocks like
RSCC are from A740 that resulted in updates to RSC layout.
Add a new entry to the catalog to describe the usual configuration and
few additional fixup mainly due to missing CB/LPAC features and updated
RSC layout.
Signed-off-by: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 34 ++
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 15 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 +-
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 81 +++-
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 5 +
.../gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h | 428 +++++++++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 +
7 files changed, 549 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 4b68416e4d05..e6598d9ba2b0 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -1500,6 +1500,40 @@ static const struct adreno_info a7xx_gpus[] = {
.gmu_cgc_mode = 0x00020000,
},
.preempt_record_size = 2860 * SZ_1K,
+ }, {
+ .chip_ids = ADRENO_CHIP_IDS(0x43020100),
+ .family = ADRENO_7XX_GEN1,
+ .fw = {
+ [ADRENO_FW_SQE] = "qcom/gen71700_sqe.fw",
+ [ADRENO_FW_GMU] = "qcom/gen71700_gmu.bin",
+ },
+ .gmem = SZ_1M,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+ ADRENO_QUIRK_HAS_HW_APRIV |
+ ADRENO_QUIRK_PREEMPTION,
+ .funcs = &a7xx_gpu_funcs,
+ .a6xx = &(const struct a6xx_info) {
+ .hwcg = a730_hwcg,
+ .protect = &a730_protect,
+ .pwrup_reglist = &a7xx_pwrup_reglist,
+ .dyn_pwrup_reglist = &a7xx_dyn_pwrup_reglist,
+ .gbif_cx = a640_gbif,
+ .gmu_chipid = 0x07110000,
+ .gmu_cgc_mode = 0x00020000,
+ .bcms = (const struct a6xx_bcm[]) {
+ { .name = "SH0", .buswidth = 16 },
+ { .name = "MC0", .buswidth = 4 },
+ {
+ .name = "ACV",
+ .fixed = true,
+ .perfmode = BIT(3),
+ .perfmode_bw = 16500000,
+ },
+ { /* sentinel */ },
+ },
+ },
+ .preempt_record_size = 1536 * SZ_1K,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
.family = ADRENO_7XX_GEN2,
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 4a3c8dc8bb88..0e11d7d69f5b 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -710,7 +710,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,
- adreno_is_a740_family(adreno_gpu) ? 0x80000021 : 0x80000000);
+ (adreno_is_a740_family(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu)) ? 0x80000021 : 0x80000000);
gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
@@ -718,7 +719,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
/* The second spin of A7xx GPUs messed with some register offsets.. */
- if (adreno_is_a740_family(adreno_gpu))
+ if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu))
seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
/* Load RSC sequencer uCode for sleep and wakeup */
@@ -1034,7 +1035,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
if (adreno_is_a8xx(adreno_gpu)) {
gpu_write(gpu, REG_A6XX_GBIF_CX_CONFIG, 0x20023000);
gmu_write(gmu, REG_A6XX_GMU_MRC_GBIF_QOS_CTRL, 0x33);
- }
+ } else if (adreno_is_a722(adreno_gpu))
+ gpu_rmw(gpu, REG_A6XX_GBIF_CX_CONFIG, GENMASK(31, 29),
+ FIELD_PREP(GENMASK(31, 29), 2));
/* Set up the lowest idle level on the GMU */
a6xx_gmu_power_config(gmu);
@@ -1087,7 +1090,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
u32 val, seqmem_off = 0;
/* The second spin of A7xx GPUs messed with some register offsets.. */
- if (adreno_is_a740_family(adreno_gpu) || adreno_is_a8xx(adreno_gpu))
+ if (adreno_is_a740_family(adreno_gpu) || adreno_is_a722(adreno_gpu) ||
+ adreno_is_a8xx(adreno_gpu))
seqmem_off = 4;
/* Make sure there are no outstanding RPMh votes */
@@ -1100,7 +1104,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,
val, (val & 1), 100, 1000);
- if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a8xx(adreno_gpu))
+ if (!adreno_is_a740_family(adreno_gpu) && !adreno_is_a722(adreno_gpu) &&
+ !adreno_is_a8xx(adreno_gpu))
return;
gmu_poll_timeout_rscc(gmu, REG_A7XX_RSCC_TCS4_DRV0_STATUS + seqmem_off,
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 8b3bb2fd433b..2228dd683982 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1273,7 +1273,8 @@ static int hw_init(struct msm_gpu *gpu)
if (!(adreno_is_a650_family(adreno_gpu) ||
adreno_is_a702(adreno_gpu) ||
adreno_is_a730(adreno_gpu))) {
- gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
+ gmem_range_min = (adreno_is_a740_family(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu)) ? SZ_16M : SZ_1M;
/* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN, gmem_range_min);
@@ -1338,6 +1339,7 @@ static int hw_init(struct msm_gpu *gpu)
/* Enable fault detection */
if (adreno_is_a612(adreno_gpu) ||
+ adreno_is_a722(adreno_gpu) ||
adreno_is_a730(adreno_gpu) ||
adreno_is_a740_family(adreno_gpu))
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
index 166365359fa6..37a0c8cc4e60 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
@@ -11,12 +11,14 @@
static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;
+static const unsigned int *gen7_17_0_external_core_regs[] __always_unused;
static const struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;
static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;
#include "adreno_gen7_0_0_snapshot.h"
#include "adreno_gen7_2_0_snapshot.h"
#include "adreno_gen7_9_0_snapshot.h"
+#include "adreno_gen7_17_0_snapshot.h"
struct a6xx_gpu_state_obj {
const void *handle;
@@ -404,8 +406,13 @@ static void a7xx_get_debugbus_blocks(struct msm_gpu *gpu,
int i;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- debugbus_blocks = gen7_0_0_debugbus_blocks;
- debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
+ if (adreno_is_a722(adreno_gpu)) {
+ debugbus_blocks = gen7_17_0_debugbus_blocks;
+ debugbus_blocks_count = ARRAY_SIZE(gen7_17_0_debugbus_blocks);
+ } else {
+ debugbus_blocks = gen7_0_0_debugbus_blocks;
+ debugbus_blocks_count = ARRAY_SIZE(gen7_0_0_debugbus_blocks);
+ }
gbif_debugbus_blocks = a7xx_gbif_debugbus_blocks;
gbif_debugbus_blocks_count = ARRAY_SIZE(a7xx_gbif_debugbus_blocks);
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
@@ -678,8 +685,13 @@ static void a7xx_get_dbgahb_clusters(struct msm_gpu *gpu,
unsigned dbgahb_clusters_size;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- dbgahb_clusters = gen7_0_0_sptp_clusters;
- dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
+ if (adreno_is_a722(adreno_gpu)) {
+ dbgahb_clusters = gen7_17_0_sptp_clusters;
+ dbgahb_clusters_size = ARRAY_SIZE(gen7_17_0_sptp_clusters);
+ } else {
+ dbgahb_clusters = gen7_0_0_sptp_clusters;
+ dbgahb_clusters_size = ARRAY_SIZE(gen7_0_0_sptp_clusters);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
dbgahb_clusters = gen7_2_0_sptp_clusters;
dbgahb_clusters_size = ARRAY_SIZE(gen7_2_0_sptp_clusters);
@@ -839,8 +851,13 @@ static void a7xx_get_clusters(struct msm_gpu *gpu,
unsigned clusters_size;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- clusters = gen7_0_0_clusters;
- clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
+ if (adreno_is_a722(adreno_gpu)) {
+ clusters = gen7_17_0_clusters;
+ clusters_size = ARRAY_SIZE(gen7_17_0_clusters);
+ } else {
+ clusters = gen7_0_0_clusters;
+ clusters_size = ARRAY_SIZE(gen7_0_0_clusters);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
clusters = gen7_2_0_clusters;
clusters_size = ARRAY_SIZE(gen7_2_0_clusters);
@@ -977,8 +994,13 @@ static void a7xx_get_shaders(struct msm_gpu *gpu,
int i;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- shader_blocks = gen7_0_0_shader_blocks;
- num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
+ if (adreno_is_a722(adreno_gpu)) {
+ shader_blocks = gen7_17_0_shader_blocks;
+ num_shader_blocks = ARRAY_SIZE(gen7_17_0_shader_blocks);
+ } else {
+ shader_blocks = gen7_0_0_shader_blocks;
+ num_shader_blocks = ARRAY_SIZE(gen7_0_0_shader_blocks);
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
shader_blocks = gen7_2_0_shader_blocks;
num_shader_blocks = ARRAY_SIZE(gen7_2_0_shader_blocks);
@@ -1376,8 +1398,13 @@ static void a7xx_get_registers(struct msm_gpu *gpu,
const struct gen7_reg_list *reglist;
if (adreno_gpu->info->family == ADRENO_7XX_GEN1) {
- reglist = gen7_0_0_reg_list;
- pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
+ if (adreno_is_a722(adreno_gpu)) {
+ reglist = gen7_17_0_reg_list;
+ pre_crashdumper_regs = gen7_9_0_pre_crashdumper_gpu_registers;
+ } else {
+ reglist = gen7_0_0_reg_list;
+ pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
+ }
} else if (adreno_gpu->info->family == ADRENO_7XX_GEN2) {
reglist = gen7_2_0_reg_list;
pre_crashdumper_regs = gen7_0_0_pre_crashdumper_gpu_registers;
@@ -1433,7 +1460,9 @@ static void a7xx_get_post_crashdumper_registers(struct msm_gpu *gpu,
const u32 *regs;
BUG_ON(adreno_gpu->info->family > ADRENO_7XX_GEN3);
- regs = gen7_0_0_post_crashdumper_registers;
+ regs = adreno_is_a722(adreno_gpu) ?
+ gen7_17_0_post_crashdumper_registers :
+ gen7_0_0_post_crashdumper_registers;
a7xx_get_ahb_gpu_registers(gpu,
a6xx_state, regs,
@@ -1540,19 +1569,35 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
const struct a6xx_indexed_registers *indexed_regs;
+ const struct a6xx_indexed_registers *mempool_regs;
int i, indexed_count, mempool_count;
+ bool concurrent_binning;
- if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {
+ if (adreno_is_a722(adreno_gpu)) {
+ /*
+ * Eliza has no BV or LPAC SQE — skip the BV/LPAC indexed
+ * registers and the BV mempool
+ */
+ indexed_regs = gen7_17_0_cp_indexed_reglist;
+ indexed_count = ARRAY_SIZE(gen7_17_0_cp_indexed_reglist);
+ mempool_regs = a7xx_cp_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_mempool_indexed);
+ concurrent_binning = false;
+ } else if (adreno_gpu->info->family <= ADRENO_7XX_GEN2) {
indexed_regs = a7xx_indexed_reglist;
indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);
+ mempool_regs = a7xx_cp_bv_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
+ concurrent_binning = true;
} else {
BUG_ON(adreno_gpu->info->family != ADRENO_7XX_GEN3);
indexed_regs = gen7_9_0_cp_indexed_reg_list;
indexed_count = ARRAY_SIZE(gen7_9_0_cp_indexed_reg_list);
+ mempool_regs = a7xx_cp_bv_mempool_indexed;
+ mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
+ concurrent_binning = true;
}
- mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
-
a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
indexed_count + mempool_count,
sizeof(*a6xx_state->indexed_regs));
@@ -1567,15 +1612,17 @@ static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
&a6xx_state->indexed_regs[i]);
gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));
- gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
+ if (concurrent_binning)
+ gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
/* Get the contents of the CP_BV mempool */
for (i = 0; i < mempool_count; i++)
- a6xx_get_indexed_regs(gpu, a6xx_state, &a7xx_cp_bv_mempool_indexed[i],
+ a6xx_get_indexed_regs(gpu, a6xx_state, &mempool_regs[i],
&a6xx_state->indexed_regs[indexed_count + i]);
gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);
- gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
+ if (concurrent_binning)
+ gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
return;
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
index b49d8427b59e..f4e912ecd50a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
@@ -462,6 +462,11 @@ static const struct a6xx_indexed_registers a7xx_cp_bv_mempool_indexed[] = {
REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2200, NULL },
};
+static const struct a6xx_indexed_registers a7xx_cp_mempool_indexed[] = {
+ { "CP_MEM_POOL_DBG", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
+ REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2200, NULL },
+};
+
#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
static const struct a6xx_debugbus_block {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h b/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
new file mode 100644
index 000000000000..00a4a0fc97d2
--- /dev/null
+++ b/drivers/gpu/drm/msm/adreno/adreno_gen7_17_0_snapshot.h
@@ -0,0 +1,428 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef __ADRENO_GEN7_17_0_SNAPSHOT_H
+#define __ADRENO_GEN7_17_0_SNAPSHOT_H
+
+#include "a6xx_gpu_state.h"
+
+/*
+ * Snapshot tables for Adreno A722 (Eliza).
+ * Cluster sub-arrays that are identical to A730 reference gen7_0_0_*
+ * symbols; adreno_gen7_0_0_snapshot.h is included first in the TU.
+ */
+
+static const u32 gen7_17_0_rscc_registers[] = {
+ 0x14000, 0x14034, 0x14036, 0x14036, 0x14040, 0x14042, 0x14044, 0x14045,
+ 0x14047, 0x14047, 0x14080, 0x14084, 0x14089, 0x1408c, 0x14091, 0x14094,
+ 0x14099, 0x1409c, 0x140a1, 0x140a4, 0x140a9, 0x140ac, 0x140b1, 0x140b4,
+ 0x140b9, 0x140bc, 0x14100, 0x14104, 0x14114, 0x14119, 0x14124, 0x14132,
+ 0x14154, 0x1416b, 0x14340, 0x14341, 0x14344, 0x14344, 0x14346, 0x1437c,
+ 0x143f0, 0x143f8, 0x143fa, 0x143fe, 0x14400, 0x14404, 0x14406, 0x1440a,
+ 0x1440c, 0x14410, 0x14412, 0x14416, 0x14418, 0x1441c, 0x1441e, 0x14422,
+ 0x14424, 0x14424, 0x14498, 0x144a0, 0x144a2, 0x144a6, 0x144a8, 0x144ac,
+ 0x144ae, 0x144b2, 0x144b4, 0x144b8, 0x144ba, 0x144be, 0x144c0, 0x144c4,
+ 0x144c6, 0x144ca, 0x144cc, 0x144cc, 0x14540, 0x14548, 0x1454a, 0x1454e,
+ 0x14550, 0x14554, 0x14556, 0x1455a, 0x1455c, 0x14560, 0x14562, 0x14566,
+ 0x14568, 0x1456c, 0x1456e, 0x14572, 0x14574, 0x14574, 0x145e8, 0x145f0,
+ 0x145f2, 0x145f6, 0x145f8, 0x145fc, 0x145fe, 0x14602, 0x14604, 0x14608,
+ 0x1460a, 0x1460e, 0x14610, 0x14614, 0x14616, 0x1461a, 0x1461c, 0x1461c,
+ 0x14690, 0x14698, 0x1469a, 0x1469e, 0x146a0, 0x146a4, 0x146a6, 0x146aa,
+ 0x146ac, 0x146b0, 0x146b2, 0x146b6, 0x146b8, 0x146bc, 0x146be, 0x146c2,
+ 0x146c4, 0x146c4, 0x14738, 0x14740, 0x14742, 0x14746, 0x14748, 0x1474c,
+ 0x1474e, 0x14752, 0x14754, 0x14758, 0x1475a, 0x1475e, 0x14760, 0x14764,
+ 0x14766, 0x1476a, 0x1476c, 0x1476c, 0x147e0, 0x147e8, 0x147ea, 0x147ee,
+ 0x147f0, 0x147f4, 0x147f6, 0x147fa, 0x147fc, 0x14800, 0x14802, 0x14806,
+ 0x14808, 0x1480c, 0x1480e, 0x14812, 0x14814, 0x14814, 0x14888, 0x14890,
+ 0x14892, 0x14896, 0x14898, 0x1489c, 0x1489e, 0x148a2, 0x148a4, 0x148a8,
+ 0x148aa, 0x148ae, 0x148b0, 0x148b4, 0x148b6, 0x148ba, 0x148bc, 0x148bc,
+ 0x14930, 0x14938, 0x1493a, 0x1493e, 0x14940, 0x14944, 0x14946, 0x1494a,
+ 0x1494c, 0x14950, 0x14952, 0x14956, 0x14958, 0x1495c, 0x1495e, 0x14962,
+ 0x14964, 0x14964,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_rscc_registers), 8));
+
+static const u32 gen7_17_0_cpr_registers[] = {
+ 0x26800, 0x26805, 0x26808, 0x2680c, 0x26814, 0x26814, 0x2681c, 0x2681c,
+ 0x26820, 0x26838, 0x26840, 0x26840, 0x26848, 0x26848, 0x26850, 0x26850,
+ 0x26880, 0x2688e, 0x26980, 0x269b0, 0x269c0, 0x269c2, 0x269c6, 0x269c8,
+ 0x269e0, 0x269ee, 0x269fb, 0x269ff, 0x26a02, 0x26a07, 0x26a09, 0x26a0b,
+ 0x26a10, 0x26b0f, 0x27440, 0x27441, 0x27444, 0x27444, 0x27480, 0x274a2,
+ 0x274ac, 0x274c4, 0x274c8, 0x274da,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_cpr_registers), 8));
+
+static const u32 gen7_17_0_gpucc_registers[] = {
+ 0x24000, 0x2400f, 0x24400, 0x2440f, 0x24800, 0x24805, 0x24c00, 0x24cff,
+ 0x25400, 0x25404, 0x25800, 0x25804, 0x25c00, 0x25c04, 0x26000, 0x26004,
+ 0x26400, 0x26405, 0x26414, 0x2641d, 0x2642a, 0x2642c, 0x2642e, 0x26432,
+ 0x26434, 0x26434, 0x26443, 0x26457, 0x26459, 0x2645d, 0x2645f, 0x26464,
+ 0x26477, 0x26479, 0x26489, 0x2648b, 0x2649a, 0x2649b, 0x264ad, 0x264af,
+ 0x264b1, 0x264b5, 0x264d6, 0x264d8, 0x264e7, 0x264e9, 0x264f9, 0x264fa,
+ 0x2650a, 0x2650d, 0x2651f, 0x26520, 0x2652d, 0x2652f, 0x2653e, 0x2653e,
+ 0x26540, 0x2654e, 0x26554, 0x26573, 0x26576, 0x26576, 0x26593, 0x26593,
+ 0x26600, 0x26616, 0x26620, 0x2662d, 0x26630, 0x26631, 0x26635, 0x26635,
+ 0x26637, 0x26637, 0x2663a, 0x2663a, 0x26642, 0x26642, 0x26656, 0x26658,
+ 0x2665b, 0x2665d, 0x2665f, 0x26662,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpucc_registers), 8));
+
+static const u32 *gen7_17_0_external_core_regs[] = {
+ gen7_17_0_gpucc_registers,
+ gen7_17_0_cpr_registers,
+};
+
+static const u32 gen7_17_0_debugbus_blocks[] = {
+ A7XX_DBGBUS_CP_0_0,
+ A7XX_DBGBUS_CP_0_1,
+ A7XX_DBGBUS_RBBM,
+ A7XX_DBGBUS_HLSQ,
+ A7XX_DBGBUS_UCHE_0,
+ A7XX_DBGBUS_TESS_BR,
+ A7XX_DBGBUS_PC_BR,
+ A7XX_DBGBUS_VFDP_BR,
+ A7XX_DBGBUS_VPC_BR,
+ A7XX_DBGBUS_TSE_BR,
+ A7XX_DBGBUS_RAS_BR,
+ A7XX_DBGBUS_VSC,
+ A7XX_DBGBUS_COM_0,
+ A7XX_DBGBUS_LRZ_BR,
+ A7XX_DBGBUS_UFC_0,
+ A7XX_DBGBUS_UFC_1,
+ A7XX_DBGBUS_GMU_GX,
+ A7XX_DBGBUS_DBGC,
+ A7XX_DBGBUS_GPC_BR,
+ A7XX_DBGBUS_LARC,
+ A7XX_DBGBUS_HLSQ_SPTP,
+ A7XX_DBGBUS_RB_0,
+ A7XX_DBGBUS_RB_1,
+ A7XX_DBGBUS_UCHE_WRAPPER,
+ A7XX_DBGBUS_CCU_0,
+ A7XX_DBGBUS_CCU_1,
+ A7XX_DBGBUS_VFD_BR_0,
+ A7XX_DBGBUS_VFD_BR_1,
+ A7XX_DBGBUS_VFD_BR_2,
+ A7XX_DBGBUS_VFD_BR_3,
+ A7XX_DBGBUS_USP_0,
+ A7XX_DBGBUS_USP_1,
+ A7XX_DBGBUS_TP_0,
+ A7XX_DBGBUS_TP_1,
+ A7XX_DBGBUS_TP_2,
+ A7XX_DBGBUS_TP_3,
+ A7XX_DBGBUS_USPTP_0,
+ A7XX_DBGBUS_USPTP_1,
+ A7XX_DBGBUS_USPTP_2,
+ A7XX_DBGBUS_USPTP_3,
+};
+
+static const struct gen7_sel_reg gen7_17_0_rb_rac_sel = {
+ .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
+ .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
+ .val = 0x0,
+};
+
+static const struct gen7_sel_reg gen7_17_0_rb_rbp_sel = {
+ .host_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_HOST,
+ .cd_reg = REG_A6XX_RB_SUB_BLOCK_SEL_CNTL_CD,
+ .val = 0x9,
+};
+
+static const u32 gen7_17_0_post_crashdumper_registers[] = {
+ 0x00535, 0x00535,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_post_crashdumper_registers), 8));
+
+static const u32 gen7_17_0_gpu_registers[] = {
+ 0x00000, 0x00000, 0x00002, 0x00002, 0x00011, 0x00012, 0x00016, 0x0001b,
+ 0x0001f, 0x00032, 0x00038, 0x0003c, 0x00042, 0x00042, 0x00044, 0x00044,
+ 0x00047, 0x00047, 0x00049, 0x0004a, 0x0004c, 0x0004c, 0x00050, 0x00050,
+ 0x00056, 0x00056, 0x00073, 0x00075, 0x000ad, 0x000ae, 0x000b0, 0x000b0,
+ 0x000b4, 0x000b4, 0x000b8, 0x000b8, 0x000bc, 0x000bc, 0x000c0, 0x000c0,
+ 0x000c4, 0x000c4, 0x000c8, 0x000c8, 0x000cc, 0x000cc, 0x000d0, 0x000d0,
+ 0x000d4, 0x000d4, 0x000d8, 0x000d8, 0x000dc, 0x000dc, 0x000e0, 0x000e0,
+ 0x000e4, 0x000e4, 0x000e8, 0x000e8, 0x000ec, 0x000ec, 0x000f0, 0x000f0,
+ 0x000f4, 0x000f4, 0x000f8, 0x000f8, 0x00100, 0x00100, 0x00104, 0x0010b,
+ 0x0010f, 0x0011d, 0x0012f, 0x0012f, 0x00200, 0x0020d, 0x00215, 0x00243,
+ 0x00260, 0x00268, 0x00272, 0x00274, 0x00286, 0x00286, 0x0028a, 0x0028a,
+ 0x0028c, 0x0028c, 0x00300, 0x00401, 0x00500, 0x00500, 0x00507, 0x0050b,
+ 0x0050f, 0x0050f, 0x00511, 0x00511, 0x00533, 0x00534, 0x00540, 0x00555,
+ 0x00564, 0x00567, 0x00800, 0x00808, 0x00810, 0x00813, 0x00820, 0x00821,
+ 0x00823, 0x00827, 0x00830, 0x00834, 0x00840, 0x00841, 0x00843, 0x00847,
+ 0x0084f, 0x00886, 0x008a0, 0x008ab, 0x008c0, 0x008c0, 0x008c4, 0x008c5,
+ 0x008d0, 0x008dd, 0x008f0, 0x008f3, 0x00900, 0x00903, 0x00908, 0x00911,
+ 0x00928, 0x0093e, 0x00942, 0x0094d, 0x00980, 0x00984, 0x0098d, 0x0098f,
+ 0x009b0, 0x009b4, 0x009c2, 0x009c9, 0x009ce, 0x009d7, 0x00a00, 0x00a00,
+ 0x00a02, 0x00a03, 0x00a10, 0x00a4f, 0x00a67, 0x00a6c, 0x00a9c, 0x00a9f,
+ 0x00c00, 0x00c00, 0x00c02, 0x00c04, 0x00c06, 0x00c06, 0x00c10, 0x00cd9,
+ 0x00ce0, 0x00d0c, 0x00df0, 0x00df4, 0x00e01, 0x00e02, 0x00e07, 0x00e0e,
+ 0x00e10, 0x00e12, 0x00e17, 0x00e17, 0x00e19, 0x00e19, 0x00e1b, 0x00e2b,
+ 0x00e30, 0x00e32, 0x00e38, 0x00e3c,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_gpu_registers), 8));
+
+static const u32 gen7_17_0_dbgc_registers[] = {
+ 0x00600, 0x0061c, 0x0061e, 0x00634, 0x00640, 0x0065a, 0x00679, 0x0067a,
+ 0x00699, 0x00699, 0x0069b, 0x0069e, 0x18400, 0x1841c, 0x1841e, 0x18434,
+ 0x18440, 0x1845c, 0x18479, 0x1847c, 0x18580, 0x18581,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_dbgc_registers), 8));
+
+static const u32 gen7_17_0_noncontext_pipe_br_registers[] = {
+ 0x00887, 0x0088c, 0x08600, 0x08600, 0x08602, 0x08602, 0x08610, 0x0861b,
+ 0x08620, 0x08620, 0x08630, 0x08630, 0x08637, 0x08639, 0x08640, 0x08640,
+ 0x09600, 0x09600, 0x09602, 0x09603, 0x0960a, 0x09616, 0x09624, 0x0963a,
+ 0x09640, 0x09640, 0x09e00, 0x09e00, 0x09e02, 0x09e07, 0x09e0a, 0x09e16,
+ 0x09e19, 0x09e19, 0x09e1c, 0x09e1c, 0x09e20, 0x09e25, 0x09e30, 0x09e31,
+ 0x09e40, 0x09e51, 0x09e64, 0x09e64, 0x09e70, 0x09e72, 0x09e78, 0x09e79,
+ 0x09e80, 0x09fff, 0x0a600, 0x0a600, 0x0a603, 0x0a603, 0x0a610, 0x0a61f,
+ 0x0a630, 0x0a631, 0x0a638, 0x0a638,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_noncontext_rb_rac_pipe_br_registers[] = {
+ 0x08e10, 0x08e1c, 0x08e20, 0x08e25, 0x08e51, 0x08e54,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rac_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_noncontext_rb_rbp_pipe_br_registers[] = {
+ 0x08e01, 0x08e01, 0x08e04, 0x08e04, 0x08e06, 0x08e09, 0x08e0c, 0x08e0c,
+ 0x08e28, 0x08e28, 0x08e2c, 0x08e35, 0x08e3b, 0x08e3f, 0x08e50, 0x08e50,
+ 0x08e5b, 0x08e5d, 0x08e5f, 0x08e5f, 0x08e61, 0x08e61, 0x08e63, 0x08e65,
+ 0x08e68, 0x08e68, 0x08e70, 0x08e79, 0x08e80, 0x08e8f,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_noncontext_rb_rbp_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_pc_cluster_fe_pipe_br_registers[] = {
+ 0x09800, 0x09804, 0x09806, 0x0980a, 0x09810, 0x09811, 0x09884, 0x09886,
+ 0x09970, 0x09972, 0x09b00, 0x09b08,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_pc_cluster_fe_pipe_br_registers), 8));
+
+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers[] = {
+ 0x0aa40, 0x0aabf,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers), 8));
+
+static const u32 gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers[] = {
+ 0x0aa40, 0x0aabf,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers), 8));
+
+static const u32 gen7_17_0_non_context_tpl1_pipe_none_usptp_registers[] = {
+ 0x0b602, 0x0b602, 0x0b604, 0x0b604, 0x0b608, 0x0b60c, 0x0b60f, 0x0b621,
+ 0x0b630, 0x0b633,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_none_usptp_registers), 8));
+
+static const u32 gen7_17_0_non_context_tpl1_pipe_br_usptp_registers[] = {
+ 0x0b600, 0x0b600,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_non_context_tpl1_pipe_br_usptp_registers), 8));
+
+static const u32 gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers[] = {
+ 0x0b300, 0x0b307, 0x0b309, 0x0b309, 0x0b310, 0x0b310,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers), 8));
+
+static const u32 gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers[] = {
+ 0x0b180, 0x0b183, 0x0b190, 0x0b195, 0x0b2c0, 0x0b2d5, 0x0b300, 0x0b307,
+ 0x0b309, 0x0b309, 0x0b310, 0x0b310,
+ UINT_MAX, UINT_MAX,
+};
+static_assert(IS_ALIGNED(sizeof(gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers), 8));
+
+/* No BV pipe — gen7_0_0_* sub-arrays are shared from adreno_gen7_0_0_snapshot.h */
+static struct gen7_cluster_registers gen7_17_0_clusters[] = {
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_pipe_br_registers, },
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_rb_rac_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_NONE, PIPE_BR, STATE_NON_CONTEXT,
+ gen7_17_0_noncontext_rb_rbp_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_rb_rac_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rac_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_rb_rbp_cluster_ps_pipe_br_registers, &gen7_17_0_rb_rbp_sel, },
+ { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_gras_cluster_gras_pipe_br_registers, },
+ { A7XX_CLUSTER_GRAS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_gras_cluster_gras_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_17_0_pc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_17_0_pc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vfd_cluster_fe_pipe_bv_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_FE, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_fe_pipe_br_registers, },
+ { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
+ { A7XX_CLUSTER_PC_VS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_pc_vs_pipe_br_registers, },
+ { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_0,
+ gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
+ { A7XX_CLUSTER_VPC_PS, PIPE_BR, STATE_FORCE_CTXT_1,
+ gen7_0_0_vpc_cluster_vpc_ps_pipe_br_registers, },
+};
+
+/* No BV pipe; 2 SPs, 2 USPTPs */
+static struct gen7_sptp_cluster_registers gen7_17_0_sptp_clusters[] = {
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_noncontext_pipe_br_hlsq_state_registers, 0xae00 },
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_noncontext_pipe_br_sp_top_registers, 0xae00 },
+ { A7XX_CLUSTER_NONE, A7XX_SP_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_noncontext_pipe_br_usptp_registers, 0xae00 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_VS, A7XX_SP_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_vs_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_HLSQ_STATE,
+ gen7_17_0_sp_cluster_sp_ps_pipe_lpac_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX0_3D_CPS_REG, PIPE_LPAC, 0, A7XX_USPTP,
+ gen7_17_0_sp_cluster_sp_ps_pipe_lpac_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_STATE,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_state_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_HLSQ_DP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_hlsq_dp_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_SP_TOP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_sp_top_registers, 0xa800 },
+ { A7XX_CLUSTER_SP_PS, A7XX_SP_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
+ gen7_0_0_sp_cluster_sp_ps_pipe_br_usptp_registers, 0xa800 },
+ { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_NONE, 0, A7XX_USPTP,
+ gen7_17_0_non_context_tpl1_pipe_none_usptp_registers, 0xb600 },
+ { A7XX_CLUSTER_NONE, A7XX_TP0_NCTX_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_non_context_tpl1_pipe_br_usptp_registers, 0xb600 },
+ { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX0_3D_CVS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_VS, A7XX_TP0_CTX1_3D_CVS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_vs_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX0_3D_CPS_REG, PIPE_BR, 0, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX1_3D_CPS_REG, PIPE_BR, 1, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX2_3D_CPS_REG, PIPE_BR, 2, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+ { A7XX_CLUSTER_SP_PS, A7XX_TP0_CTX3_3D_CPS_REG, PIPE_BR, 3, A7XX_USPTP,
+ gen7_17_0_tpl1_cluster_sp_ps_pipe_br_usptp_registers, 0xb000 },
+};
+
+static struct gen7_shader_block gen7_17_0_shader_blocks[] = {
+ { A7XX_TP0_TMO_DATA, 0x0200, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_TP0_SMO_DATA, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_TP0_MIPMAP_BASE_DATA, 0x03c0, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_DATA_1, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_0_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_1_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_2_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_3_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_4_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_LB_5_DATA, 0x0800, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_CB_RAM, 0x0390, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_INST_TAG, 0x0090, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_TMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_SMO_TAG, 0x0080, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_STATE_DATA, 0x0040, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_HWAVE_RAM, 0x0100, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_SP_L0_INST_BUF, 0x0050, 2, 2, PIPE_BR, A7XX_USPTP },
+ { A7XX_HLSQ_CVS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_BE_CTXT_BUF_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_BE_CTXT_BUF_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CVS_RAM, 0x01c0, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CPS_RAM, 0x0300, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CVS_MISC_RAM, 0x0280, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM_1, 0x0200, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_CONST_RAM, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CVS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_CPS_MISC_RAM_TAG, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM_TAG, 0x0080, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x0064, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INST_RAM_1, 0x0800, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_STPROC_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_BV_BE_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_DATAPATH_META, 0x0020, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_FRONTEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_INDIRECT_META, 0x0010, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+ { A7XX_HLSQ_BACKEND_META, 0x0040, 1, 1, PIPE_BR, A7XX_HLSQ_STATE },
+};
+
+static struct gen7_reg_list gen7_17_0_reg_list[] = {
+ { gen7_17_0_gpu_registers, NULL },
+ { gen7_17_0_dbgc_registers, NULL },
+ { NULL, NULL },
+};
+
+static const struct a6xx_indexed_registers gen7_17_0_cp_indexed_reglist[] = {
+ { "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
+ REG_A6XX_CP_SQE_STAT_DATA, 0x40, NULL },
+ { "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
+ REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
+ { "CP_SQE_UCODE_DBG", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
+ REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
+ { "CP_ROQ_DBG", REG_A6XX_CP_ROQ_DBG_ADDR,
+ REG_A6XX_CP_ROQ_DBG_DATA, 0, a7xx_get_cp_roq_size },
+};
+
+#endif /* __ADRENO_GEN7_17_0_SNAPSHOT_H */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 1f201322cb6e..114a40f79ef3 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -562,6 +562,11 @@ static inline int adreno_is_x185(struct adreno_gpu *gpu)
return gpu->info->chip_ids[0] == 0x43050c01;
}
+static inline int adreno_is_a722(struct adreno_gpu *gpu)
+{
+ return gpu->info->chip_ids[0] == 0x43020100;
+}
+
static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
{
if (WARN_ON_ONCE(!gpu->info))
--
2.54.0
^ permalink raw reply related
* [PATCH v2 4/9] dt-bindings: arm-smmu: Document GPU SMMU for Eliza SoC
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Krzysztof Kozlowski
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
Add specific compatible strings to document the GPU SMMU present
in the Eliza SoC.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index a701dec2fa0a..ed556683817c 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -95,6 +95,7 @@ properties:
- description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
items:
- enum:
+ - qcom,eliza-smmu-500
- qcom,glymur-smmu-500
- qcom,hawi-smmu-500
- qcom,kaanapali-smmu-500
@@ -570,6 +571,7 @@ allOf:
compatible:
items:
- enum:
+ - qcom,eliza-smmu-500
- qcom,glymur-smmu-500
- qcom,hawi-smmu-500
- qcom,kaanapali-smmu-500
--
2.54.0
^ permalink raw reply related
* [PATCH v2 5/9] dt-bindings: display/msm: Document Adreno 722 GPU and GMU
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Krzysztof Kozlowski
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Adreno 722 found in Eliza chipset belongs to the A7x Gen1 family. It is
derived from A730 and shares the same IP-level configurations: HWCG
registers, protected registers, GBIF CX registers and gmu_cgc_mode.
Major differences include lower cache/core counts, 1MB GMEM, no
Concurrent Binning & LPAC support. Some of the peripheral blocks like
RSCC are from A740 that resulted in updates to RSC layout.
Update the dt-binding docs to document this GPU and GMU.
Signed-off-by: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
Documentation/devicetree/bindings/display/msm/gmu.yaml | 1 +
Documentation/devicetree/bindings/display/msm/gpu.yaml | 1 +
2 files changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index 8578c2f8122e..9e459f12ce3f 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -262,6 +262,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,adreno-gmu-722.0
- qcom,adreno-gmu-730.1
- qcom,adreno-gmu-740.1
- qcom,adreno-gmu-750.1
diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index dbbd8b814189..d096632694c9 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -443,6 +443,7 @@ allOf:
- qcom,adreno-680.1
- qcom,adreno-690.0
- qcom,adreno-730.1
+ - qcom,adreno-43020100
- qcom,adreno-43030c00
- qcom,adreno-43050a01
- qcom,adreno-43050c01
--
2.54.0
^ permalink raw reply related
* [PATCH v2 6/9] arm64: dts: qcom: eliza: Add GPU SMMU node
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Abel Vesa <abel.vesa@oss.qualcomm.com>
Add the nodes to describe the GPU SMMU.
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/eliza.dtsi | 38 +++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
index c5635f22e2a7..e5b8377e6c3a 100644
--- a/arch/arm64/boot/dts/qcom/eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
@@ -2674,6 +2674,44 @@ mdss_dp0_out: endpoint {
};
};
+ adreno_smmu: iommu@3da0000 {
+ compatible = "qcom,eliza-smmu-500", "qcom,adreno-smmu",
+ "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x03da0000 0x0 0x40000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+ interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>;
+ clock-names = "hlos";
+ power-domains = <&gpucc GPU_CC_CX_GDSC>;
+ dma-coherent;
+ };
+
gpucc: clock-controller@3d90000 {
compatible = "qcom,eliza-gpucc";
reg = <0x0 0x03d90000 0x0 0xa000>;
--
2.54.0
^ permalink raw reply related
* [PATCH v2 7/9] arm64: dts: qcom: eliza: Add GPU nodes
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Konrad Dybcio
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Adreno 722 found in Eliza chipset belongs to the A7x GEN1 family. It is
derived from A730 and shares the same IP-level configurations: HWCG
registers, protected registers, GBIF CX registers and gmu_cgc_mode.
Major differences include lower cache/core counts, 1MB GMEM, no
Concurrent Binning & LPAC support. Some of the peripheral blocks like
RSCC are from A740 that resulted in updates to RSC layout.
Add the necessary devicetree nodes to describe this GPU.
Signed-off-by: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/eliza.dtsi | 152 ++++++++++++++++++++++++++++++++++++
1 file changed, 152 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
index e5b8377e6c3a..c24c5e9695d5 100644
--- a/arch/arm64/boot/dts/qcom/eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
@@ -3742,6 +3742,158 @@ nsp_noc: interconnect@320c0000 {
qcom,bcm-voters = <&apps_bcm_voter>;
#interconnect-cells = <2>;
};
+
+ gpu: gpu@3d00000 {
+ compatible = "qcom,adreno-43020100", "qcom,adreno";
+ reg = <0x0 0x03d00000 0x0 0x40000>,
+ <0x0 0x03d9e000 0x0 0x1000>,
+ <0x0 0x03d61000 0x0 0x800>;
+ reg-names = "kgsl_3d0_reg_memory",
+ "cx_mem",
+ "cx_dbgc";
+
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&adreno_smmu 0x0 0x0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+ qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+ interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "gfx-mem";
+
+ status = "disabled";
+
+ gpu_zap_shader: zap-shader {
+ memory-region = <&gpu_micro_code_mem>;
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2-adreno",
+ "operating-points-v2";
+
+ opp-259000000 {
+ opp-hz = /bits/ 64 <259000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+ opp-peak-kBps = <781250>;
+ qcom,opp-acd-level = <0xc82f5ffd>;
+ };
+
+ opp-345000000 {
+ opp-hz = /bits/ 64 <345000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ opp-peak-kBps = <2136718>;
+ qcom,opp-acd-level = <0xc82f5ffd>;
+ };
+
+ opp-515000000 {
+ opp-hz = /bits/ 64 <515000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ opp-peak-kBps = <5285156>;
+ qcom,opp-acd-level = <0xc02d5ffd>;
+ };
+
+ opp-645000000 {
+ opp-hz = /bits/ 64 <645000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+ opp-peak-kBps = <6074218>;
+ qcom,opp-acd-level = <0x882f5ffd>;
+ };
+
+ opp-724000000 {
+ opp-hz = /bits/ 64 <724000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+ opp-peak-kBps = <6671875>;
+ qcom,opp-acd-level = <0xa82d5ffd>;
+ };
+
+ opp-796000000 {
+ opp-hz = /bits/ 64 <796000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+ opp-peak-kBps = <10687500>;
+ qcom,opp-acd-level = <0x882d5ffd>;
+ };
+
+ opp-900000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+ opp-peak-kBps = <10687500>;
+ qcom,opp-acd-level = <0x882d5ffd>;
+ };
+
+ opp-975000000 {
+ opp-hz = /bits/ 64 <975000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+ opp-peak-kBps = <12449218>;
+ qcom,opp-acd-level = <0x882c5ffd>;
+ };
+
+ opp-1075000000 {
+ opp-hz = /bits/ 64 <1075000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+ opp-peak-kBps = <16500000>;
+ qcom,opp-acd-level = <0xa82a5ffd>;
+ };
+
+ opp-1150000000 {
+ opp-hz = /bits/ 64 <1150000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>;
+ opp-peak-kBps = <16500000>;
+ qcom,opp-acd-level = <0xa8295ffd>;
+ };
+ };
+ };
+
+ gmu: gmu@3d6a000 {
+ compatible = "qcom,adreno-gmu-722.0", "qcom,adreno-gmu";
+ reg = <0x0 0x03d6a000 0x0 0x35000>,
+ <0x0 0x03d50000 0x0 0x10000>,
+ <0x0 0x0b290000 0x0 0x10000>;
+ reg-names = "gmu", "rscc", "gmu_pdc";
+
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "hfi", "gmu";
+
+ clocks = <&gpucc GPU_CC_AHB_CLK>,
+ <&gpucc GPU_CC_CX_GMU_CLK>,
+ <&gpucc GPU_CC_CXO_CLK>,
+ <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&gcc GCC_GPU_GEMNOC_GFX_CLK>,
+ <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+ <&gpucc GPU_CC_DEMET_CLK>;
+ clock-names = "ahb",
+ "gmu",
+ "cxo",
+ "axi",
+ "memnoc",
+ "hub",
+ "demet";
+
+ power-domains = <&gpucc GPU_CC_CX_GDSC>,
+ <&gpucc GPU_CC_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+
+ iommus = <&adreno_smmu 0x5 0x0>;
+ qcom,qmp = <&aoss_qmp>;
+ operating-points-v2 = <&gmu_opp_table>;
+
+ gmu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-220000000 {
+ opp-hz = /bits/ 64 <220000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+
+ opp-550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+ };
+ };
};
thermal-zones {
--
2.54.0
^ permalink raw reply related
* [PATCH v2 8/9] arm64: dts: qcom: eliza: Add GPU cooling
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Gaurav Kohli
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
Unlike the CPU, the GPU does not throttle its speed automatically when it
reaches high temperatures. Set up GPU cooling by throttling the GPU speed
when it reaches 95°C.
Signed-off-by: Gaurav Kohli <gaurav.kohli@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/eliza.dtsi | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
index c24c5e9695d5..7a6095495b5a 100644
--- a/arch/arm64/boot/dts/qcom/eliza.dtsi
+++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
@@ -22,6 +22,7 @@
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&intc>;
@@ -4203,7 +4204,7 @@ gpuss0-thermal {
thermal-sensors = <&tsens1 8>;
trips {
- gpu-alert {
+ gpuss0_alert0: gpu-alert {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
@@ -4221,6 +4222,13 @@ gpu-critical {
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&gpuss0_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
gpuss1-thermal {
@@ -4229,7 +4237,7 @@ gpuss1-thermal {
thermal-sensors = <&tsens1 9>;
trips {
- gpu-alert {
+ gpuss1_alert0: gpu-alert {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
@@ -4247,6 +4255,13 @@ gpu-critical {
type = "critical";
};
};
+
+ cooling-maps {
+ map0 {
+ trip = <&gpuss1_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
modem0-thermal {
--
2.54.0
^ permalink raw reply related
* [PATCH v2 9/9] arm64: dts: qcom: eliza-mtp: Enable Adreno A722 GPU
From: Akhil P Oommen @ 2026-07-17 20:41 UTC (permalink / raw)
To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Will Deacon, Robin Murphy, Joerg Roedel (AMD)
Cc: Puranam V G Tejaswi, Abel Vesa, linux-arm-msm, dri-devel,
freedreno, linux-kernel, devicetree, linux-arm-kernel, iommu,
Akhil P Oommen, Konrad Dybcio
In-Reply-To: <20260718-eliza-gpu-v2-0-64379dbebd7a@oss.qualcomm.com>
From: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Enable the Adreno A722 GPU on the Eliza MTP board and provide the zap
shader firmware path.
Signed-off-by: Puranam V G Tejaswi <puranam.tejaswi@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/eliza-mtp.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/eliza-mtp.dts b/arch/arm64/boot/dts/qcom/eliza-mtp.dts
index 1374afd9d14e..a6e24d2e3b42 100644
--- a/arch/arm64/boot/dts/qcom/eliza-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/eliza-mtp.dts
@@ -417,6 +417,14 @@ vreg_l7k: ldo7 {
};
};
+&gpu {
+ status = "okay";
+};
+
+&gpu_zap_shader {
+ firmware-name = "qcom/eliza/gen71700_zap.mbn";
+};
+
&mdss {
status = "okay";
};
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v7] arm64: dts: s32g: Add GPR syscon region
From: sashiko-bot @ 2026-07-17 20:48 UTC (permalink / raw)
To: Jared Kangas; +Cc: robh, devicetree, Frank.Li, imx, conor+dt
In-Reply-To: <20260717-upstream-s32g-gpr-syscon-v7-1-ee198f287682@redhat.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The newly added `gpr: syscon@4007c000` node is inserted out of numerical address order in the device tree.
--
--- Patch [1]: [PATCH v7] arm64: dts: s32g: Add GPR syscon region ---
commit 1ee5b4988128c1ccf8969bc9b1f12c66a53c7919
Author: Dan Carpenter <error27@gmail.com>
arm64: dts: s32g: Add GPR syscon region
This commit adds the GPR syscon region for the s32 chipset. It resizes the
GPR syscon from 0x3000 to 0x100 to avoid a panic when reading the debugfs
regmap's registers file. The changes update the device tree files for both
s32g2 and s32g3.
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 809019ea0e299..81280ec6b07a9 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -325,6 +325,11 @@ usdhc0-200mhz-grp4 {
> };
> };
>
> + gpr: syscon@4007c000 {
> + compatible = "nxp,s32g2-gpr", "syscon";
> + reg = <0x4007c000 0x100>;
> + };
[Severity: Low]
This isn't a bug, but should the gpr: syscon@4007c000 node be inserted in
numerical address order? It appears to be placed after the pinctrl@4009c240
node (which contains usdhc0-200mhz-grp4). To maintain standard numerical
sorting, it would typically be positioned before pinctrl@4009c240.
> +
> ocotp: nvmem@400a4000 {
[ ... ]
> diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> index 22e80fc03f9c7..da35083a5e0e5 100644
> --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
> @@ -383,6 +383,11 @@ usdhc0-200mhz-grp4 {
> };
> };
>
> + gpr: syscon@4007c000 {
> + compatible = "nxp,s32g3-gpr", "syscon";
> + reg = <0x4007c000 0x100>;
> + };
[Severity: Low]
This isn't a bug, but similarly to the s32g2.dtsi changes, does this node
also break numerical address sorting? It seems to follow a node with a higher
address.
> +
> ocotp: nvmem@400a4000 {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260717-upstream-s32g-gpr-syscon-v7-1-ee198f287682@redhat.com?part=1
^ permalink raw reply
* Re: [PATCH v5 1/3] drm/bridge: ti-sn65dsi83: Simplify error condition logic
From: Luca Ceresoli @ 2026-07-17 20:49 UTC (permalink / raw)
To: Wojciech Dubowik
Cc: linux-kernel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Marek Vasut, dri-devel, devicetree
In-Reply-To: <20260717115002.308035-2-wojciech.dubowik@mt.com>
On Fri, 17 Jul 2026 13:49:59 +0200, Wojciech Dubowik <wojciech.dubowik@mt.com> wrote:
> Simplify error condition logic in lvds device tree property parsing. It
> makes it easier to add extra properties without handling complex goto
> entries.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v5 3/3] drm/bridge: ti-sn65dsi83: Add reversed lvds lanes support
From: Luca Ceresoli @ 2026-07-17 20:49 UTC (permalink / raw)
To: Wojciech Dubowik
Cc: linux-kernel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Marek Vasut, dri-devel, devicetree
In-Reply-To: <20260717115002.308035-4-wojciech.dubowik@mt.com>
On Fri, 17 Jul 2026 13:50:01 +0200, Wojciech Dubowik <wojciech.dubowik@mt.com> wrote:
Hello,
>
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index f8a786953526..df44df2e872a 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> @@ -845,6 +863,19 @@ static int sn65dsi83_parse_lvds_endpoint(struct sn65dsi83 *ctx, int channel)
> else
> return -EINVAL;
>
> + ret_data = of_property_read_u32_array(endpoint, "data-lanes", data_lanes,
> + ARRAY_SIZE(data_lanes));
> + if (!ret_data) {
> + if (memcmp(data_lanes,
> + supported_data_lane_mapping[LANE_MAPPING_REVERSE],
> + ARRAY_SIZE(data_lanes)) == 0)
Did you have a look at this sashiko report? It seems valid:
| sashiko-bot@kernel.org <sashiko-bot@kernel.org>:
|
| [Severity: Medium]
| Does this code compare the entire array? memcmp() expects the length in
| bytes, but ARRAY_SIZE(data_lanes) evaluates to 4 (the number of elements).
|
| Because data_lanes is an array of u32, checking only 4 bytes means only
| the first element is compared. Should this be using sizeof(data_lanes)
| instead?
|
| via: https://patch.msgid.link/20260717115630.C58A61F000E9@smtp.kernel.org
> + ctx->lvds_reverse_lanes_conf[channel] = true;
> + else if (memcmp(data_lanes,
> + supported_data_lane_mapping[LANE_MAPPING_NORMAL],
> + ARRAY_SIZE(data_lanes)) != 0)
Same here.
Otherwise looks good.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v7] arm64: dts: s32g: Add GPR syscon region
From: Krzysztof Kozlowski @ 2026-07-17 20:51 UTC (permalink / raw)
To: Jared Kangas, Chester Lin, Matthias Brugger, Ghennadi Procopciuc,
NXP S32 Linux Team, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, imx, devicetree, linux-kernel, Dan Carpenter
In-Reply-To: <20260717-upstream-s32g-gpr-syscon-v7-1-ee198f287682@redhat.com>
On 17/07/2026 22:33, Jared Kangas wrote:
> From: Dan Carpenter <error27@gmail.com>
>
> Add the GPR syscon region for the s32 chipset.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
> [jkangas@redhat.com: GPR syscon resized from 0x3000 to 0x100]
> Tested-by: Jared Kangas <jkangas@redhat.com>
Your SoB implies that. We do not add Tb tags to own work. Otherwise, why
would you send code which you did not test? Same for Rb tag.
> Signed-off-by: Jared Kangas <jkangas@redhat.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v1 1/4] dt-bindings: lcdif: Add interface pixel format
From: Francesco Dolcini @ 2026-07-17 20:57 UTC (permalink / raw)
To: Frank Li
Cc: sashiko-reviews, Francesco Dolcini, devicetree, robh, dri-devel,
Frank.Li, conor+dt, imx
In-Reply-To: <alpQh0ASY1HgdNqE@SMW015318>
On Fri, Jul 17, 2026 at 10:55:51AM -0500, Frank Li wrote:
> On Fri, Jul 17, 2026 at 12:28:07PM +0000, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > - [Low] Introduction of the legacy, non-standard `interface-pix-fmt` property for a standard hardware concept (parallel bus width), violating modern DT principles.
> > --
> >
> > --- Patch [1]: [PATCH v1 1/4] dt-bindings: lcdif: Add interface pixel format ---
> > commit 7225ea545d2ff50540972dd75d375b8ecea4f315
> > Author: Francesco Dolcini <francesco.dolcini@toradex.com>
> >
> > dt-bindings: lcdif: Add interface pixel format
> >
> > This commit updates the fsl,lcdif device tree binding to support the
> > interface-pix-fmt property. The property is used to describe the hardware's
> > parallel data bus transfer width to match board wiring and prevent shifted
> > colors.
> >
> > > diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
> > > index 2dd0411ec6516..209ee5a96e393 100644
> > > --- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
> > > +++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
> > > @@ -58,6 +58,13 @@ properties:
> > > items:
> > > - const: rx
> > >
> > > + interface-pix-fmt:
> > > + $ref: /schemas/types.yaml#/definitions/string
> > > + enum:
> > > + - rgb24
> > > + - rgb565
> > > + - rgb666
> >
> > [Severity: Low]
> > Is this introducing a legacy, non-standard property into the new schema ABI?
> >
> > Standard devicetree guidelines usually prefer endpoint properties like
> > bus-width (defined in video-interfaces.yaml) to describe physical parallel
> > data line configurations, such as setting bus-width = <18> for RGB666.
>
> Make sense, can we use standard property?
video-interfaces.yaml is for video capture interfaces (cameras and the
media/v4l subsystem). It does not apply here for DPI display interfaces.
Francesco
^ permalink raw reply
* [PATCH v2 0/6] hwmon: (adt7470) Add thermal zone and PWM provider support
From: Luiz Angelo Daros de Luca @ 2026-07-17 20:59 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Chris Packham, Andrew Morton, Darrick J. Wong,
Uwe Kleine-König
Cc: linux-hwmon, devicetree, linux-kernel, Luiz Angelo Daros de Luca,
linux-pwm, sashiko-bot
The ADT7470 is a temperature monitor and PWM fan controller capable of
monitoring up to 10 external temperature sensors and controlling up to 4
PWM outputs.
Currently, the driver exposes these sensors and PWM controls solely via
the standard hwmon sysfs interface. This patch series integrates the
ADT7470 driver with the kernel's thermal and PWM subsystems. This allows
its temperature sensors to be referenced by Device Tree thermal zones,
and its PWM channels to be consumed by generic Device Tree nodes (such
as "pwm-fan").
Patch 1 adds the YAML device tree binding documentation.
Patch 2 and 3 fix two pre-existing bugs found while testing this series
(fans stuck in manual mode after an I2C error, and a
busy-loop/I2C-flooding condition when auto_update_interval or
num_temp_sensors is 0).
Patch 4 performs a minor refactoring to introduce the ADT7470_PWM_MAX
macro.
Patch 5 registers the 4 PWM channels as a generic PWM provider.
Patch 6 registers the external temperature sensors as optional thermal
zones.
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
Changes in v2:
- Fixed 2 previous bugs uncovered by Sashiko-bot during review.
- Dropped the thermal cooling device registration for the PWM channels.
- Implemented generic PWM provider support using the PWM subsystem.
- Updated Kconfig to safely handle the PWM subsystem dependency (depends on PWM || PWM=n).
- Updated Device Tree bindings to require #pwm-cells instead of #cooling-cells.
- Link to v1: https://patch.msgid.link/20260716-adt7470_thermalzone-v1-0-cc55ef35edde@gmail.com
To: Guenter Roeck <linux@roeck-us.net>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: de Luca <luizluca@gmail.com>
To: Chris Packham <chris.packham@alliedtelesis.co.nz>
To: Andrew Morton <akpm@linux-foundation.org>
To: "Darrick J. Wong" <djwong@us.ibm.com>
To: Uwe Kleine-König <ukleinek@kernel.org>
Cc: linux-hwmon@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pwm@vger.kernel.org
---
Luiz Angelo Daros de Luca (6):
dt-bindings: hwmon: add binding for adi,adt7470
hwmon: (adt7470) Fix fans stuck in manual mode on I2C errors
hwmon: (adt7470) Fix busy-loop and I2C flooding in update thread
hwmon: (adt7470) Add ADT7470_PWM_MAX macro
hwmon: (adt7470) Register as a PWM provider
hwmon: (adt7470) Add thermal zone sensor support
.../devicetree/bindings/hwmon/adi,adt7470.yaml | 62 +++++++++++
drivers/hwmon/Kconfig | 1 +
drivers/hwmon/adt7470.c | 118 ++++++++++++++++++---
3 files changed, 166 insertions(+), 15 deletions(-)
---
base-commit: ca078d004cf58137bcf8cb24a8b271397431ba58
change-id: 20260716-adt7470_thermalzone-59a102278d72
Best regards,
--
Luiz Angelo Daros de Luca <luizluca@gmail.com>
^ 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