xref: /openbmc/linux/drivers/gpu/drm/panel/panel-sitronix-st7789v.c (revision 2b1b838ea8e5437ef06a29818d16e9efdfaf0037)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2017 Free Electrons
4  */
5 
6 #include <linux/delay.h>
7 #include <linux/gpio/consumer.h>
8 #include <linux/module.h>
9 #include <linux/regulator/consumer.h>
10 #include <linux/spi/spi.h>
11 
12 #include <video/mipi_display.h>
13 #include <linux/media-bus-format.h>
14 
15 #include <drm/drm_device.h>
16 #include <drm/drm_modes.h>
17 #include <drm/drm_panel.h>
18 
19 #define ST7789V_RAMCTRL_CMD		0xb0
20 #define ST7789V_RAMCTRL_RM_RGB			BIT(4)
21 #define ST7789V_RAMCTRL_DM_RGB			BIT(0)
22 #define ST7789V_RAMCTRL_MAGIC			(3 << 6)
23 #define ST7789V_RAMCTRL_EPF(n)			(((n) & 3) << 4)
24 
25 #define ST7789V_RGBCTRL_CMD		0xb1
26 #define ST7789V_RGBCTRL_WO			BIT(7)
27 #define ST7789V_RGBCTRL_RCM(n)			(((n) & 3) << 5)
28 #define ST7789V_RGBCTRL_VSYNC_HIGH		BIT(3)
29 #define ST7789V_RGBCTRL_HSYNC_HIGH		BIT(2)
30 #define ST7789V_RGBCTRL_PCLK_FALLING		BIT(1)
31 #define ST7789V_RGBCTRL_DE_LOW			BIT(0)
32 #define ST7789V_RGBCTRL_VBP(n)			((n) & 0x7f)
33 #define ST7789V_RGBCTRL_HBP(n)			((n) & 0x1f)
34 
35 #define ST7789V_PORCTRL_CMD		0xb2
36 #define ST7789V_PORCTRL_IDLE_BP(n)		(((n) & 0xf) << 4)
37 #define ST7789V_PORCTRL_IDLE_FP(n)		((n) & 0xf)
38 #define ST7789V_PORCTRL_PARTIAL_BP(n)		(((n) & 0xf) << 4)
39 #define ST7789V_PORCTRL_PARTIAL_FP(n)		((n) & 0xf)
40 
41 #define ST7789V_GCTRL_CMD		0xb7
42 #define ST7789V_GCTRL_VGHS(n)			(((n) & 7) << 4)
43 #define ST7789V_GCTRL_VGLS(n)			((n) & 7)
44 
45 #define ST7789V_VCOMS_CMD		0xbb
46 
47 #define ST7789V_LCMCTRL_CMD		0xc0
48 #define ST7789V_LCMCTRL_XBGR			BIT(5)
49 #define ST7789V_LCMCTRL_XMX			BIT(3)
50 #define ST7789V_LCMCTRL_XMH			BIT(2)
51 
52 #define ST7789V_VDVVRHEN_CMD		0xc2
53 #define ST7789V_VDVVRHEN_CMDEN			BIT(0)
54 
55 #define ST7789V_VRHS_CMD		0xc3
56 
57 #define ST7789V_VDVS_CMD		0xc4
58 
59 #define ST7789V_FRCTRL2_CMD		0xc6
60 
61 #define ST7789V_PWCTRL1_CMD		0xd0
62 #define ST7789V_PWCTRL1_MAGIC			0xa4
63 #define ST7789V_PWCTRL1_AVDD(n)			(((n) & 3) << 6)
64 #define ST7789V_PWCTRL1_AVCL(n)			(((n) & 3) << 4)
65 #define ST7789V_PWCTRL1_VDS(n)			((n) & 3)
66 
67 #define ST7789V_PVGAMCTRL_CMD		0xe0
68 #define ST7789V_PVGAMCTRL_JP0(n)		(((n) & 3) << 4)
69 #define ST7789V_PVGAMCTRL_JP1(n)		(((n) & 3) << 4)
70 #define ST7789V_PVGAMCTRL_VP0(n)		((n) & 0xf)
71 #define ST7789V_PVGAMCTRL_VP1(n)		((n) & 0x3f)
72 #define ST7789V_PVGAMCTRL_VP2(n)		((n) & 0x3f)
73 #define ST7789V_PVGAMCTRL_VP4(n)		((n) & 0x1f)
74 #define ST7789V_PVGAMCTRL_VP6(n)		((n) & 0x1f)
75 #define ST7789V_PVGAMCTRL_VP13(n)		((n) & 0xf)
76 #define ST7789V_PVGAMCTRL_VP20(n)		((n) & 0x7f)
77 #define ST7789V_PVGAMCTRL_VP27(n)		((n) & 7)
78 #define ST7789V_PVGAMCTRL_VP36(n)		(((n) & 7) << 4)
79 #define ST7789V_PVGAMCTRL_VP43(n)		((n) & 0x7f)
80 #define ST7789V_PVGAMCTRL_VP50(n)		((n) & 0xf)
81 #define ST7789V_PVGAMCTRL_VP57(n)		((n) & 0x1f)
82 #define ST7789V_PVGAMCTRL_VP59(n)		((n) & 0x1f)
83 #define ST7789V_PVGAMCTRL_VP61(n)		((n) & 0x3f)
84 #define ST7789V_PVGAMCTRL_VP62(n)		((n) & 0x3f)
85 #define ST7789V_PVGAMCTRL_VP63(n)		(((n) & 0xf) << 4)
86 
87 #define ST7789V_NVGAMCTRL_CMD		0xe1
88 #define ST7789V_NVGAMCTRL_JN0(n)		(((n) & 3) << 4)
89 #define ST7789V_NVGAMCTRL_JN1(n)		(((n) & 3) << 4)
90 #define ST7789V_NVGAMCTRL_VN0(n)		((n) & 0xf)
91 #define ST7789V_NVGAMCTRL_VN1(n)		((n) & 0x3f)
92 #define ST7789V_NVGAMCTRL_VN2(n)		((n) & 0x3f)
93 #define ST7789V_NVGAMCTRL_VN4(n)		((n) & 0x1f)
94 #define ST7789V_NVGAMCTRL_VN6(n)		((n) & 0x1f)
95 #define ST7789V_NVGAMCTRL_VN13(n)		((n) & 0xf)
96 #define ST7789V_NVGAMCTRL_VN20(n)		((n) & 0x7f)
97 #define ST7789V_NVGAMCTRL_VN27(n)		((n) & 7)
98 #define ST7789V_NVGAMCTRL_VN36(n)		(((n) & 7) << 4)
99 #define ST7789V_NVGAMCTRL_VN43(n)		((n) & 0x7f)
100 #define ST7789V_NVGAMCTRL_VN50(n)		((n) & 0xf)
101 #define ST7789V_NVGAMCTRL_VN57(n)		((n) & 0x1f)
102 #define ST7789V_NVGAMCTRL_VN59(n)		((n) & 0x1f)
103 #define ST7789V_NVGAMCTRL_VN61(n)		((n) & 0x3f)
104 #define ST7789V_NVGAMCTRL_VN62(n)		((n) & 0x3f)
105 #define ST7789V_NVGAMCTRL_VN63(n)		(((n) & 0xf) << 4)
106 
107 #define ST7789V_TEST(val, func)			\
108 	do {					\
109 		if ((val = (func)))		\
110 			return val;		\
111 	} while (0)
112 
113 #define ST7789V_IDS { 0x85, 0x85, 0x52 }
114 #define ST7789V_IDS_SIZE 3
115 
116 struct st7789_panel_info {
117 	const struct drm_display_mode *mode;
118 	u32 bus_format;
119 	u32 bus_flags;
120 	bool invert_mode;
121 };
122 
123 struct st7789v {
124 	struct drm_panel panel;
125 	const struct st7789_panel_info *info;
126 	struct spi_device *spi;
127 	struct gpio_desc *reset;
128 	struct regulator *power;
129 };
130 
131 enum st7789v_prefix {
132 	ST7789V_COMMAND = 0,
133 	ST7789V_DATA = 1,
134 };
135 
136 static inline struct st7789v *panel_to_st7789v(struct drm_panel *panel)
137 {
138 	return container_of(panel, struct st7789v, panel);
139 }
140 
141 static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix,
142 			     u8 data)
143 {
144 	struct spi_transfer xfer = { };
145 	u16 txbuf = ((prefix & 1) << 8) | data;
146 
147 	xfer.tx_buf = &txbuf;
148 	xfer.len = sizeof(txbuf);
149 
150 	return spi_sync_transfer(ctx->spi, &xfer, 1);
151 }
152 
153 static int st7789v_write_command(struct st7789v *ctx, u8 cmd)
154 {
155 	return st7789v_spi_write(ctx, ST7789V_COMMAND, cmd);
156 }
157 
158 static int st7789v_write_data(struct st7789v *ctx, u8 cmd)
159 {
160 	return st7789v_spi_write(ctx, ST7789V_DATA, cmd);
161 }
162 
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 
233 static const struct drm_display_mode default_mode = {
234 	.clock = 7000,
235 	.hdisplay = 240,
236 	.hsync_start = 240 + 38,
237 	.hsync_end = 240 + 38 + 10,
238 	.htotal = 240 + 38 + 10 + 10,
239 	.vdisplay = 320,
240 	.vsync_start = 320 + 8,
241 	.vsync_end = 320 + 8 + 4,
242 	.vtotal = 320 + 8 + 4 + 4,
243 	.width_mm = 61,
244 	.height_mm = 103,
245 	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
246 };
247 
248 static const struct drm_display_mode t28cp45tn89_mode = {
249 	.clock = 6008,
250 	.hdisplay = 240,
251 	.hsync_start = 240 + 38,
252 	.hsync_end = 240 + 38 + 10,
253 	.htotal = 240 + 38 + 10 + 10,
254 	.vdisplay = 320,
255 	.vsync_start = 320 + 8,
256 	.vsync_end = 320 + 8 + 4,
257 	.vtotal = 320 + 8 + 4 + 4,
258 	.width_mm = 43,
259 	.height_mm = 57,
260 	.flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC,
261 };
262 
263 static const struct drm_display_mode et028013dma_mode = {
264 	.clock = 3000,
265 	.hdisplay = 240,
266 	.hsync_start = 240 + 38,
267 	.hsync_end = 240 + 38 + 10,
268 	.htotal = 240 + 38 + 10 + 10,
269 	.vdisplay = 320,
270 	.vsync_start = 320 + 8,
271 	.vsync_end = 320 + 8 + 4,
272 	.vtotal = 320 + 8 + 4 + 4,
273 	.width_mm = 43,
274 	.height_mm = 58,
275 	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
276 };
277 
278 static const struct st7789_panel_info default_panel = {
279 	.mode = &default_mode,
280 	.invert_mode = true,
281 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
282 	.bus_flags = DRM_BUS_FLAG_DE_HIGH |
283 		     DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
284 };
285 
286 static const struct st7789_panel_info t28cp45tn89_panel = {
287 	.mode = &t28cp45tn89_mode,
288 	.invert_mode = false,
289 	.bus_format = MEDIA_BUS_FMT_RGB565_1X16,
290 	.bus_flags = DRM_BUS_FLAG_DE_HIGH |
291 		     DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
292 };
293 
294 static const struct st7789_panel_info et028013dma_panel = {
295 	.mode = &et028013dma_mode,
296 	.invert_mode = true,
297 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
298 	.bus_flags = DRM_BUS_FLAG_DE_HIGH |
299 		     DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
300 };
301 
302 static int st7789v_get_modes(struct drm_panel *panel,
303 			     struct drm_connector *connector)
304 {
305 	struct st7789v *ctx = panel_to_st7789v(panel);
306 	struct drm_display_mode *mode;
307 
308 	mode = drm_mode_duplicate(connector->dev, ctx->info->mode);
309 	if (!mode) {
310 		dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
311 			ctx->info->mode->hdisplay, ctx->info->mode->vdisplay,
312 			drm_mode_vrefresh(ctx->info->mode));
313 		return -ENOMEM;
314 	}
315 
316 	drm_mode_set_name(mode);
317 
318 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
319 	drm_mode_probed_add(connector, mode);
320 
321 	connector->display_info.bpc = 6;
322 	connector->display_info.width_mm = ctx->info->mode->width_mm;
323 	connector->display_info.height_mm = ctx->info->mode->height_mm;
324 	connector->display_info.bus_flags = ctx->info->bus_flags;
325 	drm_display_info_set_bus_formats(&connector->display_info,
326 					 &ctx->info->bus_format, 1);
327 
328 	return 1;
329 }
330 
331 static int st7789v_prepare(struct drm_panel *panel)
332 {
333 	struct st7789v *ctx = panel_to_st7789v(panel);
334 	u8 pixel_fmt, polarity;
335 	int ret;
336 
337 	switch (ctx->info->bus_format) {
338 	case MEDIA_BUS_FMT_RGB666_1X18:
339 		pixel_fmt = MIPI_DCS_PIXEL_FMT_18BIT;
340 		break;
341 	case MEDIA_BUS_FMT_RGB565_1X16:
342 		pixel_fmt = MIPI_DCS_PIXEL_FMT_16BIT;
343 		break;
344 	default:
345 		dev_err(panel->dev, "unsupported bus format: %d\n",
346 			ctx->info->bus_format);
347 		return -EINVAL;
348 	}
349 
350 	pixel_fmt = (pixel_fmt << 4) | pixel_fmt;
351 
352 	polarity = 0;
353 	if (ctx->info->mode->flags & DRM_MODE_FLAG_PVSYNC)
354 		polarity |= ST7789V_RGBCTRL_VSYNC_HIGH;
355 	if (ctx->info->mode->flags & DRM_MODE_FLAG_PHSYNC)
356 		polarity |= ST7789V_RGBCTRL_HSYNC_HIGH;
357 	if (ctx->info->bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE)
358 		polarity |= ST7789V_RGBCTRL_PCLK_FALLING;
359 	if (ctx->info->bus_flags & DRM_BUS_FLAG_DE_LOW)
360 		polarity |= ST7789V_RGBCTRL_DE_LOW;
361 
362 	ret = regulator_enable(ctx->power);
363 	if (ret)
364 		return ret;
365 
366 	gpiod_set_value(ctx->reset, 1);
367 	msleep(30);
368 	gpiod_set_value(ctx->reset, 0);
369 	msleep(120);
370 
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 
379 	ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE));
380 
381 	/* We need to wait 120ms after a sleep out command */
382 	msleep(120);
383 
384 	ST7789V_TEST(ret, st7789v_write_command(ctx,
385 						MIPI_DCS_SET_ADDRESS_MODE));
386 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
387 
388 	ST7789V_TEST(ret, st7789v_write_command(ctx,
389 						MIPI_DCS_SET_PIXEL_FORMAT));
390 	ST7789V_TEST(ret, st7789v_write_data(ctx, pixel_fmt));
391 
392 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD));
393 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
394 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
395 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
396 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PORCTRL_IDLE_BP(3) |
397 					     ST7789V_PORCTRL_IDLE_FP(3)));
398 	ST7789V_TEST(ret, st7789v_write_data(ctx,
399 					     ST7789V_PORCTRL_PARTIAL_BP(3) |
400 					     ST7789V_PORCTRL_PARTIAL_FP(3)));
401 
402 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_GCTRL_CMD));
403 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_GCTRL_VGLS(5) |
404 					     ST7789V_GCTRL_VGHS(3)));
405 
406 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VCOMS_CMD));
407 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0x2b));
408 
409 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_LCMCTRL_CMD));
410 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_LCMCTRL_XMH |
411 					     ST7789V_LCMCTRL_XMX |
412 					     ST7789V_LCMCTRL_XBGR));
413 
414 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVVRHEN_CMD));
415 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_VDVVRHEN_CMDEN));
416 
417 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VRHS_CMD));
418 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
419 
420 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVS_CMD));
421 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0x20));
422 
423 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_FRCTRL2_CMD));
424 	ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
425 
426 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PWCTRL1_CMD));
427 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_MAGIC));
428 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_AVDD(2) |
429 					     ST7789V_PWCTRL1_AVCL(2) |
430 					     ST7789V_PWCTRL1_VDS(1)));
431 
432 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PVGAMCTRL_CMD));
433 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP63(0xd)));
434 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP1(0xca)));
435 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP2(0xe)));
436 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP4(8)));
437 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP6(9)));
438 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP13(7)));
439 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP20(0x2d)));
440 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP27(0xb) |
441 					     ST7789V_PVGAMCTRL_VP36(3)));
442 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP43(0x3d)));
443 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_JP1(3) |
444 					     ST7789V_PVGAMCTRL_VP50(4)));
445 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP57(0xa)));
446 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP59(0xa)));
447 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP61(0x1b)));
448 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP62(0x28)));
449 
450 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_NVGAMCTRL_CMD));
451 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN63(0xd)));
452 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN1(0xca)));
453 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN2(0xf)));
454 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN4(8)));
455 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN6(8)));
456 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN13(7)));
457 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN20(0x2e)));
458 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN27(0xc) |
459 					     ST7789V_NVGAMCTRL_VN36(5)));
460 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN43(0x40)));
461 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_JN1(3) |
462 					     ST7789V_NVGAMCTRL_VN50(4)));
463 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN57(9)));
464 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN59(0xb)));
465 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b)));
466 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28)));
467 
468 	if (ctx->info->invert_mode) {
469 		ST7789V_TEST(ret, st7789v_write_command(ctx,
470 						MIPI_DCS_ENTER_INVERT_MODE));
471 	} else {
472 		ST7789V_TEST(ret, st7789v_write_command(ctx,
473 						MIPI_DCS_EXIT_INVERT_MODE));
474 	}
475 
476 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD));
477 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB |
478 					     ST7789V_RAMCTRL_RM_RGB));
479 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_EPF(3) |
480 					     ST7789V_RAMCTRL_MAGIC));
481 
482 	ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD));
483 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_WO |
484 					     ST7789V_RGBCTRL_RCM(2) |
485 					     polarity));
486 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8)));
487 	ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20)));
488 
489 	return 0;
490 }
491 
492 static int st7789v_enable(struct drm_panel *panel)
493 {
494 	struct st7789v *ctx = panel_to_st7789v(panel);
495 
496 	return st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_ON);
497 }
498 
499 static int st7789v_disable(struct drm_panel *panel)
500 {
501 	struct st7789v *ctx = panel_to_st7789v(panel);
502 	int ret;
503 
504 	ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_OFF));
505 
506 	return 0;
507 }
508 
509 static int st7789v_unprepare(struct drm_panel *panel)
510 {
511 	struct st7789v *ctx = panel_to_st7789v(panel);
512 	int ret;
513 
514 	ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_SLEEP_MODE));
515 
516 	regulator_disable(ctx->power);
517 
518 	return 0;
519 }
520 
521 static const struct drm_panel_funcs st7789v_drm_funcs = {
522 	.disable	= st7789v_disable,
523 	.enable		= st7789v_enable,
524 	.get_modes	= st7789v_get_modes,
525 	.prepare	= st7789v_prepare,
526 	.unprepare	= st7789v_unprepare,
527 };
528 
529 static int st7789v_probe(struct spi_device *spi)
530 {
531 	struct device *dev = &spi->dev;
532 	struct st7789v *ctx;
533 	int ret;
534 
535 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
536 	if (!ctx)
537 		return -ENOMEM;
538 
539 	spi_set_drvdata(spi, ctx);
540 	ctx->spi = spi;
541 
542 	spi->bits_per_word = 9;
543 	ret = spi_setup(spi);
544 	if (ret < 0)
545 		return dev_err_probe(&spi->dev, ret, "Failed to setup spi\n");
546 
547 	ctx->info = device_get_match_data(&spi->dev);
548 
549 	drm_panel_init(&ctx->panel, dev, &st7789v_drm_funcs,
550 		       DRM_MODE_CONNECTOR_DPI);
551 
552 	ctx->power = devm_regulator_get(dev, "power");
553 	ret = PTR_ERR_OR_ZERO(ctx->power);
554 	if (ret)
555 		return dev_err_probe(dev, ret, "Failed to get regulator\n");
556 
557 	ctx->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
558 	ret = PTR_ERR_OR_ZERO(ctx->reset);
559 	if (ret)
560 		return dev_err_probe(dev, ret, "Failed to get reset line\n");
561 
562 	ret = drm_panel_of_backlight(&ctx->panel);
563 	if (ret)
564 		return dev_err_probe(dev, ret, "Failed to get backlight\n");
565 
566 	drm_panel_add(&ctx->panel);
567 
568 	return 0;
569 }
570 
571 static void st7789v_remove(struct spi_device *spi)
572 {
573 	struct st7789v *ctx = spi_get_drvdata(spi);
574 
575 	drm_panel_remove(&ctx->panel);
576 }
577 
578 static const struct spi_device_id st7789v_spi_id[] = {
579 	{ "st7789v", (unsigned long) &default_panel },
580 	{ "t28cp45tn89-v17", (unsigned long) &t28cp45tn89_panel },
581 	{ "et028013dma", (unsigned long) &et028013dma_panel },
582 	{ }
583 };
584 MODULE_DEVICE_TABLE(spi, st7789v_spi_id);
585 
586 static const struct of_device_id st7789v_of_match[] = {
587 	{ .compatible = "sitronix,st7789v", .data = &default_panel },
588 	{ .compatible = "inanbo,t28cp45tn89-v17", .data = &t28cp45tn89_panel },
589 	{ .compatible = "edt,et028013dma", .data = &et028013dma_panel },
590 	{ }
591 };
592 MODULE_DEVICE_TABLE(of, st7789v_of_match);
593 
594 static struct spi_driver st7789v_driver = {
595 	.probe = st7789v_probe,
596 	.remove = st7789v_remove,
597 	.id_table = st7789v_spi_id,
598 	.driver = {
599 		.name = "st7789v",
600 		.of_match_table = st7789v_of_match,
601 	},
602 };
603 module_spi_driver(st7789v_driver);
604 
605 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
606 MODULE_DESCRIPTION("Sitronix st7789v LCD Driver");
607 MODULE_LICENSE("GPL v2");
608