Merge tag 'pci-v6.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
[linux-2.6-microblaze.git] / drivers / gpu / drm / panel / panel-dsi-cm.c
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_device.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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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");