Skip to content

Commit 290cdd7

Browse files
miquelraynalsuperna9999
authored andcommitted
drm/panel: sitronix-st7789v: Check display ID
A very basic debugging rule when a device is connected for the first time is to access a read-only register which contains known data in order to ensure the communication protocol is properly working. This driver lacked any read helper which is often a critical piece for speeding-up bring-ups. Add a read helper and use it to verify the communication with the panel is working as soon as possible in order to inform the user early if this is not the case. As this panel may work with no MISO line, the check is discarded in this case. Upon error, we do not fail probing but just warn the user, in case the DT description would be lacking the Rx bus width (which is likely on old descriptions) in order to avoid breaking existing devices. Signed-off-by: Miquel Raynal <[email protected]> Acked-by: Sam Ravnborg <[email protected]> Acked-by: Maxime Ripard <[email protected]> Reviewed-by: Sebastian Reichel <[email protected]> Tested-by: Sebastian Reichel <[email protected]> # no MISO line Signed-off-by: Sebastian Reichel <[email protected]> Signed-off-by: Neil Armstrong <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 71f7390 commit 290cdd7

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

drivers/gpu/drm/panel/panel-sitronix-st7789v.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@
110110
return val; \
111111
} while (0)
112112

113+
#define ST7789V_IDS { 0x85, 0x85, 0x52 }
114+
#define ST7789V_IDS_SIZE 3
115+
113116
struct st7789_panel_info {
114117
const struct drm_display_mode *mode;
115118
u32 bus_format;
@@ -157,6 +160,76 @@ static int st7789v_write_data(struct st7789v *ctx, u8 cmd)
157160
return st7789v_spi_write(ctx, ST7789V_DATA, cmd);
158161
}
159162

163+
static int st7789v_read_data(struct st7789v *ctx, u8 cmd, u8 *buf,
164+
unsigned int len)
165+
{
166+
struct spi_transfer xfer[2] = { };
167+
struct spi_message msg;
168+
u16 txbuf = ((ST7789V_COMMAND & 1) << 8) | cmd;
169+
u16 rxbuf[4] = {};
170+
u8 bit9 = 0;
171+
int ret, i;
172+
173+
switch (len) {
174+
case 1:
175+
case 3:
176+
case 4:
177+
break;
178+
default:
179+
return -EOPNOTSUPP;
180+
}
181+
182+
spi_message_init(&msg);
183+
184+
xfer[0].tx_buf = &txbuf;
185+
xfer[0].len = sizeof(txbuf);
186+
spi_message_add_tail(&xfer[0], &msg);
187+
188+
xfer[1].rx_buf = rxbuf;
189+
xfer[1].len = len * 2;
190+
spi_message_add_tail(&xfer[1], &msg);
191+
192+
ret = spi_sync(ctx->spi, &msg);
193+
if (ret)
194+
return ret;
195+
196+
for (i = 0; i < len; i++) {
197+
buf[i] = rxbuf[i] >> i | (bit9 << (9 - i));
198+
if (i)
199+
bit9 = rxbuf[i] & GENMASK(i - 1, 0);
200+
}
201+
202+
return 0;
203+
}
204+
205+
static int st7789v_check_id(struct drm_panel *panel)
206+
{
207+
const u8 st7789v_ids[ST7789V_IDS_SIZE] = ST7789V_IDS;
208+
struct st7789v *ctx = panel_to_st7789v(panel);
209+
bool invalid_ids = false;
210+
int ret, i;
211+
u8 ids[3];
212+
213+
if (ctx->spi->mode & SPI_NO_RX)
214+
return 0;
215+
216+
ret = st7789v_read_data(ctx, MIPI_DCS_GET_DISPLAY_ID, ids, ST7789V_IDS_SIZE);
217+
if (ret)
218+
return ret;
219+
220+
for (i = 0; i < ST7789V_IDS_SIZE; i++) {
221+
if (ids[i] != st7789v_ids[i]) {
222+
invalid_ids = true;
223+
break;
224+
}
225+
}
226+
227+
if (invalid_ids)
228+
return -EIO;
229+
230+
return 0;
231+
}
232+
160233
static const struct drm_display_mode default_mode = {
161234
.clock = 7000,
162235
.hdisplay = 240,
@@ -295,6 +368,14 @@ static int st7789v_prepare(struct drm_panel *panel)
295368
gpiod_set_value(ctx->reset, 0);
296369
msleep(120);
297370

371+
/*
372+
* Avoid failing if the IDs are invalid in case the Rx bus width
373+
* description is missing.
374+
*/
375+
ret = st7789v_check_id(panel);
376+
if (ret)
377+
dev_warn(panel->dev, "Unrecognized panel IDs");
378+
298379
ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE));
299380

300381
/* We need to wait 120ms after a sleep out command */

0 commit comments

Comments
 (0)