* [PATCH V11 1/9] dt-bindings: iio: imu: icm42600: Add mount-matrix to icm42600
From: Chris Morgan @ 2026-06-10 17:54 UTC (permalink / raw)
To: linux-iio
Cc: andy, nuno.sa, dlechner, jic23, jean-baptiste.maneyrol,
linux-rockchip, devicetree, heiko, conor+dt, krzk+dt, robh,
andriy.shevchenko, Chris Morgan, Krzysztof Kozlowski
In-Reply-To: <20260610175455.19006-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
Add mount-matrix attribute to schema. This attribute has been supported
since the first revision of this driver, but was not documented.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
.../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
index 119e28a833fd..9b2af104f186 100644
--- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
+++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
@@ -53,6 +53,8 @@ properties:
drive-open-drain:
type: boolean
+ mount-matrix: true
+
vdd-supply:
description: Regulator that provides power to the sensor
--
2.43.0
^ permalink raw reply related
* [PATCH V11 0/9] Add Invensense ICM42607
From: Chris Morgan @ 2026-06-10 17:54 UTC (permalink / raw)
To: linux-iio
Cc: andy, nuno.sa, dlechner, jic23, jean-baptiste.maneyrol,
linux-rockchip, devicetree, heiko, conor+dt, krzk+dt, robh,
andriy.shevchenko, Chris Morgan
From: Chris Morgan <macromorgan@hotmail.com>
Add support for the ICM42607 IMU. This sensor shares the same
functionality but a different register layout with the existing
ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C
and SPI, however only the ICM42607P over I2C could be tested.
Changes Since V1:
- Instead of creating a new driver, merged with the existing inv_icm42600
driver. This necessitated adding some code to the existing driver to
permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual
patches. Note that patch 0004 is still pretty hefty; if I need to split
further I may need to create some temporary stub functions.
- Used guard() and PM_RUNTIME_ACQUIRE_AUTOSUSPEND() on the new functions
per Jonathan's recommendations.
Changes Since V2:
- Went back to using a new driver on advice from Invensense engineer.
- Further split changes up into smaller chunks of functionality. Note
still that the largest patch is approximately 900 lines, and that while
the driver compiles cleanly at each commit it is not able to drive the
hardware until the commit that adds the Interrupt (as it also adds the
Makefile).
- Change the error to a warning when the devicetree binding does not match
the hardware ID.
- Dropped the ack on the devicetree bindings, as I am creating a new file
(for a new driver) instead of modifying the existing one.
Changes Since V3:
- Numerous small fixes (too many to list here). Thank you to everyone who
provided feedback.
- Split power management additions into an additional commit to break
things up further.
- Consolidated devicetree documentation in existing
invensense,icm42600.yaml file.
- Removed most of the FIELD_PREP from header file to c files to make code
easier to read.
- Changed scale values to 2D arrays for Gyro and Accelerometer.
- Removed IIO_CHAN_INFO_CALIBBIAS attribute.
Changes Since V4:
- Additional numerous small fixes, thank you again for all the feedback.
- Dropped power control API and instead run device in low noise mode.
- Split devicetree bindings into two distinct changes.
- Reordered adding of enums and structs to main header file so that they
are only brought in when needed.
- Stopped using enum for driver data and instead am using pointer to
device specific driver data.
Changes Since V5:
- Corrected use of "dev_warn_probe" to just "dev_warn".
- Fixed some return scenarios which would unconditionally return 0
when an error was present.
- Corrected use of max() to min() for bounds checking. max() was
incorrect.
- Fixed using "st->conf.accel.odr" in the gyroscope function. It
should have been "st->conf.gyro.odr" which it now is.
- Additional small fixes suggested by "sashiko.dev".
- Added a regmap cache. I used the datasheet to try and determine
which registers might change without explicit writes.
Changes Since V6:
- Corrected additional errors identified by sashiko.dev, mostly
fixing potential deadlocks, missing calls for pm runtime, and
potential overflow issues.
Changes Since V7:
- Dropped Wake on Movement patches, since some of the functionality
was only available for a device on which I cannot test.
- Dropped support for SPI 3-Wire mode, since it complicated the
bus setup (and I lack the hardware to test such features anyway).
- Fixed a few additional bugs identified by sashiko.dev bot.
Changes Since V8:
- Added back IRQ dropped accidentally when dropping wake on movement
patches.
- Dropped "Reviewed-By" tag on patch 2 because of substantial changes
made to devicetree binding documentation.
- Additional small fixes as suggested.
Changes Since V9:
- Removed interrupts (and buffers) from the driver. I previously was
unable to detect deadlocks because it turns out my IRQ was not even
wired correctly in my device.
- Updated devicetree binding commits to make interrupts optional for
users of the icm42607 driver.
Changes Since V10:
- Explicitly specified enum values in header file.
- Removed additional dead code for buffer handling.
- Cleaned up headers.
- Added additional locks as requested by sashiko.dev bot.
Chris Morgan (9):
dt-bindings: iio: imu: icm42600: Add mount-matrix to icm42600
dt-bindings: iio: imu: icm42600: Add icm42607
iio: imu: inv_icm42607: Add inv_icm42607 Core Driver
iio: imu: inv_icm42607: Add I2C and SPI For icm42607
iio: imu: inv_icm42607: Add PM support for icm42607
iio: imu: inv_icm42607: Add Temp Support in icm42607
iio: imu: inv_icm42607: Add Accelerometer for icm42607
iio: imu: inv_icm42607: Add Gyroscope to icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml | 20 +-
.../dts/rockchip/rk3568-anbernic-rg-ds.dts | 8 +-
drivers/iio/imu/Kconfig | 1 +
drivers/iio/imu/Makefile | 1 +
drivers/iio/imu/inv_icm42607/Kconfig | 30 ++
drivers/iio/imu/inv_icm42607/Makefile | 13 +
drivers/iio/imu/inv_icm42607/inv_icm42607.h | 415 ++++++++++++++
.../iio/imu/inv_icm42607/inv_icm42607_accel.c | 379 +++++++++++++
.../iio/imu/inv_icm42607/inv_icm42607_core.c | 506 ++++++++++++++++++
.../iio/imu/inv_icm42607/inv_icm42607_gyro.c | 369 +++++++++++++
.../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 93 ++++
.../iio/imu/inv_icm42607/inv_icm42607_spi.c | 105 ++++
.../iio/imu/inv_icm42607/inv_icm42607_temp.c | 82 +++
.../iio/imu/inv_icm42607/inv_icm42607_temp.h | 33 ++
14 files changed, 2053 insertions(+), 2 deletions(-)
create mode 100644 drivers/iio/imu/inv_icm42607/Kconfig
create mode 100644 drivers/iio/imu/inv_icm42607/Makefile
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607.h
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c
create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h
--
2.43.0
^ permalink raw reply
* Re: [PATCH 12/12] clk: qcom: gcc-mdm9607: Drop redundant register update during probe
From: Taniya Das @ 2026-06-10 17:31 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson
Cc: Michael Turquette, Stephen Boyd, Georgi Djakov, Shawn Guo,
Bryan O'Donoghue, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-clk,
linux-kernel, devicetree
In-Reply-To: <20260609-qcom-clk-mdm9607-fixes-v1-12-5e9717faf842@linaro.org>
On 6/9/2026 7:44 PM, Stephan Gerhold wrote:
> From: Stephan Gerhold <stephan@gerhold.net>
>
> GPLL0 is pretty much guaranteed to be already on (and voted) during boot,
> since it's used by the CPU and also various other components such as UART.
> We also vote for this bit in the actual GPLL0 definition, which will be set
> as soon as any driver in the kernel requires using the GPLL0 clock.
>
> All in all, this makes separately voting for GPLL0 during probe redundant,
> especially because the "acpuclock" in the comment is a downstream construct
> that does not exist in upstream.
>
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
> drivers/clk/qcom/gcc-mdm9607.c | 11 +----------
> 1 file changed, 1 insertion(+), 10 deletions(-)
>
> diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c
> index 0bd4c12483cd..ce78ebc8ffec 100644
> --- a/drivers/clk/qcom/gcc-mdm9607.c
> +++ b/drivers/clk/qcom/gcc-mdm9607.c
> @@ -1565,16 +1565,7 @@ MODULE_DEVICE_TABLE(of, gcc_mdm9607_match_table);
>
> static int gcc_mdm9607_probe(struct platform_device *pdev)
> {
> - struct regmap *regmap;
> -
> - regmap = qcom_cc_map(pdev, &gcc_mdm9607_desc);
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - /* Vote for GPLL0 to turn on. Needed by acpuclock. */
> - regmap_update_bits(regmap, 0x45000, BIT(0), BIT(0));
This was to ensure that the (APCS_GPLL_ENA_VOTE) vote indeed has a vote
from CPU. AFAIR, the boot up was not using this particular PLL vote
register and no piggy backing for the GPLL vote.
> -
> - return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9607_desc, regmap);
> + return qcom_cc_probe(pdev, &gcc_mdm9607_desc);
> }
>
> static struct platform_driver gcc_mdm9607_driver = {
>
--
Thanks,
Taniya Das
^ permalink raw reply
* Re: [PATCH 05/12] clk: qcom: gcc-mdm9607: Fix halt_reg for gcc_apss_axi_clk
From: Taniya Das @ 2026-06-10 17:24 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson
Cc: Michael Turquette, Stephen Boyd, Georgi Djakov, Shawn Guo,
Bryan O'Donoghue, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-clk,
linux-kernel, devicetree
In-Reply-To: <20260609-qcom-clk-mdm9607-fixes-v1-5-5e9717faf842@linaro.org>
On 6/9/2026 7:44 PM, Stephan Gerhold wrote:
> --- a/drivers/clk/qcom/gcc-mdm9607.c
> +++ b/drivers/clk/qcom/gcc-mdm9607.c
> @@ -1463,7 +1463,7 @@ static struct clk_branch gcc_apss_ahb_clk = {
> };
>
> static struct clk_branch gcc_apss_axi_clk = {
> - .halt_reg = 0x4601c,
> + .halt_reg = 0x46020,
> .halt_check = BRANCH_HALT_VOTED,
> .clkr = {
> .enable_reg = 0x45004,
Reviewed-by: Taniya Das <taniya.das@oss.qualcomm.com>
--
Thanks,
Taniya Das
^ permalink raw reply
* Re: [PATCH 04/12] clk: qcom: gcc-mdm9607: Fix BIMC PLL definition
From: Taniya Das @ 2026-06-10 17:13 UTC (permalink / raw)
To: Stephan Gerhold, Bjorn Andersson
Cc: Michael Turquette, Stephen Boyd, Georgi Djakov, Shawn Guo,
Bryan O'Donoghue, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, linux-clk,
linux-kernel, devicetree
In-Reply-To: <20260609-qcom-clk-mdm9607-fixes-v1-4-5e9717faf842@linaro.org>
On 6/9/2026 7:44 PM, Stephan Gerhold wrote:
> The gcc-mdm9607 driver was originally based on gcc-msm8916, but a closer
> match nowadays is gcc-msm8909. Looking at the differences between
> gcc-mdm9607 and gcc-msm8909, there is quite some confusion around the
> definitions for the BIMC PLL.
>
> It turns out the BIMC PLL on MDM9607 is actually an Alpha PLL just like on
> MSM8909. We can vote for it using BIT(2), which explains why BIT(3) was
> used for GPLL2.
BIMC PLL is never controlled from High Level OS (APSS). These are
controlled by other subsystems and voting should be via the ICC for BW
requirements.
--
Thanks,
Taniya Das
^ permalink raw reply
* [PATCH] arm64: dts: qcom: ipq9574: Add missing PCIe global IRQs
From: Kathiravan Thirumoorthy @ 2026-06-10 16:58 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-kernel, Kathiravan Thirumoorthy
IPQ9574 also has the dedicated 'global' IRQ line for each PCIe controller.
Add the same.
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index 622cfa96ed2b..a7e7115477c8 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -945,7 +945,8 @@ pcie1: pcie@10000000 {
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
@@ -953,7 +954,8 @@ pcie1: pcie@10000000 {
"msi4",
"msi5",
"msi6",
- "msi7";
+ "msi7",
+ "global";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -1031,7 +1033,8 @@ pcie3: pcie@18000000 {
<GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
@@ -1039,7 +1042,8 @@ pcie3: pcie@18000000 {
"msi4",
"msi5",
"msi6",
- "msi7";
+ "msi7",
+ "global";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -1117,7 +1121,8 @@ pcie2: pcie@20000000 {
<GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
@@ -1125,7 +1130,8 @@ pcie2: pcie@20000000 {
"msi4",
"msi5",
"msi6",
- "msi7";
+ "msi7",
+ "global";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
@@ -1202,7 +1208,8 @@ pcie0: pcie@28000000 {
<GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
@@ -1210,7 +1217,8 @@ pcie0: pcie@28000000 {
"msi4",
"msi5",
"msi6",
- "msi7";
+ "msi7",
+ "global";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
---
base-commit: 49e02880ec0a8c378e811bc9d85da188d7c6204c
change-id: 20260610-ipq9574_pcie_global_irq-eb2838b16374
Best regards,
--
Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
^ permalink raw reply related
* Re: [PATCH 2/2] drm/solomon: Add SSD1351 OLED display driver
From: sashiko-bot @ 2026-06-10 16:55 UTC (permalink / raw)
To: Amit Barzilai; +Cc: devicetree, conor+dt, dri-devel, robh
In-Reply-To: <20260610164428.180091-3-amit.barzilai22@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Calling sleeping functions from within DRM atomic callbacks.
- [High] Passing stack-allocated variables and read-only data (.rodata) to `spi_write()`, violating the SPI subsystem's DMA-safe memory requirements.
- [High] The OLED display is not turned off when the driver module is unloaded due to `drm_dev_unplug()` preventing the `atomic_disable` hook from accessing hardware.
- [High] Coordinate space mismatch in the damage handling loop causes incorrect pixel extraction when panning.
--
commit 830ebdf4bc79cf5af84541c3dcfa33f751296ed5
Author: Amit Barzilai <amit.barzilai22@gmail.com>
drm/solomon: Add SSD1351 OLED display driver
Add a DRM/KMS driver for the Solomon SSD1351, a 128x128 65k-color RGB
OLED controller driven over a 4-wire SPI bus.
> diff --git a/drivers/gpu/drm/solomon/ssd1351.c b/drivers/gpu/drm/solomon/ssd1351.c
> new file mode 100644
> index 0000000000000..7c4a5c461afb8
> --- /dev/null
> +++ b/drivers/gpu/drm/solomon/ssd1351.c
[ ... ]
> +static int ssd1351_write_cmd(struct ssd1351_device *ssd1351, u8 cmd,
> + const u8 *params, size_t num)
> +{
> + int ret;
> +
> + gpiod_set_value_cansleep(ssd1351->dc, 0);
> + ret = spi_write(ssd1351->spi, &cmd, 1);
[Severity: High]
Does this code pass a stack-allocated variable to spi_write()?
The SPI subsystem requires that buffers passed to spi_write() be DMA-safe.
Since cmd is a local variable on the stack, it may not be DMA-coherent
(especially if CONFIG_VMAP_STACK is enabled). Could this trigger cache
coherency failures or memory corruption when the SPI core attempts to map it?
> + if (ret)
> + return ret;
[ ... ]
> +/* Send a command followed by a fixed list of single-byte parameters. */
> +#define ssd1351_command(ssd1351, cmd, ...) \
> + ({ \
> + static const u8 _params[] = { __VA_ARGS__ }; \
> + ssd1351_write_cmd((ssd1351), (cmd), _params, \
> + ARRAY_SIZE(_params)); \
> + })
[Severity: High]
Does this macro pass read-only data (.rodata) to spi_write() via the
_params array?
Memory placed in .rodata is not DMA-safe. If the SPI subsystem attempts to map
this buffer for a DMA transfer, could this lead to kernel panics or undefined
behavior?
[ ... ]
> +static void ssd1351_reset(struct ssd1351_device *ssd1351)
> +{
> + if (!ssd1351->reset)
> + return;
> +
> + /*
> + * Work in logical levels: 1 asserts reset, 0 releases it. The DT's
> + * GPIO_ACTIVE_LOW flag handles the physical inversion, so this pulse is
> + * correct regardless of how the board wires the RES# line.
> + */
> + gpiod_set_value_cansleep(ssd1351->reset, 1);
> + usleep_range(20, 1000);
> + gpiod_set_value_cansleep(ssd1351->reset, 0);
> + msleep(120);
> +}
[Severity: High]
Are we safely calling these sleeping functions?
This function is invoked via ssd1351_init_display() from the
ssd1351_crtc_atomic_enable() callback. According to DRM subsystem guidelines,
CRTC atomic callbacks execute in an atomic context where sleeping is strictly
forbidden. Calling msleep() and usleep_range() here could result in system
instability or deadlocks.
[ ... ]
> +static void ssd1351_fb_blit_rect(struct ssd1351_device *ssd1351,
> + struct drm_framebuffer *fb,
> + const struct iosys_map *vmap,
> + struct drm_rect *rect,
> + struct drm_format_conv_state *fmtcnv_state)
> +{
> + unsigned int width = drm_rect_width(rect);
> + unsigned int height = drm_rect_height(rect);
> + unsigned int dst_pitch = width * sizeof(u16);
> + struct iosys_map dst;
> + u8 range[2];
> +
> + iosys_map_set_vaddr(&dst, ssd1351->tx_buf);
> +
> + /*
> + * The panel expects RGB565 most-significant byte first; the big-endian
> + * conversion produces exactly that byte stream for the 8-bit SPI words.
> + */
> + drm_fb_xrgb8888_to_rgb565be(&dst, &dst_pitch, vmap, fb, rect,
> + fmtcnv_state);
> +
> + range[0] = rect->x1;
> + range[1] = rect->x2 - 1;
> + if (ssd1351_write_cmd(ssd1351, SSD1351_SET_COL_ADDRESS, range,
> + sizeof(range)))
[Severity: High]
Similar to the issue in ssd1351_write_cmd(), does this pass the
stack-allocated range array down to spi_write()? This memory may not be
DMA-coherent.
[ ... ]
> +static void ssd1351_plane_atomic_update(struct drm_plane *plane,
> + struct drm_atomic_state *state)
> +{
[ ... ]
> + if (!drm_dev_enter(&ssd1351->drm, &idx))
> + return;
> +
> + if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE))
> + goto out_drm_dev_exit;
> +
> + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
> + drm_atomic_for_each_plane_damage(&iter, &damage) {
> + dst_clip = plane_state->dst;
> +
> + if (!drm_rect_intersect(&dst_clip, &damage))
> + continue;
> +
> + ssd1351_fb_blit_rect(ssd1351, fb, &shadow_plane_state->data[0],
> + &dst_clip,
> + &shadow_plane_state->fmtcnv_state);
> + }
[Severity: High]
Does this code call sleeping functions from within an atomic context?
According to DRM subsystem guidelines, plane atomic update callbacks execute
in an atomic context during non-blocking commits, where sleeping is strictly
forbidden. However, drm_gem_fb_begin_cpu_access() can block on dma-buf fences,
and ssd1351_fb_blit_rect() performs blocking SPI writes. The standard DRM
pattern for SPI displays is to defer hardware updates to a worker thread.
[Severity: High]
Does this loop also pass destination coordinates to a function expecting source
coordinates?
The helper drm_atomic_for_each_plane_damage() yields damage clips in CRTC
destination coordinates. The driver intersects these with dst_clip and passes
the result to ssd1351_fb_blit_rect(), which then passes it to
drm_fb_xrgb8888_to_rgb565be().
However, drm_fb_xrgb8888_to_rgb565be() expects the clipping rectangle to be
in framebuffer (source) coordinates to accurately extract pixels. If the
framebuffer is panned (i.e., src_x or src_y are non-zero), using destination
coordinates could extract pixels from the wrong location.
[ ... ]
> +static void ssd1351_crtc_atomic_disable(struct drm_crtc *crtc,
> + struct drm_atomic_state *state)
> +{
> + struct ssd1351_device *ssd1351 = drm_to_ssd1351(crtc->dev);
> + int idx;
> +
> + if (!drm_dev_enter(crtc->dev, &idx))
> + return;
> +
> + ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_OFF);
> +
> + drm_dev_exit(idx);
> +}
[ ... ]
> +static void ssd1351_remove(struct spi_device *spi)
> +{
> + struct drm_device *drm = spi_get_drvdata(spi);
> +
> + drm_dev_unplug(drm);
> + drm_atomic_helper_shutdown(drm);
> +}
[Severity: High]
Could the OLED display remain powered on when the driver module is unloaded?
In ssd1351_remove(), drm_dev_unplug() is called before
drm_atomic_helper_shutdown(). The drm_dev_unplug() call immediately sets the
DRM device's unplugged flag.
When drm_atomic_helper_shutdown() subsequently triggers the
ssd1351_crtc_atomic_disable() callback, the drm_dev_enter() check in that
callback will fail because the device is already marked as unplugged. As a
result, the display-off command will never be sent to the hardware.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610164428.180091-1-amit.barzilai22@gmail.com?part=2
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: display: Add Solomon SSD1351 OLED controller
From: sashiko-bot @ 2026-06-10 16:54 UTC (permalink / raw)
To: Amit Barzilai; +Cc: robh, devicetree, dri-devel, conor+dt
In-Reply-To: <20260610164428.180091-2-amit.barzilai22@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Missing type and value constraints for `rotation` property in device tree binding.
--
commit 4e4bbc4176c7e781dd970cf6e2d43e667642bddd
Author: Amit Barzilai <amit.barzilai22@gmail.com>
dt-bindings: display: Add Solomon SSD1351 OLED controller
This commit adds a new device tree binding for the Solomon SSD1351 OLED
display controller. It defines the standard properties and builds upon
the shared solomon,ssd-common.yaml schema.
> diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
> new file mode 100644
> index 0000000000000..a7d77132faa63
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
[ ... ]
> +properties:
> + compatible:
> + enum:
> + - solomon,ssd1351
> +
> + solomon,width:
> + default: 128
> +
> + solomon,height:
> + default: 128
> +
> + rotation: true
[Severity: Low]
Does this permit the rotation property without enforcing type validation?
Without including a reference to panel/panel-common.yaml# (or a direct type
definition), dt_binding_check will not enforce that rotation is a uint32 or
restricted to valid degrees (0, 90, 180, 270). This could allow incorrectly
typed device tree entries to pass schema validation but fail at runtime
when the driver attempts to call device_property_read_u32.
> +
> +required:
> + - compatible
> + - reg
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610164428.180091-1-amit.barzilai22@gmail.com?part=1
^ permalink raw reply
* Re: [External] Re: [PATCH v3 1/3] dt-bindings: riscv: clarify Svadu boot-time behavior
From: Conor Dooley @ 2026-06-10 16:52 UTC (permalink / raw)
To: yunhui cui
Cc: akpm, alex, andrew+kernel, aou, apatel, apopple, atishp,
baolin.wang, cleger, conor+dt, debug, devicetree, guodong,
hui.wang, krzk+dt, linux-kernel, linux-riscv, liu.xuemei1, namcao,
nick.hu, palmer, pincheng.plct, pjw, qingwei.hu, ritesh.list,
rmclure, robh, wangruikang, zhangchunyan, zong.li
In-Reply-To: <CAEEQ3w=C_z8awtevLhceTgqLW79ONzKTm5MRJeoSTLB9q_CeiQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2390 bytes --]
On Wed, Jun 10, 2026 at 10:03:01AM +0800, yunhui cui wrote:
> Hi Conor,
>
> On Wed, Jun 10, 2026 at 12:09 AM Conor Dooley <conor@kernel.org> wrote:
> >
> > On Tue, Jun 09, 2026 at 09:00:18PM +0800, Yunhui Cui wrote:
> > > Clarify that systems which advertise only Svadu have hardware PTE A/D
> > > updating enabled at boot, while systems advertising both Svade and Svadu
> > > must enable Svadu explicitly with SBI FWFT.
> > >
> > > Signed-off-by: Yunhui Cui <cuiyunhui@bytedance.com>
> > > Reviewed-by: Qingwei Hu <qingwei.hu@bytedance.com>
> > > ---
> > > Documentation/devicetree/bindings/riscv/extensions.yaml | 6 +++---
> > > 1 file changed, 3 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
> > > index 2b0a8a93bb214..b09888e9988de 100644
> > > --- a/Documentation/devicetree/bindings/riscv/extensions.yaml
> > > +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
> > > @@ -294,10 +294,10 @@ properties:
> > > of the PTE A/D bits or page faults when they need updated.
> > > 2) Only Svade present in DT => Supervisor must assume Svade to be
> > > always enabled.
> > > - 3) Only Svadu present in DT => Supervisor must assume Svadu to be
> > > - always enabled.
> > > + 3) Only Svadu present in DT => Supervisor must assume Svadu is
> > > + enabled at boot.
> >
> > Commit message is missing an explanation of why this behaviour change is
> > not problematic. Although, to be honest, I am not sure what the changed text
> > actually means. If only Svadu is present, then the hardware doesn't support
> > Svade, and therefore Svadu would never be anything other than enabled so
> > changing the wording to specify "at boot" seems less clear?
>
> The "enabled at boot" wording came from Andrew's feedback on the previous
> version: "always" is a sensitive term here because ADUE is writable when
> Svadu is implemented, and ADUE=0 behaves as though Svade were implemented.
Whether or not it is writeable, the current wording means that it is not
allowed to be changed. I think that's reasonable because there's nothing
else supported by the hardware so changing it makes no sense.
> Would this wording work?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: iio: pressure: Add MS5637
From: Conor Dooley @ 2026-06-10 16:45 UTC (permalink / raw)
To: Louis Adamian
Cc: Jonathan Cameron, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
devicetree, linux-kernel
In-Reply-To: <20260610020458.104818-2-adamianlouis@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 809 bytes --]
On Tue, Jun 09, 2026 at 10:04:57PM -0400, Louis Adamian wrote:
> Create meas,ms5637 devicetree binding and move existing devices from
> trivial-devices.yaml. Explicit compatible strings are added for the
> different sub-variants because each requires different constants for the
> second-order temperature compensation formulas. Previously, the driver
> exposed the generic compatibles for the ms5637, MS5803, MS5805
> and MS5837 families and applied the MS5637-02BA compensation to all of
> them.To preserve the DT ABI the existing compatibles are retained and
> mapped to the -02BA variant of each family (ms5637-02ba, ms5803-02ba,
> ms5837-02ba).
I think this should be made clear by use of fallbacks, or being marked
deprecated with a comment.
pw-bot: changes-requested
Otherwise, it looks okay to me.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v6 6/9] dt-bindings: connector: m2: Add M.2 1620 LGA soldered down connector
From: Manivannan Sadhasivam @ 2026-06-10 16:44 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Mark Pearson, Dmitry Baryshkov, Rob Herring,
Manivannan Sadhasivam, Greg KH, Jiri Slaby, Nathan Chancellor,
Nicolas Schier, Hans de Goede, Ilpo Järvinen,
Derek J . Clark, Krzysztof Kozlowski, Conor Dooley,
Marcel Holtmann, Luiz Augusto von Dentz, Bartosz Golaszewski,
Andy Shevchenko, Bartosz Golaszewski, linux-serial, linux-kernel,
linux-kbuild, platform-driver-x86@vger.kernel.org, linux-pci,
devicetree, linux-arm-msm, linux-bluetooth, linux-pm,
linux-acpi@vger.kernel.org
In-Reply-To: <acv2f1qbqu4PlSL1@linaro.org>
On Tue, Mar 31, 2026 at 06:29:51PM +0200, Stephan Gerhold wrote:
> On Wed, Mar 25, 2026 at 05:36:08PM +0530, Manivannan Sadhasivam wrote:
> > On Mon, Mar 23, 2026 at 01:23:07PM -0400, Mark Pearson wrote:
> > > On Mon, Mar 23, 2026, at 12:52 PM, Manivannan Sadhasivam wrote:
> > > > On Mon, Mar 23, 2026 at 06:45:15PM +0200, Dmitry Baryshkov wrote:
> > > >> On Mon, Mar 23, 2026 at 09:26:04PM +0530, Manivannan Sadhasivam wrote:
> > > >> > On Mon, Mar 23, 2026 at 05:14:30PM +0200, Dmitry Baryshkov wrote:
> > > >> > > On Mon, Mar 23, 2026 at 07:14:25PM +0530, Manivannan Sadhasivam wrote:
> > > >> > > > On Mon, Mar 23, 2026 at 08:39:55AM -0500, Rob Herring wrote:
> > > >> > > > > On Mon, Mar 23, 2026 at 7:16 AM Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > >> > > > > >
> > > >> > > > > > On Sun, Mar 22, 2026 at 06:37:13PM -0500, Rob Herring wrote:
> > > >> > > > > > > On Tue, Mar 17, 2026 at 09:59:56AM +0530, Manivannan Sadhasivam wrote:
> > > >> > > > > > > > Lenovo Thinkpad T14s is found to have a soldered down version of M.2 1620
> > > >> > > > > > > > LGA connector. Though, there is no 1620 LGA form factor defined in the M.2
> > > >> > > > > > > > spec, it looks very similar to the M.2 Key E connector. So add the
> > > >> > > > > > > > "pcie-m2-1620-lga-connector" compatible with "pcie-m2-e-connector" fallback
> > > >> > > > > > > > to reuse the Key E binding.
> > > >> > > > > > >
> > > >> > > > > > > What is LGA?
> > > >> > > > > > >
> > > >> > > > > >
> > > >> > > > > > Land Grid Array
> > > >> > > > > >
> > > >> > > > > > > If not in the spec, is it really something generic?
> > > >> > > > > > >
> > > >> > > > > >
> > > >> > > > > > Good question. Yes and No! LGA is not something that Lenovo only uses. Other
> > > >> > > > > > vendors may also use this form factor. PCIe connectors are full of innovation as
> > > >> > > > > > the spec gives room for hardware designers to be as innovative as possible to
> > > >> > > > > > save the BOM cost.
> > > >> > > > >
> > > >> > > > > innovation == incompatible changes
> > > >> > > > >
> > > >> > > >
> > > >> > > > Yes, I was trying to sound nice :)
> > > >> > > >
> > > >> > > > > > This is why I do not want to make it Lenovo specific. But if you prefer that, I
> > > >> > > > > > can name it as "lenovo,pcie-m2-1620-lga-connector".
> > > >> > > > >
> > > >> > > > > Depends if you think that s/w needs to know the differences. Hard to
> > > >> > > > > say with a sample size of 1.
> > > >> > > > >
> > > >> > > >
> > > >> > > > Sure. Will add the 'lenovo' prefix then.
> > > >> > >
> > > >> > > Is it really Lenovo? Or is it some other module vendor, whose LGAs are
> > > >> > > being used by Lenovo?
> > > >> > >
> > > >> > > I remember that DB820c also used some kind of a module for the WiFi card
> > > >> > > (which might be M.2 compatible or might not, I can't find exact docs at
> > > >> > > this point).
> > > >> > >
> > > >> >
> > > >> > I don't know. These kind of designs might be reused by several vendors. But
> > > >> > considering that we should not make it generic, I'd go with Lenovo as that's
> > > >> > the only vendor we know as of now.
> > > >>
> > > >> ... and later we learn that other vendors use the same idea /pinout,
> > > >> then nothing stops us from still telling that it's a
> > > >> "lenovo,pcie-m2-something-lga".
> > > >>
> > > >
> > > > How do you possibly know whether a single vendor has introduced this form factor
> > > > or reused by multiple ones? Atleast, I don't have access to such a source to
> > > > confirm.
> > > >
> > > I've not really been following this thread/patchset in detail; but want me to try and check with the T14s platform team if this device is specifically made for us (Lenovo) or not?
> > > I doubt it is - we just don't do that usually, but I can go and ask the question if it will help resolve this (with the caveat that it could hold up the review for a bit and I may not be able to get a straight answer)
> > >
> >
> > I can drop this specific patch in the meantime.
> >
> > > My vote (for what little it's worth) would be to make it non-Lenovo specific. Then when the same part causes issues on another vendors platform I won't get asked questions about why Lenovo is breaking <other vendor> :)
> > >
> >
> > Even if Lenovo prefix is used, it won't break other vendors. Just that we will
> > end up adding more compatibles.
> >
> > Anyhow, I'll wait for your reply and drop this patch for next revision.
> >
>
> If you need a vendor prefix, I think "qcom," would be more appropriate
> than Lenovo. This form factor is used by most vendors for recent
> soldered Qualcomm-based wireless cards, not just Lenovo:
>
> - Dell XPS 13 9345 has exactly the same soldered M.2 card, I assume
> there are several other vendors as well.
>
> - https://www.sparklan.com/product/wnsq-290be/ is a third-party
> (Qualcomm-based) M.2 LGA 1620 card, in the block diagram the
> pinout is called "QM.2 1620 LGA 168pin".
>
> - If you press F9 while booting the ThinkPad T14s, you should get to a
> screen with "Regulatory Information". For the T14s, this screen says
> "Contains FCC ID: J9C-QCNCM825". This is the WiFi/BT module in the
> soldered form factor. If you look that up on the FCC website, the
> applicant for this module is "Qualcomm Technologies, Inc.". This
> seems to be some kind of "modular certification" that vendors can
> reuse/adapt without going through the whole process again.
>
> Perhaps you should ask around inside Qualcomm? :-)
>
Sorry for getting back after this long. I did ask around, but our HW folks are
saying that Qcom is not the first one to use LGA M.2 modules. They claim that
other vendors also do that.
But for this specific card, it should be fine to use the 'qcom' prefix as
apparently the module was supplied by Qcom.
I'll submit the bindings patch together with DTS change for T14s.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* [PATCH 2/2] drm/solomon: Add SSD1351 OLED display driver
From: Amit Barzilai @ 2026-06-10 16:44 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, simona
Cc: javierm, robh, krzk+dt, conor+dt, dri-devel, devicetree,
linux-kernel, Amit Barzilai
In-Reply-To: <20260610164428.180091-1-amit.barzilai22@gmail.com>
Add a DRM/KMS driver for the Solomon SSD1351, a 128x128 65k-color RGB
OLED controller driven over a 4-wire SPI bus (clock, data, chip-select
and a Data/Command GPIO).
Unlike the monochrome and grayscale SSD13xx parts handled by the ssd130x
driver, the SSD1351 has a native 16-bit RGB565 frame format, so the
driver uploads pixels as RGB565 rather than down-converting to RGB332.
Its command set (column/row range 0x15/0x75, write-RAM 0x5c) differs from
MIPI DCS, so the generic mipi_dbi helpers cannot be reused for the pixel
path and a small SPI command/data layer is implemented instead.
The driver advertises XRGB8888 to userspace and converts to big-endian
RGB565 on flush via drm_fb_xrgb8888_to_rgb565be(), building on the GEM
SHMEM and atomic modeset/shadow-plane helpers with damage-clipped partial
updates. Panels wired with a BGR sub-pixel order are handled through the
colour remap register.
Also add the DRM_SSD1351 Kconfig/Makefile entries and a MAINTAINERS
record.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Amit Barzilai <amit.barzilai22@gmail.com>
---
MAINTAINERS | 7 +
drivers/gpu/drm/solomon/Kconfig | 14 +
drivers/gpu/drm/solomon/Makefile | 1 +
drivers/gpu/drm/solomon/ssd1351.c | 556 ++++++++++++++++++++++++++++++
4 files changed, 578 insertions(+)
create mode 100644 drivers/gpu/drm/solomon/ssd1351.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e80296449ba..1e2b662c5aed 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8377,6 +8377,13 @@ F: Documentation/devicetree/bindings/display/solomon,ssd-common.yaml
F: Documentation/devicetree/bindings/display/solomon,ssd13*.yaml
F: drivers/gpu/drm/solomon/ssd130x*
+DRM DRIVER FOR SOLOMON SSD1351 OLED DISPLAYS
+M: Amit Barzilai <amit.barzilai22@gmail.com>
+S: Maintained
+T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F: Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
+F: drivers/gpu/drm/solomon/ssd1351.c
+
DRM DRIVER FOR ST-ERICSSON MCDE
M: Linus Walleij <linusw@kernel.org>
S: Maintained
diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig
index 400a6cab3a67..957dc36dc495 100644
--- a/drivers/gpu/drm/solomon/Kconfig
+++ b/drivers/gpu/drm/solomon/Kconfig
@@ -30,3 +30,17 @@ config DRM_SSD130X_SPI
Say Y here if the SSD13xx OLED display is connected via SPI bus.
If M is selected the module will be called ssd130x-spi.
+
+config DRM_SSD1351
+ tristate "DRM support for Solomon SSD1351 OLED displays"
+ depends on DRM && SPI && MMU
+ select DRM_CLIENT_SELECTION
+ select DRM_GEM_SHMEM_HELPER
+ select DRM_KMS_HELPER
+ help
+ DRM driver for the Solomon SSD1351 RGB565 color OLED controller
+ connected via 4-wire SPI. It drives up to a 128x128 65k-color
+ panel and uploads pixels in the controller's native RGB565
+ format, exposing a standard DRM/KMS device to userspace.
+
+ If M is selected the module will be called ssd1351.
diff --git a/drivers/gpu/drm/solomon/Makefile b/drivers/gpu/drm/solomon/Makefile
index b5fc792257d7..35ca60e4cf36 100644
--- a/drivers/gpu/drm/solomon/Makefile
+++ b/drivers/gpu/drm/solomon/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_DRM_SSD130X) += ssd130x.o
obj-$(CONFIG_DRM_SSD130X_I2C) += ssd130x-i2c.o
obj-$(CONFIG_DRM_SSD130X_SPI) += ssd130x-spi.o
+obj-$(CONFIG_DRM_SSD1351) += ssd1351.o
diff --git a/drivers/gpu/drm/solomon/ssd1351.c b/drivers/gpu/drm/solomon/ssd1351.c
new file mode 100644
index 000000000000..7c4a5c461afb
--- /dev/null
+++ b/drivers/gpu/drm/solomon/ssd1351.c
@@ -0,0 +1,556 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * DRM driver for the Solomon SSD1351 RGB565 color OLED controller
+ *
+ * The SSD1351 drives up to a 128x128 65k-color OLED panel over a 4-wire
+ * SPI bus (clock, data, chip-select and a Data/Command GPIO). Unlike the
+ * monochrome and grayscale SSD13xx parts handled by the ssd130x driver,
+ * the SSD1351 has a native 16-bit RGB565 frame format, so this driver
+ * uploads pixels as RGB565 rather than down-converting to RGB332.
+ *
+ * The command set (column/row range 0x15/0x75, write-RAM 0x5c) differs
+ * from MIPI DCS, so the generic mipi_dbi helpers cannot be reused for the
+ * pixel path; a small SPI command/data layer is implemented here instead.
+ *
+ * Author: Amit Barzilai <amit.barzilai22@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/spi/spi.h>
+
+#include <drm/clients/drm_client_setup.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fbdev_shmem.h>
+#include <drm/drm_format_helper.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+#include <drm/drm_rect.h>
+
+#define SSD1351_WIDTH 128
+#define SSD1351_HEIGHT 128
+
+/* Commands */
+#define SSD1351_SET_COL_ADDRESS 0x15
+#define SSD1351_WRITE_RAM 0x5c
+#define SSD1351_SET_ROW_ADDRESS 0x75
+#define SSD1351_SET_REMAP 0xa0
+#define SSD1351_SET_START_LINE 0xa1
+#define SSD1351_SET_DISPLAY_OFFSET 0xa2
+#define SSD1351_SET_DISPLAY_NORMAL 0xa6
+#define SSD1351_SET_FUNCTION 0xab
+#define SSD1351_SET_DISPLAY_OFF 0xae
+#define SSD1351_SET_DISPLAY_ON 0xaf
+#define SSD1351_SET_PHASE_LENGTH 0xb1
+#define SSD1351_SET_CLOCK_DIV 0xb3
+#define SSD1351_SET_VSL 0xb4
+#define SSD1351_SET_GPIO 0xb5
+#define SSD1351_SET_PRECHARGE2 0xb6
+#define SSD1351_SET_PRECHARGE 0xbb
+#define SSD1351_SET_VCOMH 0xbe
+#define SSD1351_SET_CONTRAST 0xc1
+#define SSD1351_SET_CONTRAST_MASTER 0xc7
+#define SSD1351_SET_MUX_RATIO 0xca
+#define SSD1351_SET_COMMAND_LOCK 0xfd
+
+/* Re-map / Color Depth (command 0xa0) bits */
+#define SSD1351_REMAP_COLUMN BIT(1) /* reverse column (SEG) order */
+#define SSD1351_REMAP_COLOR_BGR BIT(2) /* swap sub-pixel color order */
+#define SSD1351_REMAP_COM_SCAN BIT(4) /* reverse COM scan direction */
+#define SSD1351_REMAP_COM_SPLIT BIT(5) /* odd/even COM split */
+#define SSD1351_REMAP_65K BIT(6) /* 65k (RGB565) color depth */
+
+struct ssd1351_device {
+ struct drm_device drm;
+ struct spi_device *spi;
+ struct gpio_desc *reset;
+ struct gpio_desc *dc;
+ u32 rotation;
+
+ /* Scratch buffer holding one frame of RGB565 pixels for SPI upload */
+ u8 *tx_buf;
+
+ struct drm_plane plane;
+ struct drm_crtc crtc;
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+};
+
+static struct ssd1351_device *drm_to_ssd1351(struct drm_device *drm)
+{
+ return container_of(drm, struct ssd1351_device, drm);
+}
+
+/*
+ * SPI access. The D/C GPIO selects whether the bytes shifted out are
+ * interpreted as a command (low) or as data (high).
+ */
+static int ssd1351_write_cmd(struct ssd1351_device *ssd1351, u8 cmd,
+ const u8 *params, size_t num)
+{
+ int ret;
+
+ gpiod_set_value_cansleep(ssd1351->dc, 0);
+ ret = spi_write(ssd1351->spi, &cmd, 1);
+ if (ret)
+ return ret;
+
+ if (num) {
+ gpiod_set_value_cansleep(ssd1351->dc, 1);
+ ret = spi_write(ssd1351->spi, params, num);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Send a command followed by a fixed list of single-byte parameters. */
+#define ssd1351_command(ssd1351, cmd, ...) \
+ ({ \
+ static const u8 _params[] = { __VA_ARGS__ }; \
+ ssd1351_write_cmd((ssd1351), (cmd), _params, \
+ ARRAY_SIZE(_params)); \
+ })
+
+static void ssd1351_reset(struct ssd1351_device *ssd1351)
+{
+ if (!ssd1351->reset)
+ return;
+
+ /*
+ * Work in logical levels: 1 asserts reset, 0 releases it. The DT's
+ * GPIO_ACTIVE_LOW flag handles the physical inversion, so this pulse is
+ * correct regardless of how the board wires the RES# line.
+ */
+ gpiod_set_value_cansleep(ssd1351->reset, 1);
+ usleep_range(20, 1000);
+ gpiod_set_value_cansleep(ssd1351->reset, 0);
+ msleep(120);
+}
+
+static int ssd1351_init_display(struct ssd1351_device *ssd1351)
+{
+ u8 remap = SSD1351_REMAP_65K | SSD1351_REMAP_COM_SPLIT |
+ SSD1351_REMAP_COLOR_BGR;
+ int ret;
+
+ ssd1351_reset(ssd1351);
+
+ /* Unlock the controller and allow access to all command registers */
+ ret = ssd1351_command(ssd1351, SSD1351_SET_COMMAND_LOCK, 0x12);
+ if (ret)
+ return ret;
+ ret = ssd1351_command(ssd1351, SSD1351_SET_COMMAND_LOCK, 0xb1);
+ if (ret)
+ return ret;
+
+ ret = ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_OFF);
+ if (ret)
+ return ret;
+
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_CLOCK_DIV, 0xf1);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_MUX_RATIO, 0x7f);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_COL_ADDRESS, 0x00, 0x7f);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_ROW_ADDRESS, 0x00, 0x7f);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_START_LINE, 0x00);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_OFFSET, 0x00);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_GPIO, 0x00);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_FUNCTION, 0x01);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_PHASE_LENGTH, 0x32);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_VSL, 0xa0, 0xb5, 0x55);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_PRECHARGE, 0x17);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_VCOMH, 0x05);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_CONTRAST, 0xc8, 0x80, 0xc8);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_CONTRAST_MASTER, 0x0f);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_PRECHARGE2, 0x01);
+ ret = ret ?: ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_NORMAL);
+ if (ret)
+ return ret;
+
+ /*
+ * Select 65k (RGB565) color depth and the orientation. 0 and 180 degrees
+ * are reached with the column/COM-scan mirror bits while keeping the
+ * controller in horizontal address-increment mode, which matches the
+ * row-major pixel data produced below. The hardware can also rotate by
+ * 90/270 via the vertical address-increment bit, but that transposes the
+ * upload and would require a transposing blit + window remap that this
+ * driver does not implement; such rotations are rejected at probe.
+ */
+ if (ssd1351->rotation == 180)
+ remap |= SSD1351_REMAP_COLUMN;
+ else
+ remap |= SSD1351_REMAP_COM_SCAN;
+
+ ret = ssd1351_write_cmd(ssd1351, SSD1351_SET_REMAP, &remap, 1);
+ if (ret)
+ return ret;
+
+ return ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_ON);
+}
+
+static void ssd1351_fb_blit_rect(struct ssd1351_device *ssd1351,
+ struct drm_framebuffer *fb,
+ const struct iosys_map *vmap,
+ struct drm_rect *rect,
+ struct drm_format_conv_state *fmtcnv_state)
+{
+ unsigned int width = drm_rect_width(rect);
+ unsigned int height = drm_rect_height(rect);
+ unsigned int dst_pitch = width * sizeof(u16);
+ struct iosys_map dst;
+ u8 range[2];
+
+ iosys_map_set_vaddr(&dst, ssd1351->tx_buf);
+
+ /*
+ * The panel expects RGB565 most-significant byte first; the big-endian
+ * conversion produces exactly that byte stream for the 8-bit SPI words.
+ */
+ drm_fb_xrgb8888_to_rgb565be(&dst, &dst_pitch, vmap, fb, rect,
+ fmtcnv_state);
+
+ range[0] = rect->x1;
+ range[1] = rect->x2 - 1;
+ if (ssd1351_write_cmd(ssd1351, SSD1351_SET_COL_ADDRESS, range,
+ sizeof(range)))
+ return;
+
+ range[0] = rect->y1;
+ range[1] = rect->y2 - 1;
+ if (ssd1351_write_cmd(ssd1351, SSD1351_SET_ROW_ADDRESS, range,
+ sizeof(range)))
+ return;
+
+ ssd1351_write_cmd(ssd1351, SSD1351_WRITE_RAM, ssd1351->tx_buf,
+ width * height * sizeof(u16));
+}
+
+/*
+ * Plane
+ */
+
+static int ssd1351_plane_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane_state *plane_state =
+ drm_atomic_get_new_plane_state(state, plane);
+ struct drm_crtc *crtc = plane_state->crtc;
+ struct drm_crtc_state *crtc_state = NULL;
+
+ if (crtc)
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+
+ return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING, false,
+ false);
+}
+
+static void ssd1351_plane_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane_state *plane_state =
+ drm_atomic_get_new_plane_state(state, plane);
+ struct drm_plane_state *old_plane_state =
+ drm_atomic_get_old_plane_state(state, plane);
+ struct drm_shadow_plane_state *shadow_plane_state =
+ to_drm_shadow_plane_state(plane_state);
+ struct ssd1351_device *ssd1351 = drm_to_ssd1351(plane->dev);
+ struct drm_framebuffer *fb = plane_state->fb;
+ struct drm_atomic_helper_damage_iter iter;
+ struct drm_rect damage;
+ struct drm_rect dst_clip;
+ int idx;
+
+ if (!fb)
+ return;
+
+ if (!drm_dev_enter(&ssd1351->drm, &idx))
+ return;
+
+ if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE))
+ goto out_drm_dev_exit;
+
+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
+ drm_atomic_for_each_plane_damage(&iter, &damage) {
+ dst_clip = plane_state->dst;
+
+ if (!drm_rect_intersect(&dst_clip, &damage))
+ continue;
+
+ ssd1351_fb_blit_rect(ssd1351, fb, &shadow_plane_state->data[0],
+ &dst_clip,
+ &shadow_plane_state->fmtcnv_state);
+ }
+
+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
+
+out_drm_dev_exit:
+ drm_dev_exit(idx);
+}
+
+static const struct drm_plane_helper_funcs ssd1351_plane_helper_funcs = {
+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
+ .atomic_check = ssd1351_plane_atomic_check,
+ .atomic_update = ssd1351_plane_atomic_update,
+};
+
+static const struct drm_plane_funcs ssd1351_plane_funcs = {
+ DRM_GEM_SHADOW_PLANE_FUNCS,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = drm_plane_cleanup,
+};
+
+static const u32 ssd1351_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+/*
+ * CRTC
+ */
+
+static void ssd1351_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct ssd1351_device *ssd1351 = drm_to_ssd1351(crtc->dev);
+ int idx, ret;
+
+ if (!drm_dev_enter(crtc->dev, &idx))
+ return;
+
+ ret = ssd1351_init_display(ssd1351);
+ if (ret)
+ drm_err(crtc->dev, "Failed to initialize display: %d\n", ret);
+
+ drm_dev_exit(idx);
+}
+
+static void ssd1351_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct ssd1351_device *ssd1351 = drm_to_ssd1351(crtc->dev);
+ int idx;
+
+ if (!drm_dev_enter(crtc->dev, &idx))
+ return;
+
+ ssd1351_command(ssd1351, SSD1351_SET_DISPLAY_OFF);
+
+ drm_dev_exit(idx);
+}
+
+static const struct drm_crtc_helper_funcs ssd1351_crtc_helper_funcs = {
+ .atomic_check = drm_crtc_helper_atomic_check,
+ .atomic_enable = ssd1351_crtc_atomic_enable,
+ .atomic_disable = ssd1351_crtc_atomic_disable,
+};
+
+static const struct drm_crtc_funcs ssd1351_crtc_funcs = {
+ .reset = drm_atomic_helper_crtc_reset,
+ .destroy = drm_crtc_cleanup,
+ .set_config = drm_atomic_helper_set_config,
+ .page_flip = drm_atomic_helper_page_flip,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+/*
+ * Encoder
+ */
+
+static const struct drm_encoder_funcs ssd1351_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+/*
+ * Connector
+ */
+
+static const struct drm_display_mode ssd1351_mode = {
+ DRM_SIMPLE_MODE(SSD1351_WIDTH, SSD1351_HEIGHT, 24, 24),
+};
+
+static int ssd1351_connector_get_modes(struct drm_connector *connector)
+{
+ return drm_connector_helper_get_modes_fixed(connector, &ssd1351_mode);
+}
+
+static const struct drm_connector_helper_funcs ssd1351_connector_helper_funcs = {
+ .get_modes = ssd1351_connector_get_modes,
+};
+
+static const struct drm_connector_funcs ssd1351_connector_funcs = {
+ .reset = drm_atomic_helper_connector_reset,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_mode_config_funcs ssd1351_mode_config_funcs = {
+ .fb_create = drm_gem_fb_create_with_dirty,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+/*
+ * Driver
+ */
+
+DEFINE_DRM_GEM_FOPS(ssd1351_fops);
+
+static const struct drm_driver ssd1351_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+ .fops = &ssd1351_fops,
+ DRM_GEM_SHMEM_DRIVER_OPS,
+ DRM_FBDEV_SHMEM_DRIVER_OPS,
+ .name = "ssd1351",
+ .desc = "Solomon SSD1351",
+ .major = 1,
+ .minor = 0,
+};
+
+static int ssd1351_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct ssd1351_device *ssd1351;
+ struct drm_device *drm;
+ int ret;
+
+ ssd1351 = devm_drm_dev_alloc(dev, &ssd1351_driver,
+ struct ssd1351_device, drm);
+ if (IS_ERR(ssd1351))
+ return PTR_ERR(ssd1351);
+
+ drm = &ssd1351->drm;
+ ssd1351->spi = spi;
+ spi_set_drvdata(spi, drm);
+
+ ssd1351->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ssd1351->reset))
+ return dev_err_probe(dev, PTR_ERR(ssd1351->reset),
+ "Failed to get reset GPIO\n");
+
+ ssd1351->dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
+ if (IS_ERR(ssd1351->dc))
+ return dev_err_probe(dev, PTR_ERR(ssd1351->dc),
+ "Failed to get D/C GPIO\n");
+
+ device_property_read_u32(dev, "rotation", &ssd1351->rotation);
+ if (ssd1351->rotation != 0 && ssd1351->rotation != 180)
+ return dev_err_probe(dev, -EINVAL,
+ "Unsupported rotation %u; only 0 and 180 are supported\n",
+ ssd1351->rotation);
+
+ ssd1351->tx_buf = devm_kmalloc(dev,
+ SSD1351_WIDTH * SSD1351_HEIGHT * sizeof(u16),
+ GFP_KERNEL);
+ if (!ssd1351->tx_buf)
+ return -ENOMEM;
+
+ ret = drmm_mode_config_init(drm);
+ if (ret)
+ return ret;
+
+ drm->mode_config.min_width = SSD1351_WIDTH;
+ drm->mode_config.max_width = SSD1351_WIDTH;
+ drm->mode_config.min_height = SSD1351_HEIGHT;
+ drm->mode_config.max_height = SSD1351_HEIGHT;
+ drm->mode_config.preferred_depth = 24;
+ drm->mode_config.funcs = &ssd1351_mode_config_funcs;
+
+ ret = drm_universal_plane_init(drm, &ssd1351->plane, 0,
+ &ssd1351_plane_funcs, ssd1351_formats,
+ ARRAY_SIZE(ssd1351_formats), NULL,
+ DRM_PLANE_TYPE_PRIMARY, NULL);
+ if (ret)
+ return ret;
+ drm_plane_helper_add(&ssd1351->plane, &ssd1351_plane_helper_funcs);
+ drm_plane_enable_fb_damage_clips(&ssd1351->plane);
+
+ ret = drm_crtc_init_with_planes(drm, &ssd1351->crtc, &ssd1351->plane,
+ NULL, &ssd1351_crtc_funcs, NULL);
+ if (ret)
+ return ret;
+ drm_crtc_helper_add(&ssd1351->crtc, &ssd1351_crtc_helper_funcs);
+
+ ret = drm_encoder_init(drm, &ssd1351->encoder, &ssd1351_encoder_funcs,
+ DRM_MODE_ENCODER_NONE, NULL);
+ if (ret)
+ return ret;
+ ssd1351->encoder.possible_crtcs = drm_crtc_mask(&ssd1351->crtc);
+
+ ret = drm_connector_init(drm, &ssd1351->connector,
+ &ssd1351_connector_funcs,
+ DRM_MODE_CONNECTOR_SPI);
+ if (ret)
+ return ret;
+ drm_connector_helper_add(&ssd1351->connector,
+ &ssd1351_connector_helper_funcs);
+
+ ret = drm_connector_attach_encoder(&ssd1351->connector,
+ &ssd1351->encoder);
+ if (ret)
+ return ret;
+
+ drm_mode_config_reset(drm);
+
+ ret = drm_dev_register(drm, 0);
+ if (ret)
+ return ret;
+
+ drm_client_setup(drm, NULL);
+
+ return 0;
+}
+
+static void ssd1351_remove(struct spi_device *spi)
+{
+ struct drm_device *drm = spi_get_drvdata(spi);
+
+ drm_dev_unplug(drm);
+ drm_atomic_helper_shutdown(drm);
+}
+
+static void ssd1351_shutdown(struct spi_device *spi)
+{
+ drm_atomic_helper_shutdown(spi_get_drvdata(spi));
+}
+
+static const struct of_device_id ssd1351_of_match[] = {
+ { .compatible = "solomon,ssd1351" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ssd1351_of_match);
+
+static const struct spi_device_id ssd1351_id[] = { { "ssd1351", 0 }, {} };
+MODULE_DEVICE_TABLE(spi, ssd1351_id);
+
+static struct spi_driver ssd1351_spi_driver = {
+ .driver = {
+ .name = "ssd1351",
+ .of_match_table = ssd1351_of_match,
+ },
+ .id_table = ssd1351_id,
+ .probe = ssd1351_probe,
+ .remove = ssd1351_remove,
+ .shutdown = ssd1351_shutdown,
+};
+module_spi_driver(ssd1351_spi_driver);
+
+MODULE_DESCRIPTION("Solomon SSD1351 DRM driver");
+MODULE_AUTHOR("Amit Barzilai <amit.barzilai22@gmail.com>");
+MODULE_LICENSE("GPL");
--
2.54.0
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: display: Add Solomon SSD1351 OLED controller
From: Amit Barzilai @ 2026-06-10 16:44 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, simona
Cc: javierm, robh, krzk+dt, conor+dt, dri-devel, devicetree,
linux-kernel, Amit Barzilai
In-Reply-To: <20260610164428.180091-1-amit.barzilai22@gmail.com>
Add a device tree binding for the Solomon SSD1351, a 128x128 65k-color
RGB OLED display controller driven over a 4-wire SPI bus. The binding
builds on the shared solomon,ssd-common.yaml properties already used by
the other Solomon display controllers.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Amit Barzilai <amit.barzilai22@gmail.com>
---
.../bindings/display/solomon,ssd1351.yaml | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
new file mode 100644
index 000000000000..a7d77132faa6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/solomon,ssd1351.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Solomon SSD1351 OLED Display Controller
+
+maintainers:
+ - Amit Barzilai <amit.barzilai22@gmail.com>
+
+allOf:
+ - $ref: solomon,ssd-common.yaml#
+
+properties:
+ compatible:
+ enum:
+ - solomon,ssd1351
+
+ solomon,width:
+ default: 128
+
+ solomon,height:
+ default: 128
+
+ rotation: true
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ oled@0 {
+ compatible = "solomon,ssd1351";
+ reg = <0x0>;
+ reset-gpios = <&gpio2 7>;
+ dc-gpios = <&gpio2 8>;
+ spi-max-frequency = <10000000>;
+ };
+ };
--
2.54.0
^ permalink raw reply related
* [PATCH 0/2] drm: Add driver for the Solomon SSD1351 OLED controller
From: Amit Barzilai @ 2026-06-10 16:44 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, simona
Cc: javierm, robh, krzk+dt, conor+dt, dri-devel, devicetree,
linux-kernel, Amit Barzilai
This series adds a new DRM/KMS driver for the Solomon SSD1351, a 128x128
65k-color RGB OLED controller driven over a 4-wire SPI bus. The SSD1351
currently has no DRM driver; the only in-tree support is the legacy fbtft
fb_ssd1351.
The driver advertises XRGB8888 to userspace and converts to big-endian
RGB565 on flush via drm_fb_xrgb8888_to_rgb565be(), building on the GEM
SHMEM and atomic modeset/shadow-plane helpers with damage-clipped partial
updates.
The SSD1351 is implemented as a standalone driver rather than as part of
ssd130x. ssd130x converts XRGB8888 down to a packed <= 8bpp hardware
format (mono, grayscale, or 256-colour RGB332); the SSD1351 is driven in
its native 65k-colour RGB565 and does not fit that pixel pipeline.
For the record, the generic mipi_dbi helpers do not apply either: the
SSD1351 pixel path uses non-DCS opcodes (window 0x15/0x75 and write-RAM
0x5c rather than DCS 0x2a/0x2b/0x2c).
Smoke-tested on a Raspberry Pi 4 driving a 128x128 SSD1351 panel: the
display initialises and shows correct colours. The panel's sub-pixel
colour order is set in the controller's remap register, hardcoded to match
the tested module (as the ili9341/ili9163/mi0283qt tinydrm drivers do for
their panels).
Patch 1 adds the device tree binding; patch 2 adds the driver together
with the Kconfig/Makefile glue and a MAINTAINERS entry.
Amit Barzilai (2):
dt-bindings: display: Add Solomon SSD1351 OLED controller
drm/solomon: Add SSD1351 OLED display driver
.../bindings/display/solomon,ssd1351.yaml | 47 ++
MAINTAINERS | 7 +
drivers/gpu/drm/solomon/Kconfig | 14 +
drivers/gpu/drm/solomon/Makefile | 1 +
drivers/gpu/drm/solomon/ssd1351.c | 556 ++++++++++++++++++
5 files changed, 625 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/solomon,ssd1351.yaml
create mode 100644 drivers/gpu/drm/solomon/ssd1351.c
base-commit: 83e8d8bbffa8161e94f3aeee4dd09a35062a78c8
--
2.54.0
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add HINLINK H28K
From: Conor Dooley @ 2026-06-10 16:43 UTC (permalink / raw)
To: Chukun Pan
Cc: Heiko Stuebner, Rob Herring, Conor Dooley, Krzysztof Kozlowski,
linux-arm-kernel, linux-rockchip, linux-kernel, devicetree
In-Reply-To: <20260610100006.366963-2-amadeus@jmu.edu.cn>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] arm64: dts: qcom: monaco-arduino-monza: Add QCA2066 M.2 WiFi/BT support
From: Manivannan Sadhasivam @ 2026-06-10 16:42 UTC (permalink / raw)
To: Loic Poulain
Cc: Dmitry Baryshkov, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-pci,
linux-pm, linux-kernel, linux-arm-msm, linux-bluetooth,
devicetree
In-Reply-To: <CAFEp6-3Gbd1gzfeu5xdfBJixL6JXaoSFkRUsBjOji0ZEOHHyvw@mail.gmail.com>
On Wed, May 20, 2026 at 04:41:18PM +0200, Loic Poulain wrote:
> On Wed, May 20, 2026 at 4:36 PM Dmitry Baryshkov
> <dmitry.baryshkov@oss.qualcomm.com> wrote:
> >
> > On Wed, May 20, 2026 at 04:29:40PM +0200, Loic Poulain wrote:
> > > On Wed, May 20, 2026 at 2:34 PM Dmitry Baryshkov
> > > <dmitry.baryshkov@oss.qualcomm.com> wrote:
> > > >
> > > > On Wed, May 20, 2026 at 01:01:44PM +0200, Loic Poulain wrote:
> > > > > Add support for the QCA2066 (QCNFA765) WiFi/Bluetooth module on the
> > > > > Arduino VENTUNO Q board. The module is interfaced via LGA and is
> > > > > compatible with the M.2 Key E.
> > > > >
> > > > > Add wireless-lga-connector node using pcie-m2-e-connector binding,
> > > > > connecting PCIe port 0 to the WiFi interface and UART10 port 3 to
> > > > > the Bluetooth interface.
> > > > >
> > > > > Add pcie@1,0 downstream port node with pciclass,0604 compatible so
> > > > > the pci-pwrctrl driver can acquire the power sequencer and enable
> > > > > the M.2 slot before PCIe enumeration.
> > > > >
> > > > > Add nfa725b_default_state pinctrl for the W_DISABLE1/2 GPIOs
> > > > > (gpio56/gpio55) used by the power sequencer.
> > > > >
> > > > > Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> > > > > ---
> > > > > arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts | 65 +++++++++++++++++++++++
> > > > > 1 file changed, 65 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> > > > > index 93ed575817af1c5e903662c209ead629fe202ee2..6fcad77f320cb82eccb6f07244d185abfb1976d9 100644
> > > > > --- a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> > > > > +++ b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
> > > > > @@ -154,6 +154,39 @@ vreg_nvme: regulator-3p3-m2 {
> > > > > enable-active-high;
> > > > > startup-delay-us = <20000>;
> > > > > };
> > > > > +
> > > > > + wireless-lga-connector {
> > > > > + compatible = "pcie-m2-e-connector";
> > > >
> > > > I think it was discussed that LGA can't be an actual M.2 E-key
> > > > connector.
> > >
> > > I am not sure I followed this discussion. Do you mean that I should
> > > introduce a dedicated LGA/vendor-compatible string in the compatible
> > > list of the pcie-m2-e-connector binding, or that LGA-based designs
> > > should not be described using the pcie-m2-e-connector binding (graph
> > > representation)?
> >
> > I think, it should be a separate, vendor-specific compat (maybe using
> > m2-e as a fallback).
>
You can use "qcom,pcie-m2-<size>-lga-connector", where size depends on the
module size, like 1620.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH] dt-bindings: iio: accel: Convert lis302 binding to YAML schema
From: Conor Dooley @ 2026-06-10 16:40 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Md Shofiqul Islam, linux-iio, devicetree, dlechner, nuno.sa, andy,
robh, krzk+dt, conor+dt, krzk, linux-kernel
In-Reply-To: <20260610165640.411c1477@jic23-huawei>
[-- Attachment #1: Type: text/plain, Size: 2324 bytes --]
On Wed, Jun 10, 2026 at 04:56:40PM +0100, Jonathan Cameron wrote:
> On Wed, 10 Jun 2026 14:00:51 +0300
> Md Shofiqul Islam <shofiqtest@gmail.com> wrote:
>
> > Convert the STMicroelectronics LIS302DL/LIS3LV02D accelerometer device
> > tree binding from plain text format to YAML schema format.
> >
> > The binding covers two variants matched via their respective bus drivers:
> > - SPI: st,lis302dl-spi (drivers/misc/lis3lv02d/lis3lv02d_spi.c)
> > - I2C: st,lis3lv02d (drivers/misc/lis3lv02d/lis3lv02d_i2c.c)
> >
> > Document all vendor-specific properties read by the driver via
> > of_property_read_*(), including click detection, IRQ routing, free-fall/
> > wake-up engines, high-pass filtering, axis remapping, output data rate,
> > and self-test limits.
> >
> > Also correct the click threshold property names: the driver reads
> > "st,click-threshold-{x,y,z}" but the old .txt documented them as
> > "st,click-thresh-{x,y,z}".
> >
> > Validated with: make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/iio/accel/st,lis302dl.yaml
> >
> > Signed-off-by: Md Shofiqul Islam <shofiqtest@gmail.com>
>
> Hi.
>
> So the conundrum here is whether we want to keep carrying this binding
> as it dates to a previous era.
>
> The driver never made it to IIO and is still in drivers/misc.
> The majority of what is the text document should never have been
> in DT in the first place. I'll guess this dates all the way back
> to the wild west days before we had regular binding review.
I'd say this should be treated like a staging binding but for the fact
that this has a user in arm. Problem of course is that it's probably
impossible to get that board and so doing any rework is probably not
realistic for this submitter?
Is there a general policy for iio devices in misc? Do they get reworked
to be moved?
The user funnily enough has the binding's click-thresh properties:
st,click-single-x;
st,click-single-y;
st,click-single-z;
st,click-thresh-x = <10>;
st,click-thresh-y = <10>;
st,click-thresh-z = <10>;
st,irq1-click;
st,irq2-click;
st,wakeup-x-lo;
st,wakeup-x-hi;
st,wakeup-y-lo;
st,wakeup-y-hi;
st,wakeup-z-lo;
st,wakeup-z-hi;
Dunno what that ultimately means in terms of which should be used
though.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: soc: sophgo: add Milk-V Duo 256M board
From: Conor Dooley @ 2026-06-10 16:34 UTC (permalink / raw)
To: Chen-Yu Yeh
Cc: unicorn_wang, inochiama, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Nutty Liu, Han Gao, Alexander Sverdlin, Chao Wei,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list:SOPHGO DEVICETREES and DRIVERS, open list
In-Reply-To: <20260610121026.1517621-1-chenyou910331@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: (subset) [PATCH v3 0/3] PCI: qcom: Add support for Eliza
From: Manivannan Sadhasivam @ 2026-06-10 16:34 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Bjorn Helgaas, Bjorn Andersson, Krishna Chaitanya Chundru
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Krzysztof Kozlowski, Dmitry Baryshkov
In-Reply-To: <20260608-eliza-v3-0-9bdeb7434b28@oss.qualcomm.com>
On Mon, 08 Jun 2026 14:18:12 +0530, Krishna Chaitanya Chundru wrote:
> This series adds PCIe support for the Qualcomm Eliza SoC. Eliza includes
> two PCIe root complex controllers capable of 8GT/s x1 and 8GT/s x2.
>
> The QMP PCIe PHY support adds a new Gen3x1 PHY configuration with
> Eliza-specific initialization tables, and reuses the existing SM8550
> Gen3x2 configuration for the x2 PHY instance.
>
> [...]
Applied, thanks!
[2/3] dt-bindings: PCI: qcom,pcie-sm8550: Add Eliza compatible
commit: d233626c009a515fb3ed823fcd78cee432701d1e
Best regards,
--
Manivannan Sadhasivam <mani@kernel.org>
^ permalink raw reply
* Re: [PATCH 7/8] dt-bindings: input: microchip,cap11xx: Add CAP1114 support
From: Conor Dooley @ 2026-06-10 16:34 UTC (permalink / raw)
To: Jun Yan
Cc: conor+dt, devicetree, dmitry.torokhov, krzk+dt, linux-input,
linux-kernel, robh
In-Reply-To: <20260610133458.970174-1-jerrysteve1101@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1751 bytes --]
On Wed, Jun 10, 2026 at 09:34:58PM +0800, Jun Yan wrote:
> > > > > + threshold, so counts differ.
> > > > > =3D20
> > > > > microchip,calib-sensitivity:
> > > > > $ref: /schemas/types.yaml#/definitions/uint32-array
> > > > > @@ -149,7 +153,7 @@ patternProperties:
> > > > > reg:
> > > > > description: LED channel number
> > > > > minimum: 0
> > > > > - maximum: 7
> > > > > + maximum: 10
> > > > > =3D20
> > > > > required:
> > > > > - reg
> > > > > @@ -199,6 +203,19 @@ allOf:
> > > > > reg:
> > > > > maximum: 1
> > > > > =3D20
> > > > > + - if:
> > > > > + properties:
> > > > > + compatible:
> > > > > + contains:
> > > > > + enum:
> > > > > + - microchip,cap1188
> > > >=20
> > > > I don't understand this restriction, shouldn't this be
> > > > if: properties: compatible: not: contains: microchip,cap1114
> > > > so that the constraints before your change are retained?
> > > >=20
> > >=20
> > > Previously, the LED reg property had a default maximum of 7 for CAP1188.=
> > =20
> > > With the addition of CAP1114, the default maximum is now 11.=20
> > > An if-then constraint is added to limit the LED count for CAP1188.
> >
> > Ah, is this because cap1188 is the only existing device in the binding
> > that actually has LEDs?
>
> - CAP1126: max 2 LED channels (0-1)
> - CAP1188: max 8 LED channels (0-7)
> - CAP1106, CAP12xx: no LED support
>
> The LED reg property constraints for CAP1126 were added in Patch 3 [1].
>
> [1] https://lore.kernel.org/linux-input/20260606150458.250606-4-jerrysteve1101@gmail.com/
Okay, that makes more sense now. Thanks.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 2/3] dt-bindings: arm: rockchip: Add Youyeetoo YY3588
From: Conor Dooley @ 2026-06-10 16:33 UTC (permalink / raw)
To: Daniele Briguglio
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
devicetree, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260610-yy3588-board-v1-2-4bb7176b6826@superkali.me>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: vendor-prefixes: Add youyeetoo
From: Conor Dooley @ 2026-06-10 16:33 UTC (permalink / raw)
To: Daniele Briguglio
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
devicetree, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260610-yy3588-board-v1-1-4bb7176b6826@superkali.me>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 3/3] phy: qcom: qmp-pcie: Add QMP PCIe PHY support for Eliza
From: Manivannan Sadhasivam @ 2026-06-10 16:32 UTC (permalink / raw)
To: Krishna Chaitanya Chundru
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Bjorn Helgaas, Bjorn Andersson, linux-arm-msm, linux-phy,
devicetree, linux-kernel, linux-pci, Dmitry Baryshkov
In-Reply-To: <20260608-eliza-v3-3-9bdeb7434b28@oss.qualcomm.com>
On Mon, Jun 08, 2026 at 02:18:15PM +0530, Krishna Chaitanya Chundru wrote:
> Add QMP PCIe PHY support for the Eliza SoC. Introduce a new Gen3x1 PHY
> configuration with Eliza-specific initialization tables, and reuse the
> existing sm8550 Gen3x2 configuration for the Gen3x2 PHY instance.
>
> Also add the missing QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1 register
> definition to the PCIe V6 PCS header.
>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
- Mani
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 139 ++++++++++++++++++++++++
> drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h | 1 +
> 2 files changed, 140 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index fed2fc9bb311..257b4df965c3 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> @@ -198,6 +198,112 @@ static const struct qmp_phy_init_tbl msm8998_pcie_pcs_tbl[] = {
> QMP_PHY_INIT_CFG(QPHY_V3_PCS_SIGDET_CNTRL, 0x03),
> };
>
> +static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_serdes_tbl[] = {
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x93),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x0a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x1a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x34),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x55),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0x55),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE1, 0xb4),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE1, 0x03),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xf8),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x04),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0d),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xaa),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE0, 0x24),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
> + QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_3, 0x0f),
> +};
> +
> +static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_pcs_tbl[] = {
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_REFGEN_REQ_CONFIG1, 0x05),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_G3S2_PRE_GAIN, 0x2e),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_RX_SIGDET_LVL, 0x77),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_RATE_SLEW_CNTRL1, 0x0b),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_PCS_TX_RX_CONFIG, 0x0c),
> + QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG2, 0x0f),
> +};
> +
> +static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_misc_pcs_tbl[] = {
> + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
> + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
> + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
> + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
> + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27),
> +};
> +
> +static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_tx_tbl[] = {
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x17),
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x06),
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x15),
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_4, 0x3f),
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RCV_DETECT_LVL_2, 0x12),
> + QMP_PHY_INIT_CFG(QSERDES_V6_TX_PI_QEC_CTRL, 0x02),
> +};
> +
> +static const struct qmp_phy_init_tbl eliza_qmp_gen3x1_pcie_rx_tbl[] = {
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_FO_GAIN, 0x09),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_GAIN, 0x05),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_PI_CONTROLS, 0xf0),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH1, 0x08),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_UCDR_SB2_THRESH2, 0x08),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_AUX_DATA_TCOARSE_TFINE, 0x30),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_TX_ADAPT_POST_THRESH, 0xf0),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL1, 0x04),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_VGA_CAL_CNTRL2, 0x0f),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_GM_CAL, 0x0d),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_IDAC_TSETTLE_LOW, 0x07),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIDGET_ENABLES, 0x0c),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_LOW, 0x3f),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH, 0xbf),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH2, 0xbf),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH3, 0xb7),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_00_HIGH4, 0xea),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_LOW, 0xdc),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH, 0x5c),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH2, 0x9c),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH3, 0x1a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_01_HIGH4, 0x89),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH, 0x94),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH2, 0x5b),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH3, 0x1a),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_RX_MODE_10_HIGH4, 0x89),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
> + QMP_PHY_INIT_CFG(QSERDES_V6_RX_SIGDET_CAL_TRIM, 0x08),
> +};
> +
> static const struct qmp_phy_init_tbl ipq6018_pcie_serdes_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
> QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
> @@ -3532,6 +3638,33 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = {
> .txrxz = 0xd000,
> };
>
> +static const struct qmp_phy_cfg eliza_qmp_gen3x1_pciephy_cfg = {
> + .lanes = 1,
> +
> + .offsets = &qmp_pcie_offsets_v5,
> +
> + .tbls = {
> + .serdes = eliza_qmp_gen3x1_pcie_serdes_tbl,
> + .serdes_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_serdes_tbl),
> + .tx = eliza_qmp_gen3x1_pcie_tx_tbl,
> + .tx_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_tx_tbl),
> + .rx = eliza_qmp_gen3x1_pcie_rx_tbl,
> + .rx_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_rx_tbl),
> + .pcs = eliza_qmp_gen3x1_pcie_pcs_tbl,
> + .pcs_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_pcs_tbl),
> + .pcs_misc = eliza_qmp_gen3x1_pcie_misc_pcs_tbl,
> + .pcs_misc_num = ARRAY_SIZE(eliza_qmp_gen3x1_pcie_misc_pcs_tbl),
> + },
> + .reset_list = sdm845_pciephy_reset_l,
> + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
> + .vreg_list = qmp_phy_vreg_l,
> + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
> + .regs = pciephy_v6_regs_layout,
> +
> + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
> + .phy_status = PHYSTATUS,
> +};
> +
> static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
> .lanes = 1,
>
> @@ -5399,6 +5532,12 @@ static int qmp_pcie_probe(struct platform_device *pdev)
>
> static const struct of_device_id qmp_pcie_of_match_table[] = {
> {
> + .compatible = "qcom,eliza-qmp-gen3x1-pcie-phy",
> + .data = &eliza_qmp_gen3x1_pciephy_cfg,
> + }, {
> + .compatible = "qcom,eliza-qmp-gen3x2-pcie-phy",
> + .data = &sm8550_qmp_gen3x2_pciephy_cfg,
> + }, {
> .compatible = "qcom,glymur-qmp-gen4x2-pcie-phy",
> .data = &glymur_qmp_gen4x2_pciephy_cfg,
> }, {
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
> index 45397cb3c0c6..17a0f9d18acf 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v6.h
> @@ -12,6 +12,7 @@
> #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
> #define QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4 0x14
> #define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
> +#define QPHY_PCIE_V6_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x54
> #define QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
>
> #define QPHY_PCIE_V6_PCS_LANE1_INSIG_SW_CTRL2 0x024
>
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: phy: sc8280xp-qmp-pcie: Document Eliza PCIe phy
From: Manivannan Sadhasivam @ 2026-06-10 16:31 UTC (permalink / raw)
To: Krishna Chaitanya Chundru
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lorenzo Pieralisi, Krzysztof Wilczyński,
Bjorn Helgaas, Bjorn Andersson, linux-arm-msm, linux-phy,
devicetree, linux-kernel, linux-pci, Krzysztof Kozlowski
In-Reply-To: <20260608-eliza-v3-1-9bdeb7434b28@oss.qualcomm.com>
On Mon, Jun 08, 2026 at 02:18:13PM +0530, Krishna Chaitanya Chundru wrote:
> Add compatibles for the Eliza PCIe QMP PHY's, which supports Gen3x1 and
> Gen3x2 configurations.
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
- Mani
> ---
> .../devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> index 3a35120a77ec..be4bbc327982 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -16,6 +16,8 @@ description:
> properties:
> compatible:
> enum:
> + - qcom,eliza-qmp-gen3x1-pcie-phy
> + - qcom,eliza-qmp-gen3x2-pcie-phy
> - qcom,glymur-qmp-gen4x2-pcie-phy
> - qcom,glymur-qmp-gen5x4-pcie-phy
> - qcom,kaanapali-qmp-gen3x2-pcie-phy
> @@ -181,6 +183,8 @@ allOf:
> compatible:
> contains:
> enum:
> + - qcom,eliza-qmp-gen3x1-pcie-phy
> + - qcom,eliza-qmp-gen3x2-pcie-phy
> - qcom,glymur-qmp-gen4x2-pcie-phy
> - qcom,glymur-qmp-gen5x4-pcie-phy
> - qcom,qcs8300-qmp-gen4x2-pcie-phy
> @@ -206,6 +210,8 @@ allOf:
> compatible:
> contains:
> enum:
> + - qcom,eliza-qmp-gen3x1-pcie-phy
> + - qcom,eliza-qmp-gen3x2-pcie-phy
> - qcom,glymur-qmp-gen4x2-pcie-phy
> - qcom,glymur-qmp-gen5x4-pcie-phy
> - qcom,kaanapali-qmp-gen3x2-pcie-phy
>
> --
> 2.34.1
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v4 3/3] arm64: dts: nuvoton: npcm845-evb: Add peripheral nodes
From: sashiko-bot @ 2026-06-10 16:23 UTC (permalink / raw)
To: Tomer Maimon; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260610160816.2828713-4-tmaimon77@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Missing `/bits/ 8` for `fan-tach-ch` and `cooling-levels` causes incorrect 32-bit integer array emission, corrupting the thermal fan driver state.
- [High] The `tip_reserved` memory node lacks the `no-map` directive, causing speculative external aborts.
- [Medium] Incorrect Device Tree property name `spix-mode` prevents the FIU controller from enabling SPIX mode.
--
commit 011b4946d76e73a81f86b002033d53a6d052bd40
Author: Tomer Maimon <tmaimon77@gmail.com>
arm64: dts: nuvoton: npcm845-evb: Add peripheral nodes
Enable peripheral support for the NPCM845 evaluation board by wiring up
the SoC controller nodes to the board design.
> diff --git a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
> index 5edf5d13342da..ea92888d9b9e2 100644
> --- a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
> +++ b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
[ ... ]
> @@ -26,12 +62,389 @@ refclk: refclk-25mhz {
> clock-frequency = <25000000>;
> #clock-cells = <0>;
> };
> +
> + reserved-memory {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + tip_reserved: tip@0 {
> + reg = <0x0 0x0 0x0 0x6200000>;
[Severity: High]
Does this reserved memory region need the no-map directive?
Without no-map, the kernel establishes a direct, cacheable linear mapping
over this region. Since this block is isolated by hardware firewalls for the
Trusted Information Processing firmware, could speculative execution or
prefetching by the CPU into this linear mapping trigger fatal synchronous
external aborts or SErrors?
> + };
> + };
[ ... ]
> +&fiux {
> + spix-mode;
[Severity: Medium]
Is this property missing the vendor prefix?
The SPI driver for the NPCM FIU (drivers/spi/spi-npcm-fiu.c) appears to
check specifically for the "nuvoton,spix-mode" property. If it is only named
"spix-mode" here, will the driver fail to detect it and silently fall back
to standard mode?
> +};
[ ... ]
> +&pwm_fan {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pwm0_pins &pwm1_pins
> + &pwm2_pins &pwm3_pins
> + &pwm4_pins &pwm5_pins
> + &pwm6_pins &pwm7_pins
> + &fanin0_pins &fanin1_pins
> + &fanin2_pins &fanin3_pins
> + &fanin4_pins &fanin5_pins
> + &fanin6_pins &fanin7_pins>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + fan@0 {
> + reg = <0x00>;
> + fan-tach-ch = <0x0 0x1>;
> + cooling-levels = <127 255>;
[Severity: High]
Should these arrays be explicitly sized using /bits/ 8?
The Device Tree compiler natively emits 32-bit big-endian integers for this
syntax. However, if the driver (npcm750-pwm-fan.c) explicitly reads both
properties using of_property_read_u8_array(), an 8-byte payload like
<127 255> would be read as 8 individual u8 elements:
0, 0, 0, 127, 0, 0, 0, 255.
Does this result in registering intermediate thermal cooling states with a 0
duty cycle, inadvertently turning the fan off during active cooling requests?
> + };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260610160816.2828713-1-tmaimon77@gmail.com?part=3
^ 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