xref: /linux/drivers/gpu/drm/panel/panel-dsi-cm.c (revision a940daa52167e9db8ecce82213813b735a9d9f23)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Generic DSI Command Mode panel driver
4   *
5   * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/
6   * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
7   */
8  
9  #include <linux/backlight.h>
10  #include <linux/delay.h>
11  #include <linux/gpio/consumer.h>
12  #include <linux/jiffies.h>
13  #include <linux/module.h>
14  #include <linux/of.h>
15  #include <linux/regulator/consumer.h>
16  
17  #include <drm/drm_connector.h>
18  #include <drm/drm_mipi_dsi.h>
19  #include <drm/drm_modes.h>
20  #include <drm/drm_panel.h>
21  
22  #include <video/mipi_display.h>
23  
24  #define DCS_GET_ID1		0xda
25  #define DCS_GET_ID2		0xdb
26  #define DCS_GET_ID3		0xdc
27  
28  #define DCS_REGULATOR_SUPPLY_NUM 2
29  
30  static const struct of_device_id dsicm_of_match[];
31  
32  struct dsic_panel_data {
33  	u32 xres;
34  	u32 yres;
35  	u32 refresh;
36  	u32 width_mm;
37  	u32 height_mm;
38  	u32 max_hs_rate;
39  	u32 max_lp_rate;
40  	bool te_support;
41  };
42  
43  struct panel_drv_data {
44  	struct mipi_dsi_device *dsi;
45  	struct drm_panel panel;
46  	struct drm_display_mode mode;
47  
48  	struct mutex lock;
49  
50  	struct backlight_device *bldev;
51  	struct backlight_device *extbldev;
52  
53  	unsigned long	hw_guard_end;	/* next value of jiffies when we can
54  					 * issue the next sleep in/out command
55  					 */
56  	unsigned long	hw_guard_wait;	/* max guard time in jiffies */
57  
58  	const struct dsic_panel_data *panel_data;
59  
60  	struct gpio_desc *reset_gpio;
61  
62  	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
63  
64  	bool use_dsi_backlight;
65  
66  	/* runtime variables */
67  	bool enabled;
68  
69  	bool intro_printed;
70  };
71  
panel_to_ddata(struct drm_panel * panel)72  static inline struct panel_drv_data *panel_to_ddata(struct drm_panel *panel)
73  {
74  	return container_of(panel, struct panel_drv_data, panel);
75  }
76  
dsicm_bl_power(struct panel_drv_data * ddata,bool enable)77  static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
78  {
79  	struct backlight_device *backlight;
80  
81  	if (ddata->bldev)
82  		backlight = ddata->bldev;
83  	else if (ddata->extbldev)
84  		backlight = ddata->extbldev;
85  	else
86  		return;
87  
88  	if (enable)
89  		backlight_enable(backlight);
90  	else
91  		backlight_disable(backlight);
92  }
93  
hw_guard_start(struct panel_drv_data * ddata,int guard_msec)94  static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
95  {
96  	ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
97  	ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
98  }
99  
hw_guard_wait(struct panel_drv_data * ddata)100  static void hw_guard_wait(struct panel_drv_data *ddata)
101  {
102  	unsigned long wait = ddata->hw_guard_end - jiffies;
103  
104  	if ((long)wait > 0 && wait <= ddata->hw_guard_wait) {
105  		set_current_state(TASK_UNINTERRUPTIBLE);
106  		schedule_timeout(wait);
107  	}
108  }
109  
dsicm_dcs_read_1(struct panel_drv_data * ddata,u8 dcs_cmd,u8 * data)110  static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
111  {
112  	return mipi_dsi_dcs_read(ddata->dsi, dcs_cmd, data, 1);
113  }
114  
dsicm_dcs_write_1(struct panel_drv_data * ddata,u8 dcs_cmd,u8 param)115  static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
116  {
117  	return mipi_dsi_dcs_write(ddata->dsi, dcs_cmd, &param, 1);
118  }
119  
dsicm_sleep_in(struct panel_drv_data * ddata)120  static int dsicm_sleep_in(struct panel_drv_data *ddata)
121  
122  {
123  	int r;
124  
125  	hw_guard_wait(ddata);
126  
127  	r = mipi_dsi_dcs_enter_sleep_mode(ddata->dsi);
128  	if (r)
129  		return r;
130  
131  	hw_guard_start(ddata, 120);
132  
133  	usleep_range(5000, 10000);
134  
135  	return 0;
136  }
137  
dsicm_sleep_out(struct panel_drv_data * ddata)138  static int dsicm_sleep_out(struct panel_drv_data *ddata)
139  {
140  	int r;
141  
142  	hw_guard_wait(ddata);
143  
144  	r = mipi_dsi_dcs_exit_sleep_mode(ddata->dsi);
145  	if (r)
146  		return r;
147  
148  	hw_guard_start(ddata, 120);
149  
150  	usleep_range(5000, 10000);
151  
152  	return 0;
153  }
154  
dsicm_get_id(struct panel_drv_data * ddata,u8 * id1,u8 * id2,u8 * id3)155  static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
156  {
157  	int r;
158  
159  	r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
160  	if (r)
161  		return r;
162  	r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
163  	if (r)
164  		return r;
165  	r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
166  	if (r)
167  		return r;
168  
169  	return 0;
170  }
171  
dsicm_set_update_window(struct panel_drv_data * ddata)172  static int dsicm_set_update_window(struct panel_drv_data *ddata)
173  {
174  	struct mipi_dsi_device *dsi = ddata->dsi;
175  	int r;
176  
177  	r = mipi_dsi_dcs_set_column_address(dsi, 0, ddata->mode.hdisplay - 1);
178  	if (r < 0)
179  		return r;
180  
181  	r = mipi_dsi_dcs_set_page_address(dsi, 0, ddata->mode.vdisplay - 1);
182  	if (r < 0)
183  		return r;
184  
185  	return 0;
186  }
187  
dsicm_bl_update_status(struct backlight_device * dev)188  static int dsicm_bl_update_status(struct backlight_device *dev)
189  {
190  	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
191  	int r = 0;
192  	int level = backlight_get_brightness(dev);
193  
194  	dev_dbg(&ddata->dsi->dev, "update brightness to %d\n", level);
195  
196  	mutex_lock(&ddata->lock);
197  
198  	if (ddata->enabled)
199  		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
200  				      level);
201  
202  	mutex_unlock(&ddata->lock);
203  
204  	return r;
205  }
206  
dsicm_bl_get_intensity(struct backlight_device * dev)207  static int dsicm_bl_get_intensity(struct backlight_device *dev)
208  {
209  	return backlight_get_brightness(dev);
210  }
211  
212  static const struct backlight_ops dsicm_bl_ops = {
213  	.get_brightness = dsicm_bl_get_intensity,
214  	.update_status  = dsicm_bl_update_status,
215  };
216  
num_dsi_errors_show(struct device * dev,struct device_attribute * attr,char * buf)217  static ssize_t num_dsi_errors_show(struct device *dev,
218  		struct device_attribute *attr, char *buf)
219  {
220  	struct panel_drv_data *ddata = dev_get_drvdata(dev);
221  	u8 errors = 0;
222  	int r = -ENODEV;
223  
224  	mutex_lock(&ddata->lock);
225  
226  	if (ddata->enabled)
227  		r = dsicm_dcs_read_1(ddata, MIPI_DCS_GET_ERROR_COUNT_ON_DSI, &errors);
228  
229  	mutex_unlock(&ddata->lock);
230  
231  	if (r)
232  		return r;
233  
234  	return sysfs_emit(buf, "%d\n", errors);
235  }
236  
hw_revision_show(struct device * dev,struct device_attribute * attr,char * buf)237  static ssize_t hw_revision_show(struct device *dev,
238  		struct device_attribute *attr, char *buf)
239  {
240  	struct panel_drv_data *ddata = dev_get_drvdata(dev);
241  	u8 id1, id2, id3;
242  	int r = -ENODEV;
243  
244  	mutex_lock(&ddata->lock);
245  
246  	if (ddata->enabled)
247  		r = dsicm_get_id(ddata, &id1, &id2, &id3);
248  
249  	mutex_unlock(&ddata->lock);
250  
251  	if (r)
252  		return r;
253  
254  	return sysfs_emit(buf, "%02x.%02x.%02x\n", id1, id2, id3);
255  }
256  
257  static DEVICE_ATTR_RO(num_dsi_errors);
258  static DEVICE_ATTR_RO(hw_revision);
259  
260  static struct attribute *dsicm_attrs[] = {
261  	&dev_attr_num_dsi_errors.attr,
262  	&dev_attr_hw_revision.attr,
263  	NULL,
264  };
265  
266  static const struct attribute_group dsicm_attr_group = {
267  	.attrs = dsicm_attrs,
268  };
269  
dsicm_hw_reset(struct panel_drv_data * ddata)270  static void dsicm_hw_reset(struct panel_drv_data *ddata)
271  {
272  	gpiod_set_value(ddata->reset_gpio, 1);
273  	udelay(10);
274  	/* reset the panel */
275  	gpiod_set_value(ddata->reset_gpio, 0);
276  	/* assert reset */
277  	udelay(10);
278  	gpiod_set_value(ddata->reset_gpio, 1);
279  	/* wait after releasing reset */
280  	usleep_range(5000, 10000);
281  }
282  
dsicm_power_on(struct panel_drv_data * ddata)283  static int dsicm_power_on(struct panel_drv_data *ddata)
284  {
285  	u8 id1, id2, id3;
286  	int r;
287  
288  	dsicm_hw_reset(ddata);
289  
290  	ddata->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
291  
292  	r = dsicm_sleep_out(ddata);
293  	if (r)
294  		goto err;
295  
296  	r = dsicm_get_id(ddata, &id1, &id2, &id3);
297  	if (r)
298  		goto err;
299  
300  	r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff);
301  	if (r)
302  		goto err;
303  
304  	r = dsicm_dcs_write_1(ddata, MIPI_DCS_WRITE_CONTROL_DISPLAY,
305  			(1<<2) | (1<<5));	/* BL | BCTRL */
306  	if (r)
307  		goto err;
308  
309  	r = mipi_dsi_dcs_set_pixel_format(ddata->dsi, MIPI_DCS_PIXEL_FMT_24BIT);
310  	if (r)
311  		goto err;
312  
313  	r = dsicm_set_update_window(ddata);
314  	if (r)
315  		goto err;
316  
317  	r = mipi_dsi_dcs_set_display_on(ddata->dsi);
318  	if (r)
319  		goto err;
320  
321  	if (ddata->panel_data->te_support) {
322  		r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
323  		if (r)
324  			goto err;
325  	}
326  
327  	/* possible panel bug */
328  	msleep(100);
329  
330  	ddata->enabled = true;
331  
332  	if (!ddata->intro_printed) {
333  		dev_info(&ddata->dsi->dev, "panel revision %02x.%02x.%02x\n",
334  			id1, id2, id3);
335  		ddata->intro_printed = true;
336  	}
337  
338  	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
339  
340  	return 0;
341  err:
342  	dev_err(&ddata->dsi->dev, "error while enabling panel, issuing HW reset\n");
343  
344  	dsicm_hw_reset(ddata);
345  
346  	return r;
347  }
348  
dsicm_power_off(struct panel_drv_data * ddata)349  static int dsicm_power_off(struct panel_drv_data *ddata)
350  {
351  	int r;
352  
353  	ddata->enabled = false;
354  
355  	r = mipi_dsi_dcs_set_display_off(ddata->dsi);
356  	if (!r)
357  		r = dsicm_sleep_in(ddata);
358  
359  	if (r) {
360  		dev_err(&ddata->dsi->dev,
361  				"error disabling panel, issuing HW reset\n");
362  		dsicm_hw_reset(ddata);
363  	}
364  
365  	return r;
366  }
367  
dsicm_prepare(struct drm_panel * panel)368  static int dsicm_prepare(struct drm_panel *panel)
369  {
370  	struct panel_drv_data *ddata = panel_to_ddata(panel);
371  	int r;
372  
373  	r = regulator_bulk_enable(ARRAY_SIZE(ddata->supplies), ddata->supplies);
374  	if (r)
375  		dev_err(&ddata->dsi->dev, "failed to enable supplies: %d\n", r);
376  
377  	return r;
378  }
379  
dsicm_enable(struct drm_panel * panel)380  static int dsicm_enable(struct drm_panel *panel)
381  {
382  	struct panel_drv_data *ddata = panel_to_ddata(panel);
383  	int r;
384  
385  	mutex_lock(&ddata->lock);
386  
387  	r = dsicm_power_on(ddata);
388  	if (r)
389  		goto err;
390  
391  	mutex_unlock(&ddata->lock);
392  
393  	dsicm_bl_power(ddata, true);
394  
395  	return 0;
396  err:
397  	dev_err(&ddata->dsi->dev, "enable failed (%d)\n", r);
398  	mutex_unlock(&ddata->lock);
399  	return r;
400  }
401  
dsicm_unprepare(struct drm_panel * panel)402  static int dsicm_unprepare(struct drm_panel *panel)
403  {
404  	struct panel_drv_data *ddata = panel_to_ddata(panel);
405  	int r;
406  
407  	r = regulator_bulk_disable(ARRAY_SIZE(ddata->supplies), ddata->supplies);
408  	if (r)
409  		dev_err(&ddata->dsi->dev, "failed to disable supplies: %d\n", r);
410  
411  	return r;
412  }
413  
dsicm_disable(struct drm_panel * panel)414  static int dsicm_disable(struct drm_panel *panel)
415  {
416  	struct panel_drv_data *ddata = panel_to_ddata(panel);
417  	int r;
418  
419  	dsicm_bl_power(ddata, false);
420  
421  	mutex_lock(&ddata->lock);
422  
423  	r = dsicm_power_off(ddata);
424  
425  	mutex_unlock(&ddata->lock);
426  
427  	return r;
428  }
429  
dsicm_get_modes(struct drm_panel * panel,struct drm_connector * connector)430  static int dsicm_get_modes(struct drm_panel *panel,
431  			   struct drm_connector *connector)
432  {
433  	struct panel_drv_data *ddata = panel_to_ddata(panel);
434  	struct drm_display_mode *mode;
435  
436  	mode = drm_mode_duplicate(connector->dev, &ddata->mode);
437  	if (!mode) {
438  		dev_err(&ddata->dsi->dev, "failed to add mode %ux%ux@%u kHz\n",
439  			ddata->mode.hdisplay, ddata->mode.vdisplay,
440  			ddata->mode.clock);
441  		return -ENOMEM;
442  	}
443  
444  	connector->display_info.width_mm = ddata->panel_data->width_mm;
445  	connector->display_info.height_mm = ddata->panel_data->height_mm;
446  
447  	drm_mode_probed_add(connector, mode);
448  
449  	return 1;
450  }
451  
452  static const struct drm_panel_funcs dsicm_panel_funcs = {
453  	.unprepare = dsicm_unprepare,
454  	.disable = dsicm_disable,
455  	.prepare = dsicm_prepare,
456  	.enable = dsicm_enable,
457  	.get_modes = dsicm_get_modes,
458  };
459  
dsicm_probe_of(struct mipi_dsi_device * dsi)460  static int dsicm_probe_of(struct mipi_dsi_device *dsi)
461  {
462  	struct backlight_device *backlight;
463  	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
464  	int err;
465  	struct drm_display_mode *mode = &ddata->mode;
466  
467  	ddata->reset_gpio = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
468  	if (IS_ERR(ddata->reset_gpio)) {
469  		err = PTR_ERR(ddata->reset_gpio);
470  		dev_err(&dsi->dev, "reset gpio request failed: %d", err);
471  		return err;
472  	}
473  
474  	mode->hdisplay = mode->hsync_start = mode->hsync_end = mode->htotal =
475  		ddata->panel_data->xres;
476  	mode->vdisplay = mode->vsync_start = mode->vsync_end = mode->vtotal =
477  		ddata->panel_data->yres;
478  	mode->clock = ddata->panel_data->xres * ddata->panel_data->yres *
479  		ddata->panel_data->refresh / 1000;
480  	mode->width_mm = ddata->panel_data->width_mm;
481  	mode->height_mm = ddata->panel_data->height_mm;
482  	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
483  	drm_mode_set_name(mode);
484  
485  	ddata->supplies[0].supply = "vpnl";
486  	ddata->supplies[1].supply = "vddi";
487  	err = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ddata->supplies),
488  				      ddata->supplies);
489  	if (err)
490  		return err;
491  
492  	backlight = devm_of_find_backlight(&dsi->dev);
493  	if (IS_ERR(backlight))
494  		return PTR_ERR(backlight);
495  
496  	/* If no backlight device is found assume native backlight support */
497  	if (backlight)
498  		ddata->extbldev = backlight;
499  	else
500  		ddata->use_dsi_backlight = true;
501  
502  	return 0;
503  }
504  
dsicm_probe(struct mipi_dsi_device * dsi)505  static int dsicm_probe(struct mipi_dsi_device *dsi)
506  {
507  	struct panel_drv_data *ddata;
508  	struct backlight_device *bldev = NULL;
509  	struct device *dev = &dsi->dev;
510  	int r;
511  
512  	dev_dbg(dev, "probe\n");
513  
514  	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
515  	if (!ddata)
516  		return -ENOMEM;
517  
518  	mipi_dsi_set_drvdata(dsi, ddata);
519  	ddata->dsi = dsi;
520  
521  	ddata->panel_data = of_device_get_match_data(dev);
522  	if (!ddata->panel_data)
523  		return -ENODEV;
524  
525  	r = dsicm_probe_of(dsi);
526  	if (r)
527  		return r;
528  
529  	mutex_init(&ddata->lock);
530  
531  	dsicm_hw_reset(ddata);
532  
533  	drm_panel_init(&ddata->panel, dev, &dsicm_panel_funcs,
534  		       DRM_MODE_CONNECTOR_DSI);
535  
536  	if (ddata->use_dsi_backlight) {
537  		struct backlight_properties props = { 0 };
538  		props.max_brightness = 255;
539  		props.type = BACKLIGHT_RAW;
540  
541  		bldev = devm_backlight_device_register(dev, dev_name(dev),
542  			dev, ddata, &dsicm_bl_ops, &props);
543  		if (IS_ERR(bldev)) {
544  			r = PTR_ERR(bldev);
545  			goto err_bl;
546  		}
547  
548  		ddata->bldev = bldev;
549  	}
550  
551  	r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
552  	if (r) {
553  		dev_err(dev, "failed to create sysfs files\n");
554  		goto err_bl;
555  	}
556  
557  	dsi->lanes = 2;
558  	dsi->format = MIPI_DSI_FMT_RGB888;
559  	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS |
560  			  MIPI_DSI_MODE_NO_EOT_PACKET;
561  	dsi->hs_rate = ddata->panel_data->max_hs_rate;
562  	dsi->lp_rate = ddata->panel_data->max_lp_rate;
563  
564  	drm_panel_add(&ddata->panel);
565  
566  	r = mipi_dsi_attach(dsi);
567  	if (r < 0)
568  		goto err_dsi_attach;
569  
570  	return 0;
571  
572  err_dsi_attach:
573  	drm_panel_remove(&ddata->panel);
574  	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
575  err_bl:
576  	if (ddata->extbldev)
577  		put_device(&ddata->extbldev->dev);
578  
579  	return r;
580  }
581  
dsicm_remove(struct mipi_dsi_device * dsi)582  static void dsicm_remove(struct mipi_dsi_device *dsi)
583  {
584  	struct panel_drv_data *ddata = mipi_dsi_get_drvdata(dsi);
585  
586  	dev_dbg(&dsi->dev, "remove\n");
587  
588  	mipi_dsi_detach(dsi);
589  
590  	drm_panel_remove(&ddata->panel);
591  
592  	sysfs_remove_group(&dsi->dev.kobj, &dsicm_attr_group);
593  
594  	if (ddata->extbldev)
595  		put_device(&ddata->extbldev->dev);
596  }
597  
598  static const struct dsic_panel_data taal_data = {
599  	.xres = 864,
600  	.yres = 480,
601  	.refresh = 60,
602  	.width_mm = 0,
603  	.height_mm = 0,
604  	.max_hs_rate = 300000000,
605  	.max_lp_rate = 10000000,
606  	.te_support = true,
607  };
608  
609  static const struct dsic_panel_data himalaya_data = {
610  	.xres = 480,
611  	.yres = 864,
612  	.refresh = 60,
613  	.width_mm = 49,
614  	.height_mm = 88,
615  	.max_hs_rate = 300000000,
616  	.max_lp_rate = 10000000,
617  	.te_support = false,
618  };
619  
620  static const struct dsic_panel_data droid4_data = {
621  	.xres = 540,
622  	.yres = 960,
623  	.refresh = 60,
624  	.width_mm = 50,
625  	.height_mm = 89,
626  	.max_hs_rate = 300000000,
627  	.max_lp_rate = 10000000,
628  	.te_support = false,
629  };
630  
631  static const struct of_device_id dsicm_of_match[] = {
632  	{ .compatible = "tpo,taal", .data = &taal_data },
633  	{ .compatible = "nokia,himalaya", &himalaya_data },
634  	{ .compatible = "motorola,droid4-panel", &droid4_data },
635  	{},
636  };
637  
638  MODULE_DEVICE_TABLE(of, dsicm_of_match);
639  
640  static struct mipi_dsi_driver dsicm_driver = {
641  	.probe = dsicm_probe,
642  	.remove = dsicm_remove,
643  	.driver = {
644  		.name = "panel-dsi-cm",
645  		.of_match_table = dsicm_of_match,
646  	},
647  };
648  module_mipi_dsi_driver(dsicm_driver);
649  
650  MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
651  MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
652  MODULE_LICENSE("GPL");
653