All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: Amit Barzilai <amit.barzilai22@gmail.com>
Cc: Javier Martinez Canillas <javierm@redhat.com>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Fabio Piparo <holofermes@gmail.com>,
	dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 6/6] drm/ssd130x: Add SSD135X_FAMILY and SSD1351 support
Date: Tue, 18 Aug 2026 11:55:10 +0300	[thread overview]
Message-ID: <aoQd7qsojnphARpH@ashevche-desk.local> (raw)
In-Reply-To: <20260818080626.30430-7-amit.barzilai22@gmail.com>

On Tue, Aug 18, 2026 at 11:06:26AM +0300, Amit Barzilai wrote:
> The Solomon SSD1351 is a 128x128 RGB color OLED controller. It shares the
> SSD133X pixel layout: one 65k color (RGB565) pixel per Segment, written as
> a bulk transfer once a column/row addressing window has been programmed.
> Add it as a new SSD135X_FAMILY rather than as a separate driver, so that
> the ssd130x plane, CRTC and encoder infrastructure is reused.
> 
> Give the family its own primary plane update and disable, encoder enable
> and backlight callbacks instead of teaching the ssd133x ones about a second
> family. Only the callbacks that carry no family specific logic are reused
> as is: ssd133x_primary_plane_atomic_check(), ssd133x_crtc_atomic_check()
> and ssd130x_encoder_atomic_disable().
> 
> The data path differs from the ssd133x family in one respect. The SSD1351
> only starts accepting pixel data after an explicit Write RAM command
> (0x5c), while the SSD133X enters data mode as soon as the address window
> has been programmed. Emit it from ssd135x_update_rect(), which both the
> damage update and the clear screen paths go through.
> 
> SSD1351 differs from previous controllers in the command protocol. While
> the opcode is still sent on the command path, the parameters are sent on
> the data path. Introduce the cmd_params_are_data flag to struct
> ssd130x_deviceinfo and let ssd130x_write_cmds() split the buffer in
> accordance to the device specifications.
> 
> The SSD1351 also needs its own init sequence (ssd135x_init). The remap
> byte is fixed at horizontal address increment, COM split, reversed COM
> scan direction, BGR sub-pixel order and 65k color depth; rotation is not
> supported.
> 
> Contrast is calibrated per color channel as for the ssd133x family, but
> the three channels are parameters of a single command (0xc1) instead of
> one command per channel. Add ssd135x_set_contrast() for that and use it
> from both the init and the backlight update paths.
> 
> The SSD1351 is SPI-only, so only the SPI transport match tables gain an
> entry; no new config symbol is needed.

...

>  static int ssd130x_write_cmds(struct ssd130x_device *ssd130x, const u8 *cmd,
>  			      size_t len)

>  	unsigned int i;
>  	int ret;
>  
> +	if (ssd130x->device_info->cmd_params_are_data) {
> +		if (!len)
> +			return 0;
> +
> +		ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, cmd[0]);
> +		if (ret || len == 1)
> +			return ret;
> +
> +		return ssd130x_write_data(ssd130x, cmd + 1, len - 1);
> +	}
> +
>  	for (i = 0; i < len; i++) {
>  		ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, cmd[i]);
>  		if (ret)

>  	return ssd130x_run_cmd_seq(ssd130x, cmds);
>  }

...

> +static int ssd135x_init(struct ssd130x_device *ssd130x)
> +{
> +	/*
> +	 * Horizontal address increment, COM split, reversed COM scan direction,
> +	 * BGR sub-pixel order and 65k (RGB565) color depth. Rotation is not
> +	 * supported, so the remap byte is fixed.
> +	 */
> +	u8 remap = SSD135X_SET_REMAP_65K | SSD135X_SET_REMAP_COM_SPLIT |
> +		   SSD135X_SET_REMAP_COLOR_BGR | SSD135X_SET_REMAP_COM_SCAN;

Same comment about const.

> +	int ret;

Why not placing it after cmds?

> +	const u8 cmds[] = {
> +		/* Unlock the controller, then the extended command set */
> +		2, SSD135X_SET_COMMAND_LOCK, 0x12,
> +		2, SSD135X_SET_COMMAND_LOCK, 0xb1,
> +		1, SSD13XX_DISPLAY_OFF,
> +		2, SSD135X_SET_CLOCK_FREQ, 0xf1,
> +		2, SSD135X_SET_MUX_RATIO, ssd130x->height - 1,
> +		3, SSD135X_SET_COL_RANGE, 0x00, ssd130x->width - 1,
> +		3, SSD135X_SET_ROW_RANGE, 0x00, ssd130x->height - 1,
> +		2, SSD135X_SET_DISPLAY_START, 0x00,
> +		2, SSD135X_SET_DISPLAY_OFFSET, 0x00,
> +		2, SSD135X_SET_GPIO, 0x00,
> +		2, SSD135X_SET_FUNCTION, 0x01,
> +		2, SSD135X_SET_PHASE_LENGTH, 0x32,
> +		4, SSD135X_SET_VSL, 0xa0, 0xb5, 0x55,
> +		2, SSD135X_SET_PRECHARGE_VOLTAGE, 0x17,
> +		2, SSD135X_SET_VCOMH_VOLTAGE, 0x05,
> +		2, SSD135X_SET_CONTRAST_MASTER, 0x0f,
> +		2, SSD135X_SET_PRECHARGE2, 0x01,
> +		1, SSD135X_SET_DISPLAY_NORMAL,
> +		2, SSD13XX_SET_SEG_REMAP, remap,
> +		0,
> +	};
> +
> +	ret = ssd130x_run_cmd_seq(ssd130x, cmds);
> +	if (ret < 0)
> +		return ret;
> +
> +	return ssd135x_set_contrast(ssd130x, ssd130x->contrast);
> +}

