xref: /linux/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c (revision d4dc08c530cbf71fb1c7cddb9d1e7e36bd62e22f)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2014 Google, Inc.
4  *
5  * Copyright (C) 2022 Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
6  *
7  * Adapted from the downstream Pixel C driver written by Sean Paul
8  */
9 
10 #include <linux/backlight.h>
11 #include <linux/delay.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/regulator/consumer.h>
16 
17 #include <video/mipi_display.h>
18 
19 #include <drm/drm_crtc.h>
20 #include <drm/drm_mipi_dsi.h>
21 #include <drm/drm_panel.h>
22 
23 #define MCS_CMD_ACS_PROT			0xB0
24 #define MCS_CMD_ACS_PROT_OFF			(0 << 0)
25 
26 #define MCS_PWR_CTRL_FUNC			0xD0
27 #define MCS_PWR_CTRL_PARAM1_DEFAULT		(2 << 0)
28 #define MCS_PWR_CTRL_PARAM1_VGH_210_DIV		(1 << 4)
29 #define MCS_PWR_CTRL_PARAM1_VGH_240_DIV		(2 << 4)
30 #define MCS_PWR_CTRL_PARAM1_VGH_280_DIV		(3 << 4)
31 #define MCS_PWR_CTRL_PARAM1_VGH_330_DIV		(4 << 4)
32 #define MCS_PWR_CTRL_PARAM1_VGH_410_DIV		(5 << 4)
33 #define MCS_PWR_CTRL_PARAM2_DEFAULT		(9 << 4)
34 #define MCS_PWR_CTRL_PARAM2_VGL_210_DIV		(1 << 0)
35 #define MCS_PWR_CTRL_PARAM2_VGL_240_DIV		(2 << 0)
36 #define MCS_PWR_CTRL_PARAM2_VGL_280_DIV		(3 << 0)
37 #define MCS_PWR_CTRL_PARAM2_VGL_330_DIV		(4 << 0)
38 #define MCS_PWR_CTRL_PARAM2_VGL_410_DIV		(5 << 0)
39 
40 struct jdi_panel {
41 	struct drm_panel base;
42 	struct mipi_dsi_device *link1;
43 	struct mipi_dsi_device *link2;
44 
45 	struct regulator *supply;
46 	struct regulator *ddi_supply;
47 	struct backlight_device *backlight;
48 
49 	struct gpio_desc *enable_gpio;
50 	struct gpio_desc *reset_gpio;
51 
52 	const struct drm_display_mode *mode;
53 };
54 
55 static inline struct jdi_panel *to_panel_jdi(struct drm_panel *panel)
56 {
57 	return container_of(panel, struct jdi_panel, base);
58 }
59 
60 static void jdi_wait_frames(struct jdi_panel *jdi, unsigned int frames)
61 {
62 	unsigned int refresh = drm_mode_vrefresh(jdi->mode);
63 
64 	if (WARN_ON(frames > refresh))
65 		return;
66 
67 	msleep(1000 / (refresh / frames));
68 }
69 
70 static int jdi_panel_disable(struct drm_panel *panel)
71 {
72 	struct jdi_panel *jdi = to_panel_jdi(panel);
73 
74 	backlight_disable(jdi->backlight);
75 
76 	jdi_wait_frames(jdi, 2);
77 
78 	return 0;
79 }
80 
81 static int jdi_panel_unprepare(struct drm_panel *panel)
82 {
83 	struct jdi_panel *jdi = to_panel_jdi(panel);
84 
85 	/*
86 	 * One context per panel since we'll continue trying to shut down the
87 	 * other panel even if one isn't responding.
88 	 */
89 	struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = jdi->link1 };
90 	struct mipi_dsi_multi_context dsi_ctx2 = { .dsi = jdi->link2 };
91 
92 	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx1);
93 	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx2);
94 
95 	/* Specified by JDI @ 50ms, subject to change */
96 	msleep(50);
97 
98 	/* Doesn't hurt to try sleep mode even if display off fails */
99 	dsi_ctx1.accum_err = 0;
100 	dsi_ctx2.accum_err = 0;
101 	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx1);
102 	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx2);
103 
104 	/* Specified by JDI @ 150ms, subject to change */
105 	msleep(150);
106 
107 	gpiod_set_value(jdi->reset_gpio, 1);
108 
109 	/* T4 = 1ms */
110 	usleep_range(1000, 3000);
111 
112 	gpiod_set_value(jdi->enable_gpio, 0);
113 
114 	/* T5 = 2ms */
115 	usleep_range(2000, 4000);
116 
117 	regulator_disable(jdi->ddi_supply);
118 
119 	/* T6 = 2ms plus some time to discharge capacitors */
120 	usleep_range(7000, 9000);
121 
122 	regulator_disable(jdi->supply);
123 	/* Specified by JDI @ 20ms, subject to change */
124 	msleep(20);
125 
126 	return 0;
127 }
128 
129 static void jdi_setup_symmetrical_split(struct mipi_dsi_multi_context *dsi_ctx,
130 					struct mipi_dsi_device *left,
131 					struct mipi_dsi_device *right,
132 					const struct drm_display_mode *mode)
133 {
134 	mipi_dsi_dual(mipi_dsi_dcs_set_column_address_multi,
135 		      dsi_ctx, left, right,
136 		      0, mode->hdisplay / 2 - 1);
137 	mipi_dsi_dual(mipi_dsi_dcs_set_page_address_multi,
138 		      dsi_ctx, left, right,
139 		      0, mode->vdisplay - 1);
140 }
141 
142 static void jdi_write_dcdc_registers(struct mipi_dsi_multi_context *dsi_ctx,
143 				     struct jdi_panel *jdi)
144 {
145 	/* Clear the manufacturer command access protection */
146 	mipi_dsi_dual_generic_write_seq_multi(dsi_ctx, jdi->link1, jdi->link2,
147 					      MCS_CMD_ACS_PROT,
148 					      MCS_CMD_ACS_PROT_OFF);
149 	/*
150 	 * Change the VGH/VGL divide ratios to move the noise generated by the
151 	 * TCONN. This should hopefully avoid interaction with the backlight
152 	 * controller.
153 	 */
154 	mipi_dsi_dual_generic_write_seq_multi(dsi_ctx, jdi->link1, jdi->link2,
155 					      MCS_PWR_CTRL_FUNC,
156 					      MCS_PWR_CTRL_PARAM1_VGH_330_DIV |
157 					      MCS_PWR_CTRL_PARAM1_DEFAULT,
158 					      MCS_PWR_CTRL_PARAM2_VGL_410_DIV |
159 					      MCS_PWR_CTRL_PARAM2_DEFAULT);
160 }
161 
162 static int jdi_panel_prepare(struct drm_panel *panel)
163 {
164 	struct jdi_panel *jdi = to_panel_jdi(panel);
165 	struct mipi_dsi_multi_context dsi_ctx = {};
166 	int err;
167 
168 	/* Disable backlight to avoid showing random pixels
169 	 * with a conservative delay for it to take effect.
170 	 */
171 	backlight_disable(jdi->backlight);
172 	jdi_wait_frames(jdi, 3);
173 
174 	jdi->link1->mode_flags |= MIPI_DSI_MODE_LPM;
175 	jdi->link2->mode_flags |= MIPI_DSI_MODE_LPM;
176 
177 	err = regulator_enable(jdi->supply);
178 	if (err < 0) {
179 		dev_err(panel->dev, "failed to enable supply: %d\n", err);
180 		return err;
181 	}
182 	/* T1 = 2ms */
183 	usleep_range(2000, 4000);
184 
185 	err = regulator_enable(jdi->ddi_supply);
186 	if (err < 0) {
187 		dev_err(panel->dev, "failed to enable ddi_supply: %d\n", err);
188 		goto supply_off;
189 	}
190 	/* T2 = 1ms */
191 	usleep_range(1000, 3000);
192 
193 	gpiod_set_value(jdi->enable_gpio, 1);
194 	/* T3 = 10ms */
195 	usleep_range(10000, 15000);
196 
197 	gpiod_set_value(jdi->reset_gpio, 0);
198 	/* Specified by JDI @ 3ms, subject to change */
199 	usleep_range(3000, 5000);
200 
201 	/*
202 	 * TODO: The device supports both left-right and even-odd split
203 	 * configurations, but this driver currently supports only the left-
204 	 * right split. To support a different mode a mechanism needs to be
205 	 * put in place to communicate the configuration back to the DSI host
206 	 * controller.
207 	 */
208 	jdi_setup_symmetrical_split(&dsi_ctx, jdi->link1, jdi->link2,
209 				    jdi->mode);
210 
211 	mipi_dsi_dual(mipi_dsi_dcs_set_tear_scanline_multi,
212 		      &dsi_ctx, jdi->link1, jdi->link2,
213 		      jdi->mode->vdisplay - 16);
214 
215 	mipi_dsi_dual(mipi_dsi_dcs_set_tear_on_multi,
216 		      &dsi_ctx, jdi->link1, jdi->link2,
217 		      MIPI_DSI_DCS_TEAR_MODE_VBLANK);
218 
219 	mipi_dsi_dual(mipi_dsi_dcs_set_pixel_format_multi,
220 		      &dsi_ctx, jdi->link1, jdi->link2,
221 		      MIPI_DCS_PIXEL_FMT_24BIT);
222 
223 	mipi_dsi_dual(mipi_dsi_dcs_exit_sleep_mode_multi,
224 		      &dsi_ctx, jdi->link1, jdi->link2);
225 
226 	jdi_write_dcdc_registers(&dsi_ctx, jdi);
227 	/*
228 	 * We need to wait 150ms between mipi_dsi_dcs_exit_sleep_mode_multi()
229 	 * and mipi_dsi_dcs_set_display_on_multi().
230 	 */
231 	mipi_dsi_msleep(&dsi_ctx, 150);
232 
233 	mipi_dsi_dual(mipi_dsi_dcs_set_display_on_multi,
234 		      &dsi_ctx, jdi->link1, jdi->link2);
235 
236 	if (dsi_ctx.accum_err < 0)
237 		goto poweroff;
238 
239 	jdi->link1->mode_flags &= ~MIPI_DSI_MODE_LPM;
240 	jdi->link2->mode_flags &= ~MIPI_DSI_MODE_LPM;
241 
242 	return 0;
243 
244 poweroff:
245 	regulator_disable(jdi->ddi_supply);
246 
247 	/* T6 = 2ms plus some time to discharge capacitors */
248 	usleep_range(7000, 9000);
249 supply_off:
250 	regulator_disable(jdi->supply);
251 	/* Specified by JDI @ 20ms, subject to change */
252 	msleep(20);
253 
254 	return err;
255 }
256 
257 static int jdi_panel_enable(struct drm_panel *panel)
258 {
259 	struct jdi_panel *jdi = to_panel_jdi(panel);
260 
261 	/*
262 	 * Ensure we send image data before turning the backlight
263 	 * on, to avoid the display showing random pixels.
264 	 */
265 	jdi_wait_frames(jdi, 3);
266 
267 	backlight_enable(jdi->backlight);
268 
269 	return 0;
270 }
271 
272 static const struct drm_display_mode default_mode = {
273 	.clock = (2560 + 80 + 80 + 80) * (1800 + 4 + 4 + 4) * 60 / 1000,
274 	.hdisplay = 2560,
275 	.hsync_start = 2560 + 80,
276 	.hsync_end = 2560 + 80 + 80,
277 	.htotal = 2560 + 80 + 80 + 80,
278 	.vdisplay = 1800,
279 	.vsync_start = 1800 + 4,
280 	.vsync_end = 1800 + 4 + 4,
281 	.vtotal = 1800 + 4 + 4 + 4,
282 	.flags = 0,
283 };
284 
285 static int jdi_panel_get_modes(struct drm_panel *panel,
286 			       struct drm_connector *connector)
287 {
288 	struct drm_display_mode *mode;
289 	struct jdi_panel *jdi = to_panel_jdi(panel);
290 	struct device *dev = &jdi->link1->dev;
291 
292 	mode = drm_mode_duplicate(connector->dev, &default_mode);
293 	if (!mode) {
294 		dev_err(dev, "failed to add mode %ux%ux@%u\n",
295 			default_mode.hdisplay, default_mode.vdisplay,
296 			drm_mode_vrefresh(&default_mode));
297 		return -ENOMEM;
298 	}
299 
300 	drm_mode_set_name(mode);
301 
302 	drm_mode_probed_add(connector, mode);
303 
304 	connector->display_info.width_mm = 211;
305 	connector->display_info.height_mm = 148;
306 	connector->display_info.bpc = 8;
307 
308 	return 1;
309 }
310 
311 static const struct drm_panel_funcs jdi_panel_funcs = {
312 	.prepare = jdi_panel_prepare,
313 	.enable = jdi_panel_enable,
314 	.disable = jdi_panel_disable,
315 	.unprepare = jdi_panel_unprepare,
316 	.get_modes = jdi_panel_get_modes,
317 };
318 
319 static const struct of_device_id jdi_of_match[] = {
320 	{ .compatible = "jdi,lpm102a188a", },
321 	{ }
322 };
323 MODULE_DEVICE_TABLE(of, jdi_of_match);
324 
325 static int jdi_panel_add(struct jdi_panel *jdi)
326 {
327 	struct device *dev = &jdi->link1->dev;
328 
329 	jdi->mode = &default_mode;
330 
331 	jdi->supply = devm_regulator_get(dev, "power");
332 	if (IS_ERR(jdi->supply))
333 		return dev_err_probe(dev, PTR_ERR(jdi->supply),
334 				     "failed to get power regulator\n");
335 
336 	jdi->ddi_supply = devm_regulator_get(dev, "ddi");
337 	if (IS_ERR(jdi->ddi_supply))
338 		return dev_err_probe(dev, PTR_ERR(jdi->ddi_supply),
339 				     "failed to get ddi regulator\n");
340 
341 	jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
342 	if (IS_ERR(jdi->reset_gpio))
343 		return dev_err_probe(dev, PTR_ERR(jdi->reset_gpio),
344 				     "failed to get reset gpio\n");
345 	/* T4 = 1ms */
346 	usleep_range(1000, 3000);
347 
348 	jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
349 	if (IS_ERR(jdi->enable_gpio))
350 		return dev_err_probe(dev, PTR_ERR(jdi->enable_gpio),
351 				     "failed to get enable gpio\n");
352 	/* T5 = 2ms */
353 	usleep_range(2000, 4000);
354 
355 	jdi->backlight = devm_of_find_backlight(dev);
356 	if (IS_ERR(jdi->backlight))
357 		return dev_err_probe(dev, PTR_ERR(jdi->backlight),
358 				     "failed to create backlight\n");
359 
360 	drm_panel_add(&jdi->base);
361 
362 	return 0;
363 }
364 
365 static void jdi_panel_del(struct jdi_panel *jdi)
366 {
367 	if (jdi->base.dev)
368 		drm_panel_remove(&jdi->base);
369 
370 	if (jdi->link2)
371 		put_device(&jdi->link2->dev);
372 }
373 
374 static int jdi_panel_dsi_probe(struct mipi_dsi_device *dsi)
375 {
376 	struct mipi_dsi_device *secondary = NULL;
377 	struct jdi_panel *jdi;
378 	struct device_node *np;
379 	int err;
380 
381 	dsi->lanes = 4;
382 	dsi->format = MIPI_DSI_FMT_RGB888;
383 	dsi->mode_flags = 0;
384 
385 	/* Find DSI-LINK1 */
386 	np = of_parse_phandle(dsi->dev.of_node, "link2", 0);
387 	if (np) {
388 		secondary = of_find_mipi_dsi_device_by_node(np);
389 		of_node_put(np);
390 
391 		if (!secondary)
392 			return -EPROBE_DEFER;
393 	}
394 
395 	/* register a panel for only the DSI-LINK1 interface */
396 	if (secondary) {
397 		jdi = devm_drm_panel_alloc(&dsi->dev, __typeof(*jdi),
398 					   base, &jdi_panel_funcs,
399 					   DRM_MODE_CONNECTOR_DSI);
400 
401 		if (IS_ERR(jdi)) {
402 			put_device(&secondary->dev);
403 			return PTR_ERR(jdi);
404 		}
405 
406 		mipi_dsi_set_drvdata(dsi, jdi);
407 
408 		jdi->link1 = dsi;
409 		jdi->link2 = secondary;
410 
411 		err = jdi_panel_add(jdi);
412 		if (err < 0) {
413 			put_device(&secondary->dev);
414 			return err;
415 		}
416 	}
417 
418 	err = mipi_dsi_attach(dsi);
419 	if (err < 0) {
420 		if (secondary)
421 			jdi_panel_del(jdi);
422 
423 		return err;
424 	}
425 
426 	return 0;
427 }
428 
429 static void jdi_panel_dsi_remove(struct mipi_dsi_device *dsi)
430 {
431 	struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
432 	int err;
433 
434 	/* only detach from host for the DSI-LINK2 interface */
435 	if (!jdi)
436 		mipi_dsi_detach(dsi);
437 
438 	err = jdi_panel_disable(&jdi->base);
439 	if (err < 0)
440 		dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
441 
442 	err = mipi_dsi_detach(dsi);
443 	if (err < 0)
444 		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
445 
446 	jdi_panel_del(jdi);
447 }
448 
449 static void jdi_panel_dsi_shutdown(struct mipi_dsi_device *dsi)
450 {
451 	struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
452 
453 	if (!jdi)
454 		return;
455 
456 	jdi_panel_disable(&jdi->base);
457 }
458 
459 static struct mipi_dsi_driver jdi_panel_dsi_driver = {
460 	.driver = {
461 		.name = "panel-jdi-lpm102a188a",
462 		.of_match_table = jdi_of_match,
463 	},
464 	.probe = jdi_panel_dsi_probe,
465 	.remove = jdi_panel_dsi_remove,
466 	.shutdown = jdi_panel_dsi_shutdown,
467 };
468 module_mipi_dsi_driver(jdi_panel_dsi_driver);
469 
470 MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>");
471 MODULE_AUTHOR("Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>");
472 MODULE_DESCRIPTION("DRM Driver for JDI LPM102A188A DSI panel, command mode");
473 MODULE_LICENSE("GPL");
474