aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/panel/panel-simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/panel/panel-simple.c')
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c203
1 files changed, 189 insertions, 14 deletions
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index a25136132c31..4ce1db0a68ff 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -37,14 +37,35 @@ struct panel_desc {
37 const struct drm_display_mode *modes; 37 const struct drm_display_mode *modes;
38 unsigned int num_modes; 38 unsigned int num_modes;
39 39
40 unsigned int bpc;
41
40 struct { 42 struct {
41 unsigned int width; 43 unsigned int width;
42 unsigned int height; 44 unsigned int height;
43 } size; 45 } size;
46
47 /**
48 * @prepare: the time (in milliseconds) that it takes for the panel to
49 * become ready and start receiving video data
50 * @enable: the time (in milliseconds) that it takes for the panel to
51 * display the first valid frame after starting to receive
52 * video data
53 * @disable: the time (in milliseconds) that it takes for the panel to
54 * turn the display off (no content is visible)
55 * @unprepare: the time (in milliseconds) that it takes for the panel
56 * to power itself down completely
57 */
58 struct {
59 unsigned int prepare;
60 unsigned int enable;
61 unsigned int disable;
62 unsigned int unprepare;
63 } delay;
44}; 64};
45 65
46struct panel_simple { 66struct panel_simple {
47 struct drm_panel base; 67 struct drm_panel base;
68 bool prepared;
48 bool enabled; 69 bool enabled;
49 70
50 const struct panel_desc *desc; 71 const struct panel_desc *desc;
@@ -87,6 +108,7 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel)
87 num++; 108 num++;
88 } 109 }
89 110
111 connector->display_info.bpc = panel->desc->bpc;
90 connector->display_info.width_mm = panel->desc->size.width; 112 connector->display_info.width_mm = panel->desc->size.width;
91 connector->display_info.height_mm = panel->desc->size.height; 113 connector->display_info.height_mm = panel->desc->size.height;
92 114
@@ -105,21 +127,40 @@ static int panel_simple_disable(struct drm_panel *panel)
105 backlight_update_status(p->backlight); 127 backlight_update_status(p->backlight);
106 } 128 }
107 129
130 if (p->desc->delay.disable)
131 msleep(p->desc->delay.disable);
132
133 p->enabled = false;
134
135 return 0;
136}
137
138static int panel_simple_unprepare(struct drm_panel *panel)
139{
140 struct panel_simple *p = to_panel_simple(panel);
141
142 if (!p->prepared)
143 return 0;
144
108 if (p->enable_gpio) 145 if (p->enable_gpio)
109 gpiod_set_value_cansleep(p->enable_gpio, 0); 146 gpiod_set_value_cansleep(p->enable_gpio, 0);
110 147
111 regulator_disable(p->supply); 148 regulator_disable(p->supply);
112 p->enabled = false; 149
150 if (p->desc->delay.unprepare)
151 msleep(p->desc->delay.unprepare);
152
153 p->prepared = false;
113 154
114 return 0; 155 return 0;
115} 156}
116 157
117static int panel_simple_enable(struct drm_panel *panel) 158static int panel_simple_prepare(struct drm_panel *panel)
118{ 159{
119 struct panel_simple *p = to_panel_simple(panel); 160 struct panel_simple *p = to_panel_simple(panel);
120 int err; 161 int err;
121 162
122 if (p->enabled) 163 if (p->prepared)
123 return 0; 164 return 0;
124 165
125 err = regulator_enable(p->supply); 166 err = regulator_enable(p->supply);
@@ -131,6 +172,24 @@ static int panel_simple_enable(struct drm_panel *panel)
131 if (p->enable_gpio) 172 if (p->enable_gpio)
132 gpiod_set_value_cansleep(p->enable_gpio, 1); 173 gpiod_set_value_cansleep(p->enable_gpio, 1);
133 174
175 if (p->desc->delay.prepare)
176 msleep(p->desc->delay.prepare);
177
178 p->prepared = true;
179
180 return 0;
181}
182
183static int panel_simple_enable(struct drm_panel *panel)
184{
185 struct panel_simple *p = to_panel_simple(panel);
186
187 if (p->enabled)
188 return 0;
189
190 if (p->desc->delay.enable)
191 msleep(p->desc->delay.enable);
192
134 if (p->backlight) { 193 if (p->backlight) {
135 p->backlight->props.power = FB_BLANK_UNBLANK; 194 p->backlight->props.power = FB_BLANK_UNBLANK;
136 backlight_update_status(p->backlight); 195 backlight_update_status(p->backlight);
@@ -164,6 +223,8 @@ static int panel_simple_get_modes(struct drm_panel *panel)
164 223
165static const struct drm_panel_funcs panel_simple_funcs = { 224static const struct drm_panel_funcs panel_simple_funcs = {
166 .disable = panel_simple_disable, 225 .disable = panel_simple_disable,
226 .unprepare = panel_simple_unprepare,
227 .prepare = panel_simple_prepare,
167 .enable = panel_simple_enable, 228 .enable = panel_simple_enable,
168 .get_modes = panel_simple_get_modes, 229 .get_modes = panel_simple_get_modes,
169}; 230};
@@ -179,22 +240,21 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
179 return -ENOMEM; 240 return -ENOMEM;
180 241
181 panel->enabled = false; 242 panel->enabled = false;
243 panel->prepared = false;
182 panel->desc = desc; 244 panel->desc = desc;
183 245
184 panel->supply = devm_regulator_get(dev, "power"); 246 panel->supply = devm_regulator_get(dev, "power");
185 if (IS_ERR(panel->supply)) 247 if (IS_ERR(panel->supply))
186 return PTR_ERR(panel->supply); 248 return PTR_ERR(panel->supply);
187 249
188 panel->enable_gpio = devm_gpiod_get(dev, "enable"); 250 panel->enable_gpio = devm_gpiod_get_optional(dev, "enable");
189 if (IS_ERR(panel->enable_gpio)) { 251 if (IS_ERR(panel->enable_gpio)) {
190 err = PTR_ERR(panel->enable_gpio); 252 err = PTR_ERR(panel->enable_gpio);
191 if (err != -ENOENT) { 253 dev_err(dev, "failed to request GPIO: %d\n", err);
192 dev_err(dev, "failed to request GPIO: %d\n", err); 254 return err;
193 return err; 255 }
194 }
195 256
196 panel->enable_gpio = NULL; 257 if (panel->enable_gpio) {
197 } else {
198 err = gpiod_direction_output(panel->enable_gpio, 0); 258 err = gpiod_direction_output(panel->enable_gpio, 0);
199 if (err < 0) { 259 if (err < 0) {
200 dev_err(dev, "failed to setup GPIO: %d\n", err); 260 dev_err(dev, "failed to setup GPIO: %d\n", err);
@@ -285,6 +345,7 @@ static const struct drm_display_mode auo_b101aw03_mode = {
285static const struct panel_desc auo_b101aw03 = { 345static const struct panel_desc auo_b101aw03 = {
286 .modes = &auo_b101aw03_mode, 346 .modes = &auo_b101aw03_mode,
287 .num_modes = 1, 347 .num_modes = 1,
348 .bpc = 6,
288 .size = { 349 .size = {
289 .width = 223, 350 .width = 223,
290 .height = 125, 351 .height = 125,
@@ -307,12 +368,40 @@ static const struct drm_display_mode auo_b133xtn01_mode = {
307static const struct panel_desc auo_b133xtn01 = { 368static const struct panel_desc auo_b133xtn01 = {
308 .modes = &auo_b133xtn01_mode, 369 .modes = &auo_b133xtn01_mode,
309 .num_modes = 1, 370 .num_modes = 1,
371 .bpc = 6,
310 .size = { 372 .size = {
311 .width = 293, 373 .width = 293,
312 .height = 165, 374 .height = 165,
313 }, 375 },
314}; 376};
315 377
378static const struct drm_display_mode auo_b133htn01_mode = {
379 .clock = 150660,
380 .hdisplay = 1920,
381 .hsync_start = 1920 + 172,
382 .hsync_end = 1920 + 172 + 80,
383 .htotal = 1920 + 172 + 80 + 60,
384 .vdisplay = 1080,
385 .vsync_start = 1080 + 25,
386 .vsync_end = 1080 + 25 + 10,
387 .vtotal = 1080 + 25 + 10 + 10,
388 .vrefresh = 60,
389};
390
391static const struct panel_desc auo_b133htn01 = {
392 .modes = &auo_b133htn01_mode,
393 .num_modes = 1,
394 .size = {
395 .width = 293,
396 .height = 165,
397 },
398 .delay = {
399 .prepare = 105,
400 .enable = 20,
401 .unprepare = 50,
402 },
403};
404
316static const struct drm_display_mode chunghwa_claa101wa01a_mode = { 405static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
317 .clock = 72070, 406 .clock = 72070,
318 .hdisplay = 1366, 407 .hdisplay = 1366,
@@ -329,6 +418,7 @@ static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
329static const struct panel_desc chunghwa_claa101wa01a = { 418static const struct panel_desc chunghwa_claa101wa01a = {
330 .modes = &chunghwa_claa101wa01a_mode, 419 .modes = &chunghwa_claa101wa01a_mode,
331 .num_modes = 1, 420 .num_modes = 1,
421 .bpc = 6,
332 .size = { 422 .size = {
333 .width = 220, 423 .width = 220,
334 .height = 120, 424 .height = 120,
@@ -351,6 +441,7 @@ static const struct drm_display_mode chunghwa_claa101wb01_mode = {
351static const struct panel_desc chunghwa_claa101wb01 = { 441static const struct panel_desc chunghwa_claa101wb01 = {
352 .modes = &chunghwa_claa101wb01_mode, 442 .modes = &chunghwa_claa101wb01_mode,
353 .num_modes = 1, 443 .num_modes = 1,
444 .bpc = 6,
354 .size = { 445 .size = {
355 .width = 223, 446 .width = 223,
356 .height = 125, 447 .height = 125,
@@ -374,6 +465,7 @@ static const struct drm_display_mode edt_et057090dhu_mode = {
374static const struct panel_desc edt_et057090dhu = { 465static const struct panel_desc edt_et057090dhu = {
375 .modes = &edt_et057090dhu_mode, 466 .modes = &edt_et057090dhu_mode,
376 .num_modes = 1, 467 .num_modes = 1,
468 .bpc = 6,
377 .size = { 469 .size = {
378 .width = 115, 470 .width = 115,
379 .height = 86, 471 .height = 86,
@@ -397,12 +489,82 @@ static const struct drm_display_mode edt_etm0700g0dh6_mode = {
397static const struct panel_desc edt_etm0700g0dh6 = { 489static const struct panel_desc edt_etm0700g0dh6 = {
398 .modes = &edt_etm0700g0dh6_mode, 490 .modes = &edt_etm0700g0dh6_mode,
399 .num_modes = 1, 491 .num_modes = 1,
492 .bpc = 6,
400 .size = { 493 .size = {
401 .width = 152, 494 .width = 152,
402 .height = 91, 495 .height = 91,
403 }, 496 },
404}; 497};
405 498
499static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
500 .clock = 32260,
501 .hdisplay = 800,
502 .hsync_start = 800 + 168,
503 .hsync_end = 800 + 168 + 64,
504 .htotal = 800 + 168 + 64 + 88,
505 .vdisplay = 480,
506 .vsync_start = 480 + 37,
507 .vsync_end = 480 + 37 + 2,
508 .vtotal = 480 + 37 + 2 + 8,
509 .vrefresh = 60,
510};
511
512static const struct panel_desc foxlink_fl500wvr00_a0t = {
513 .modes = &foxlink_fl500wvr00_a0t_mode,
514 .num_modes = 1,
515 .size = {
516 .width = 108,
517 .height = 65,
518 },
519};
520
521static const struct drm_display_mode innolux_n116bge_mode = {
522 .clock = 71000,
523 .hdisplay = 1366,
524 .hsync_start = 1366 + 64,
525 .hsync_end = 1366 + 64 + 6,
526 .htotal = 1366 + 64 + 6 + 64,
527 .vdisplay = 768,
528 .vsync_start = 768 + 8,
529 .vsync_end = 768 + 8 + 4,
530 .vtotal = 768 + 8 + 4 + 8,
531 .vrefresh = 60,
532 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
533};
534
535static const struct panel_desc innolux_n116bge = {
536 .modes = &innolux_n116bge_mode,
537 .num_modes = 1,
538 .bpc = 6,
539 .size = {
540 .width = 256,
541 .height = 144,
542 },
543};
544
545static const struct drm_display_mode innolux_n156bge_l21_mode = {
546 .clock = 69300,
547 .hdisplay = 1366,
548 .hsync_start = 1366 + 16,
549 .hsync_end = 1366 + 16 + 34,
550 .htotal = 1366 + 16 + 34 + 50,
551 .vdisplay = 768,
552 .vsync_start = 768 + 2,
553 .vsync_end = 768 + 2 + 6,
554 .vtotal = 768 + 2 + 6 + 12,
555 .vrefresh = 60,
556};
557
558static const struct panel_desc innolux_n156bge_l21 = {
559 .modes = &innolux_n156bge_l21_mode,
560 .num_modes = 1,
561 .bpc = 6,
562 .size = {
563 .width = 344,
564 .height = 193,
565 },
566};
567
406static const struct drm_display_mode lg_lp129qe_mode = { 568static const struct drm_display_mode lg_lp129qe_mode = {
407 .clock = 285250, 569 .clock = 285250,
408 .hdisplay = 2560, 570 .hdisplay = 2560,
@@ -419,6 +581,7 @@ static const struct drm_display_mode lg_lp129qe_mode = {
419static const struct panel_desc lg_lp129qe = { 581static const struct panel_desc lg_lp129qe = {
420 .modes = &lg_lp129qe_mode, 582 .modes = &lg_lp129qe_mode,
421 .num_modes = 1, 583 .num_modes = 1,
584 .bpc = 8,
422 .size = { 585 .size = {
423 .width = 272, 586 .width = 272,
424 .height = 181, 587 .height = 181,
@@ -441,6 +604,7 @@ static const struct drm_display_mode samsung_ltn101nt05_mode = {
441static const struct panel_desc samsung_ltn101nt05 = { 604static const struct panel_desc samsung_ltn101nt05 = {
442 .modes = &samsung_ltn101nt05_mode, 605 .modes = &samsung_ltn101nt05_mode,
443 .num_modes = 1, 606 .num_modes = 1,
607 .bpc = 6,
444 .size = { 608 .size = {
445 .width = 1024, 609 .width = 1024,
446 .height = 600, 610 .height = 600,
@@ -452,6 +616,9 @@ static const struct of_device_id platform_of_match[] = {
452 .compatible = "auo,b101aw03", 616 .compatible = "auo,b101aw03",
453 .data = &auo_b101aw03, 617 .data = &auo_b101aw03,
454 }, { 618 }, {
619 .compatible = "auo,b133htn01",
620 .data = &auo_b133htn01,
621 }, {
455 .compatible = "auo,b133xtn01", 622 .compatible = "auo,b133xtn01",
456 .data = &auo_b133xtn01, 623 .data = &auo_b133xtn01,
457 }, { 624 }, {
@@ -470,14 +637,21 @@ static const struct of_device_id platform_of_match[] = {
470 .compatible = "edt,etm0700g0dh6", 637 .compatible = "edt,etm0700g0dh6",
471 .data = &edt_etm0700g0dh6, 638 .data = &edt_etm0700g0dh6,
472 }, { 639 }, {
640 .compatible = "foxlink,fl500wvr00-a0t",
641 .data = &foxlink_fl500wvr00_a0t,
642 }, {
643 .compatible = "innolux,n116bge",
644 .data = &innolux_n116bge,
645 }, {
646 .compatible = "innolux,n156bge-l21",
647 .data = &innolux_n156bge_l21,
648 }, {
473 .compatible = "lg,lp129qe", 649 .compatible = "lg,lp129qe",
474 .data = &lg_lp129qe, 650 .data = &lg_lp129qe,
475 }, { 651 }, {
476 .compatible = "samsung,ltn101nt05", 652 .compatible = "samsung,ltn101nt05",
477 .data = &samsung_ltn101nt05, 653 .data = &samsung_ltn101nt05,
478 }, { 654 }, {
479 .compatible = "simple-panel",
480 }, {
481 /* sentinel */ 655 /* sentinel */
482 } 656 }
483}; 657};
@@ -545,7 +719,7 @@ static const struct panel_desc_dsi lg_ld070wx3_sl01 = {
545 .height = 151, 719 .height = 151,
546 }, 720 },
547 }, 721 },
548 .flags = MIPI_DSI_MODE_VIDEO, 722 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
549 .format = MIPI_DSI_FMT_RGB888, 723 .format = MIPI_DSI_FMT_RGB888,
550 .lanes = 4, 724 .lanes = 4,
551}; 725};
@@ -599,7 +773,8 @@ static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
599 .height = 136, 773 .height = 136,
600 }, 774 },
601 }, 775 },
602 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE, 776 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
777 MIPI_DSI_CLOCK_NON_CONTINUOUS,
603 .format = MIPI_DSI_FMT_RGB888, 778 .format = MIPI_DSI_FMT_RGB888,
604 .lanes = 4, 779 .lanes = 4,
605}; 780};