...

> +static void ssd135x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
> +{
> +	struct drm_rect screen = DRM_RECT_INIT(0, 0, ssd130x->width, ssd130x->height);
> +	const struct drm_format_info *fi = drm_format_info(DRM_FORMAT_RGB565);
> +	unsigned int pitch;

> +	if (!fi)
> +		return;

It's less maintainable than

	const struct drm_format_info *fi;
	unsigned int pitch;

	fi = drm_format_info(DRM_FORMAT_RGB565);
	if (!fi)
		return;


> +	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
> +
> +	memset(data_array, 0, pitch * ssd130x->height);
> +
> +	ssd135x_update_rect(ssd130x, &screen, data_array, pitch);
> +}

...

> +static int ssd135x_fb_blit_rect(struct drm_framebuffer *fb,
> +				const struct iosys_map *vmap,
> +				struct drm_rect *rect, u8 *data_array,
> +				struct drm_format_conv_state *fmtcnv_state)
> +{
> +	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
> +	const struct drm_format_info *fi = drm_format_info(DRM_FORMAT_RGB565);
> +	unsigned int dst_pitch;
> +	struct iosys_map dst;
> +
> +	if (!fi)
> +		return -EINVAL;

Ditto. The problem is that the current style is tempting for subtle mistakes
such as defining more variables that may use fi in between.

> +	dst_pitch = drm_format_info_min_pitch(fi, 0, drm_rect_width(rect));
> +
> +	iosys_map_set_vaddr(&dst, data_array);
> +	drm_fb_xrgb8888_to_rgb565be(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
> +
> +	ssd135x_update_rect(ssd130x, rect, data_array, dst_pitch);
> +
> +	return 0;
> +}

...

> +static void ssd135x_primary_plane_atomic_disable(struct drm_plane *plane,
> +						 struct drm_atomic_commit *state)
> +{
> +	struct drm_device *drm = plane->dev;
> +	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
> +	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
> +	struct drm_crtc_state *crtc_state;
> +	struct ssd130x_crtc_state *ssd130x_crtc_state;
> +	int idx;
> +
> +	if (!plane_state->crtc)
> +		return;

In the similar way here.

> +	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
> +	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
> +
> +	if (!drm_dev_enter(drm, &idx))
> +		return;
> +
> +	ssd135x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
> +
> +	drm_dev_exit(idx);
> +}

-- 
With Best Regards,
Andy Shevchenko



  parent reply	other threads:[~2026-08-18  8:55 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-18  8:06 [PATCH v4 0/6] drm/ssd130x: Add support for the Solomon SSD1351 OLED controller Amit Barzilai
2026-08-18  8:06 ` [PATCH v4 1/6] dt-bindings: display: Add " Amit Barzilai
2026-08-18  8:06 ` [PATCH v4 2/6] drm/ssd130x: Change SSD133X color format to RGB565 from RGB332 Amit Barzilai
2026-08-18  8:18   ` sashiko-bot
2026-08-18  8:36   ` Andy Shevchenko
2026-08-18 18:58     ` Amit Barzilai
2026-08-18  8:06 ` [PATCH v4 3/6] drm/ssd130x: Constify ssd130x_write_data() 'values' parameter Amit Barzilai
2026-08-18  8:37   ` Andy Shevchenko
2026-08-18  8:06 ` [PATCH v4 4/6] drm/ssd130x: Replace positional ssd130x_spi_id[] initialization with C99 Amit Barzilai
2026-08-18  8:40   ` Andy Shevchenko
2026-08-18 19:25     ` Amit Barzilai
2026-08-20  9:06       ` Amit Barzilai
2026-08-20 13:24         ` Javier Martinez Canillas
2026-08-18  8:06 ` [PATCH v4 5/6] drm/ssd130x: Implement ssd130x_write_cmd() on top of ssd130x_write_cmds() Amit Barzilai
2026-08-18  8:43   ` Andy Shevchenko
2026-08-18 19:34     ` Amit Barzilai
2026-08-18  8:06 ` [PATCH v4 6/6] drm/ssd130x: Add SSD135X_FAMILY and SSD1351 support Amit Barzilai
2026-08-18  8:24   ` sashiko-bot
2026-08-18  8:55   ` Andy Shevchenko [this message]
2026-08-18 20:13     ` Amit Barzilai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aoQd7qsojnphARpH@ashevche-desk.local \
    --to=andriy.shevchenko@intel.com \
    --cc=airlied@gmail.com \
    --cc=amit.barzilai22@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=holofermes@gmail.com \
    --cc=javierm@redhat.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=robh@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.